如何优化“实时”C#write-to-file& MATLAB读取文件操作

时间:2013-04-21 23:40:36

标签: c# matlab optimization asynchronous read-write

我正在尝试找到一种很好的方法将数据从NetworkStream(通过C#)写入文本文件,同时“准同时”将新写入的数据从文本文件读入Matlab。

基本上,是否存在用于协调写/读操作(来自单独的程序)的良好方法或技术,使得读操作不会阻止写操作(反之亦然)并且连续写/读之间的延迟被最小化?

目前我只是通过WriteLine循环将数据从网络流写入(附加)到文本文件,并通过循环Matlab的fscanf函数读取数据,该函数还标记最后读取的元素并将文件指针重新定位到该位置。

C#代码的相关部分:

(注意:我正在使用的循环条件是任意的,我只是想看看现在有什么用。)

NetworkStream network_stream = tcp_client.GetStream();

string path = @"C:\Matlab\serial_data.txt";
            FileInfo file_info = new FileInfo(path);
            using (StreamWriter writer = file_info.CreateText())
            {
                string foo = "";
                writer.WriteLine(foo);
            }

            using (StreamWriter writer = File.AppendText(path))
            {
                byte[] buffer = new byte[1];
                int maxlines = 100000;
                int lines = 0;
                while (lines <= maxlines)
                {
                    network_stream.Read(buffer, 0, buffer.Length);
                    byte byte2string = buffer[0];
                    writer.WriteLine(byte2string);
                    lines++;
                }
            }

相关的Matlab代码:

i=0;

while i<100;
    a = fopen('serial_data.txt');
    b = fscanf(a, '%g', [1000 1]);
    fclose(a);
    i=i+1;
end

当我查看读入Matlab的数据时,实际数据之间存在大量的零,而最令人不安的部分是在这些“假零”延伸之间读取的连续数据点的数量变化很大。

我正在考虑尝试将一些延迟(Thread.sleep和wait(timerObject))分别插入到C#和Matlab中,但即便如此,我也不相信会保证我总是获得通过网络流,这是必要的。

非常感谢任何建议/建议。

1 个答案:

答案 0 :(得分:1)

看起来在Matlab方面的阅读器中使用fscanf的方式存在问题。

读者代码看起来每次都会重复读取整个文件,因为它会在每次循环中重新打开它。这是故意的吗?如果要跟踪文件的结尾,您可能希望保持文件句柄处于打开状态,并且只需检查是否可以通过在同一个打开的文件句柄上重复fscanf次调用来从中读取更多数据。 / p>

此外,fscanf调用看起来总是返回一个零填充的1000元素数组,无论它读取的文件有多大。也许这就是你的“假零”来自哪里。有多少会因文件中实际存在多少数据以及Matlab代码在写入之间读取它的频率而有所不同。抓住fscanf的第二个argout,看看它实际读取了多少元素。

[b,nRead] = fscanf(a, '%g', [1000 1]);
fprintf('Read %d numbers\n', nRead);
b = b(1:nRead);

检查doc page for fscanf。在“输出参数”部分中:“如果输入包含少于sizeA的元素,则MATLAB®会用零填充A.”

然后你可能想看看这个问题:How can I do an atomic write/append in C#, or how do I get files opened with the FILE_APPEND_DATA flag?。保持写入比输出流的缓冲区更短(就像它们现在一样)将使它们成为原子,并且在每次写入后刷新将使读者及时看到它们。