2

我正在尝试找到一种将数据从 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 的数据时,实际数据之间存在大量零,最令人不安的部分是在这些“假零”延伸之间读取的连续数据点的数量变化很大。

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

任何意见/建议将不胜感激。

4

1 回答 1

1

看起来fscanf在 Matlab 端的阅读器中如何使用存在问题。

阅读器代码看起来每次循环都会重新读取整个文件,因为它会在每次循环时重新打开它。这是故意的吗?如果您想跟踪文件的结尾,您可能希望保持文件句柄打开,并继续检查是否可以通过重复fscanf调用同一个打开的文件句柄来从中读取更多数据。

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

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

检查文档页面以获取fscanf. 在“输出参数”部分:“如果输入包含的元素少于 sizeA,则 MATLAB® 用零填充 A。”

然后你可能想看看这个问题:如何在 C# 中进行原子写入/追加,或者如何使用 FILE_APPEND_DATA 标志打​​开文件?. 保持写入比输出流的缓冲区短(就像现在一样)将使它们具有原子性,并且在每次写入后刷新将使它们及时对读者可见。

于 2013-04-22T02:06:06.410 回答