首页 文章

python写文件vs matlab写文件,由另一个软件读取

提问于
浏览
0

我在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运行该代码时,它可以运行SOMETIMES,每5次尝试中就有1次会成功并且会发送参数 . 始终使用上面的python代码删除'request.txt'文件,但我输入的参数显然没有发送到我的实验室设备 . 我的猜测是,当我在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()是绝对必要的 . 如果我删除该行并仍然包括额外的休眠时间,它将再次在大约五次尝试中工作 . 这对我来说真的很奇怪 . 任何解释,或更好的解决方案?

3 回答

  • 0

    不知道有关您正在使用的特定设备和其他软件的任何细节很难说 . 一个猜测是写入调用的缓冲区别 .

    来自Matlab上的博客文章fwrite:"The default behavior for fprintf and fwrite is to flush the file buffer after each call to either of these functions"

    而对于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

    我的猜测(这可能是错误的)是文件在完全刷新之前被读取 . 我会尝试在写入后使用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)
    
  • 2

    问题可能是您在文件仍处于打开状态时正在执行延迟,因此无法写入磁盘 . 尝试这样的事情:

    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 块结束时关闭),因此在文本写入磁盘之前不会发生延迟 .

    用文字说,你在做的是:

    • 打开(并创建)文件

    • 将文本写入缓冲区(在内存中,而不是在磁盘上)

    • 等待50毫秒

    • 关闭(并写入)文件

    你想要做的是:

    • 打开(并创建)文件

    • 将文本写入缓冲区(在内存中,而不是在磁盘上)

    • 关闭(并写入)文件

    • 等待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)
    

    还要记住,你也不能做相反的事情:假设在你关闭之前没有写入任何文本 . 对于像这样的小文件,可能会发生这种情况 . 但是当文件写入磁盘时取决于很多因素 . 当文件关闭时,它会被写入,但也可以在此之前写入 .

相关问题