python写入文件与matlab写入文件,由另一软件读取

时间:2018-06-25 23:32:16

标签: python matlab

我在python中打开/关闭文件时遇到了这个奇怪的问题。我正在尝试在python中做与在matlab中成功完成的相同的事情,但是在通过文本文件与某些软件进行通讯时遇到了问题。我想出了一个奇怪的解决方法来解决该问题,但是我不明白为什么会起作用。

我有与某些实验室设备通讯的软件。为了与此软件进行通信,我将文件('wavefile.txt')写入特定的文件夹,其中包含要发送到设备的参数。然后,我写另一个名为“ request.txt”的文件,其中包含第一个文件(“ wavefile.txt”)的位置,该文​​件包含要发送到设备的参数。软件会不断检查此文件夹以找到名为“ request.txt”的文件,一旦找到该文件,它将读取文件中“ request.txt”中文本指定的参数,然后删除“ request.txt” '。软件/设备开发人员指示在关闭“ request.txt”文件之前给出50毫秒的延迟。

有效的原始matlab代码:

home = cd;
cd \\CREOL-FAST-01\data
fileID = fopen('request.txt', 'wt');
proj = 'C:\\dazzler\\data\\wavefile.txt';
fprintf(fileID, proj);
pause(0.05);
fclose('all');
cd(home);

无效的原始python代码:

home = os.getcwd()
os.chdir(r'\\CREOL-FAST-01\data')
with open('request.txt', 'w') as file:
    proj = r'C:\dazzler\data\wavefile.txt'
    file.write(proj)
    time.sleep(0.05)
os.chdir(home)

每次设备程序在使用matlab时读取“ request.txt”时,都会在matlab关闭后立即将其删除。当我使用python运行该代码时,它可能会在某些时候运行,也许每5次尝试中就有1次将成功执行并发送参数。 “ request.txt”文件始终使用上面的python代码删除,但是我输入的参数显然不会发送到我的实验室设备。我的猜测是,当我用python编写文件时,设备程序能够在python将文本写入文本之前读取它,因此它只是打开空白文件,不应用任何参数,然后将其删除。

我在python中的解决方法:

home = os.getcwd()
os.chdir(r'\\CREOL-FAST-01\data')
fileh = open('request.txt', 'w+')
proj = r'C:\dazzler\data\wavefile.txt'
fileh.write(proj)
time.sleep(0.05)
print(fileh.read())
time.sleep(0.05)
fileh.close()

此方法在python中似乎可以100%地起作用。我以w +模式打开文件,并且绝对需要使用fileh.read()。如果我删除该行并且仍然包括额外的睡眠时间,它将再次在大约5次尝试中工作1次。这对我来说真的很奇怪。有什么解释或更好的解决方案吗?

3 个答案:

答案 0 :(得分:2)

我的猜测(可能是错误的)是在文件完全刷新之前正在读取文件。我会在写入后尝试使用 flush() 方法,以确保将完整的数据写入文件中。您可能还需要os.fsync()方法来确保正确刷新数据。尝试这样的事情:

home = os.getcwd()
os.chdir(r'\\CREOL-FAST-01\data')
with open('request.txt', 'w') as file:
   proj = r'C:\dazzler\data\wavefile.txt'
   file.write(proj)
   file.flush()
   os.fsync()
   time.sleep(0.05)
os.chdir(home)

答案 1 :(得分:2)

不知道有关正在使用的特定设备和其他软件的任何详细信息,这很难说。一种猜测是写调用缓冲的区别。

在有关Matlab fwrite的这篇博客文章中:“ fprintf和fwrite的默认行为是在每次调用这两个函数之一后刷新文件缓冲区”

Python open的地方:

  

不提供缓冲参数时,默认缓冲策略   工作原理如下:

     

二进制文件以固定大小的块缓冲;缓冲区的大小   选择使用启发式尝试来确定基础   设备的“块大小”,然后返回io.DEFAULT_BUFFER_SIZE。上   在许多系统中,缓冲区的长度通常为4096或8192字节。

     

“交互式”文本文件(isatty()返回True的文件)使用   行缓冲。其他文本文件将上述策略用于   二进制文件。

要测试此猜测更改,请执行以下操作:

with open('request.txt', 'w') as file:
    proj = r'C:\dazzler\data\wavefile.txt'

收件人:

with open('request.txt', 'w', buffer=1) as file:
    proj = 'C:\\dazzler\\data\\wavefile.txt\n'

答案 2 :(得分:0)

问题可能出在文件仍处于打开状态,因此未写入磁盘时,您正在延迟。尝试这样的事情:

home = os.getcwd()
os.chdir(r'\\CREOL-FAST-01\data')
with open('request.txt', 'w') as file:
    proj = r'C:\dazzler\data\wavefile.txt'
    file.write(proj)
time.sleep(0.05)
os.chdir(home)

这里唯一的区别是,在文件关闭后 结束睡眠(with块结束时文件关闭了),因此延迟不会发生,直到将文本写入磁盘后。

用语言来说,您正在做的是:

  1. 打开(并创建)文件
  2. 将文本写到缓冲区(在内存中,不在磁盘上)
  3. 等待50毫秒
  4. 关闭(并写入)文件

您想要做的是:

  1. 打开(并创建)文件
  2. 将文本写到缓冲区(在内存中,不在磁盘上)
  3. 关闭(并写入)文件
  4. 等待50毫秒

因此,最终的结果是创建文本文件的时间至少为50毫秒,但是其中没有任何内容,因为文本位于计算机内存中而不是磁盘上。

说实话,我将尽可能少地放在with块中,以避免出现此类问题。所以我会这样写:

home = os.getcwd()
os.chdir(r'\\CREOL-FAST-01\data')
proj = r'C:\dazzler\data\wavefile.txt'
with open('request.txt', 'w') as file:
    file.write(proj)
time.sleep(0.05)
os.chdir(home)

还请记住,您也不能做相反的事情:假设在关闭之前不会写入任何文本。对于像这样的小文件,可能会发生。但是何时将文件写入磁盘取决于很多因素。关闭文件后,它会被写入,但也可能在此之前被写入。