ReadExisting() 方法 Returns Un-Parseable 字符串?
ReadExisting() Method Returns Un-Parseable String?
所以,我在 c++ win 表单应用程序中有一个串行端口控件 (System::IO::Ports::SerialPort),它从串行连接读取数据,正如标题所暗示的那样。但是,无论出于何种原因,Microsoft 决定读取数据只会 return 字符串值,如果您只是在事后解析字符串,这是可以的。除了,当我尝试解析从 ReadExisting() 命令编辑的 return 字符串时,我得到一个 System.FormatException.
我确定它与 ReadExisting() return 字符串值的方式有关,因为当我将其更改为 ReadLine() 时,我可以轻松地调用 Double::Parse (string) 并得到一个干净的 return 值。除了我没有使用 ReadLine() 的奢侈,因为它对我的应用程序来说太慢了。我试图以 640 Hz 的频率读取通过该串行连接传输的每条数据,因此当我尝试使用 ReadLine() 时,等待新行字符将其速度减慢大约 10 倍,这意味着我而是以大约 64 Hz 的频率读取。没有数据丢失,但它对我的应用程序来说太慢了。
这是附加到 DataReceived 事件的方法。我正在寻找一种允许我解析从 ReadExisting() 传回的字符串的方法。或者,或者一种更有效的阅读方法,让我不会失去任何速度,但仍然允许我最终解析数据,以便我可以使用它。
private: System::Void serialPort1_DataReceived(System::Object^ sender, System::IO::Ports::SerialDataReceivedEventArgs^ e) {
if (!this->reading) return;
else
{
try
{
//get incoming port and read
SerialPort^ sp = (SerialPort^)sender;
String^ sInData = sp->ReadExisting();
//parse read data
double inData = Double::Parse(sInData);
//write data to debugger for testing
Debug::WriteLine(sInData);
//start populating the "in" array
AppendIn(inData);
}
catch (Exception^ e)
{
Debug::WriteLine(e->Message);
}
}
}
提前感谢您提供的任何想法。
我猜 FormatException
中的消息说的是无效字符串。 ReadExisting
读取任何可用字节,将字节解码为字符,然后 returns 将它们作为字符串。由于您没有检查 ReadExisting
的结果,也可能是那里有多个双打。既然你说 ReadLine
有效,也许从 ReadExisting
返回的字符串是“123\n456\n”,而 Double::Parse
抛出 FormatException
因为那不是有效的双精度数。
我要做的是将读取串行字节与解析传入数据的关注分开。有一个接收字节的缓冲区,并在 DataReceived
事件中附加到它。当你这样做时,检查缓冲区是否有足够的数据,如果是,处理完整的传入数据包,并将该数据包从缓冲区中删除。就像现在一样,您依赖 ReadLine
为您打包东西,或者您依赖 DataReceived
每个数据包被调用一次,但它不会。
另外,我不明白你说的阅读速度是什么意思。
I'm attempting to read every piece of data ... at 640 Hz, ... I'm reading at roughly 64 Hz instead. No data is being lost...
如果数据的输入速度比您读取数据的速度快 10 倍,则只有两种可能的选择:要么您正在丢弃数据,要么您的程序越来越落后。
所以,我在 c++ win 表单应用程序中有一个串行端口控件 (System::IO::Ports::SerialPort),它从串行连接读取数据,正如标题所暗示的那样。但是,无论出于何种原因,Microsoft 决定读取数据只会 return 字符串值,如果您只是在事后解析字符串,这是可以的。除了,当我尝试解析从 ReadExisting() 命令编辑的 return 字符串时,我得到一个 System.FormatException.
我确定它与 ReadExisting() return 字符串值的方式有关,因为当我将其更改为 ReadLine() 时,我可以轻松地调用 Double::Parse (string) 并得到一个干净的 return 值。除了我没有使用 ReadLine() 的奢侈,因为它对我的应用程序来说太慢了。我试图以 640 Hz 的频率读取通过该串行连接传输的每条数据,因此当我尝试使用 ReadLine() 时,等待新行字符将其速度减慢大约 10 倍,这意味着我而是以大约 64 Hz 的频率读取。没有数据丢失,但它对我的应用程序来说太慢了。
这是附加到 DataReceived 事件的方法。我正在寻找一种允许我解析从 ReadExisting() 传回的字符串的方法。或者,或者一种更有效的阅读方法,让我不会失去任何速度,但仍然允许我最终解析数据,以便我可以使用它。
private: System::Void serialPort1_DataReceived(System::Object^ sender, System::IO::Ports::SerialDataReceivedEventArgs^ e) {
if (!this->reading) return;
else
{
try
{
//get incoming port and read
SerialPort^ sp = (SerialPort^)sender;
String^ sInData = sp->ReadExisting();
//parse read data
double inData = Double::Parse(sInData);
//write data to debugger for testing
Debug::WriteLine(sInData);
//start populating the "in" array
AppendIn(inData);
}
catch (Exception^ e)
{
Debug::WriteLine(e->Message);
}
}
}
提前感谢您提供的任何想法。
我猜 FormatException
中的消息说的是无效字符串。 ReadExisting
读取任何可用字节,将字节解码为字符,然后 returns 将它们作为字符串。由于您没有检查 ReadExisting
的结果,也可能是那里有多个双打。既然你说 ReadLine
有效,也许从 ReadExisting
返回的字符串是“123\n456\n”,而 Double::Parse
抛出 FormatException
因为那不是有效的双精度数。
我要做的是将读取串行字节与解析传入数据的关注分开。有一个接收字节的缓冲区,并在 DataReceived
事件中附加到它。当你这样做时,检查缓冲区是否有足够的数据,如果是,处理完整的传入数据包,并将该数据包从缓冲区中删除。就像现在一样,您依赖 ReadLine
为您打包东西,或者您依赖 DataReceived
每个数据包被调用一次,但它不会。
另外,我不明白你说的阅读速度是什么意思。
I'm attempting to read every piece of data ... at 640 Hz, ... I'm reading at roughly 64 Hz instead. No data is being lost...
如果数据的输入速度比您读取数据的速度快 10 倍,则只有两种可能的选择:要么您正在丢弃数据,要么您的程序越来越落后。