Файл записи Python против файла записи Matlab, прочитанного другим программным обеспечением - PullRequest
0 голосов
/ 26 июня 2018

Я столкнулся с этой странной проблемой с открытием / закрытием файлов в python.Я пытаюсь сделать то же самое в Python, что я делал успешно в Matlab, и у меня возникла проблема при общении с некоторыми программами через текстовые файлы.Я нашел странный обходной путь для решения проблемы, но я не понимаю, почему он работает.

У меня есть программное обеспечение, которое взаимодействует с некоторым лабораторным оборудованием.Чтобы связаться с этим программным обеспечением, я записываю файл ('wavefile.txt') в определенную папку, содержащую параметры для отправки на устройство.Затем я пишу другой файл с именем 'request.txt', содержащий местоположение этого первого файла ('wavefile.txt'), который содержит параметры для отправки на устройство.Программное обеспечение постоянно проверяет эту папку, чтобы найти файл с именем «request.txt», и как только оно его находит, оно считывает параметры в файле, который указан в тексте «request.txt», а затем удаляет «request.txt».».Разработчик программного обеспечения / оборудования дает команду дать задержку в 50 мс перед закрытием файла request.txt.

оригинальный код 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)

Каждый раз, когда программа устройства читает «request.txt»когда он работает с matlab, он удаляет его сразу после того, как matlab закрывает его.Когда я запускаю этот код с python, он работает ИНОГДА, возможно, 1 из каждых 5 попыток будет успешным, и параметры будут отправлены.Файл '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 () абсолютно необходимо.если я удаляю эту строку и все еще включаю дополнительное время сна, она снова будет работать примерно в 1 из 5 попытокЭто кажется мне действительно странным.Любое объяснение или лучшие решения?

Ответы [ 3 ]

0 голосов
/ 26 июня 2018

Трудно сказать, не зная подробностей о конкретном оборудовании и другом программном обеспечении, которое вы используете.Одним из предположений является различие в буферизации при вызовах записи.

Из этого сообщения в блоге 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'
0 голосов
/ 26 июня 2018

Возможно, проблема в том, что вы делаете задержку, пока файл еще открыт и, следовательно, не записывается на диск.Попробуйте что-то вроде этого:

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)

Также имейте в виду, что вы также не можете сделать обратное: предположите, что текст не написан, пока вы не закроете.Для небольших файлов, как это, это, вероятно, произойдет.Но когда файл записывается на диск, зависит от многих факторов.Когда файл закрыт, он записывается, но может быть записан и до этого.

0 голосов
/ 26 июня 2018

Мое предположение (что может быть неверным) заключается в том, что файл читается до того, как он будет полностью очищен.Я бы попытался использовать метод 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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...