如何读取BytesToRead指示的Serialport中的所有字节

时间:2017-05-21 14:04:12

标签: c# serial-port

我正在尝试读取一米的数据。设备实际支持的圣杯是1000 samples per second。如果重要,波特率为38400, Parity.NoneStopbits.One。我正在使用binary mode来保持尽可能快的东西。我计划使用DataReceived事件,如下所示。

private void serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
    {
        int bytesToRead = _serialPort.BytesToRead;
        byte[] data = new byte[bytesToRead];
        int actualBytesRead = 0;
        do
        {
            actualBytesRead = serialPort.Read(data, 0, bytesToRead);
        } while (actualBytesRead != bytesToRead);

        //At this point assume that the data byte array has all the data
    }

BytesToRead似乎会返回可以为该事件读取的所有字节。但是link表示

The SerialPort class buffers data, but the stream object contained in the
SerialPort.BaseStream property does not. Therefore, the SerialPort object
and the stream object might differ on the number of bytes that are 
available to read. When bytes are buffered to the SerialPort object, the 
BytesToRead property includes these bytes in its value; 
however, these bytes might not be accessible to the stream contained in
the BaseStream property. 

Read仅返回已读取的字节数。 因此,作为对此的预防措施,我计划不断阅读,直到我得到的字节数与BytesToRead为引发的事件所指示的相同。但是,我不清楚几点。

  • 这甚至会起作用吗?我不确定从串口缓冲区读取的数据是否仍然存在。
  • 如果没有,那么在循环时我应该保持读取的字节数等于BytesToRead,还是应该调整它已经从缓冲区读取的字节数。
  • 我几乎不停地冲击缓冲区,直到我得到所有字节。这是正确的吗?这会导致锁定问题,因为字节需要更长的时间才能变得可用吗?
  • 有没有更好的方法来获取BytesToRead所指示的所有字节?

1 个答案:

答案 0 :(得分:3)

以下是错误的:

int actualBytesRead = 0;
do
{
    actualBytesRead = serialPort.Read(data, 0, bytesToRead);
} while (actualBytesRead != bytesToRead);

在循环的每次迭代中,您总是为offset传递0,因此每次读取字节时都会覆盖先前读取的字节。

我会按如下方式重写:

for( int offset = 0;  offset < data.Length;  )
{
    int n = serialPort.Read( data, offset, data.Length - offset );
    offset += n;
}