«_csv.Error: строка содержит байт NULL» после усечения файла журнала csv, который передается другим процессом - PullRequest
0 голосов
/ 02 февраля 2020

Как обрезать файл журнала csv, который используется в качестве места назначения std out pipe из другого процесса, не генерируя ошибку _csv.Error: line contains NULL byte?

У меня работает один процесс rtlamr > log/readings.txt, который передает радиосигнал данные до readings.txt. Я не думаю, что имеет значение, что передается в файл - подойдет любой длительный процесс конвейера.

У меня есть средство просмотра файлов, использующее для этого файла watchdog (Python наблюдатель файла), который запускает функцию при изменении файла. Функция читает файлы и обновляет базу данных.

Затем я пытаюсь усечь readings.txt, чтобы она не росла бесконечно (или не создавала резервные копии).

file = open(dir_path+'/log/readings.txt', "w")
file.truncate()
file.close()

Это повреждает readings.txt и генерирует ошибку (в начале файла содержатся символы мусора).

Я попытался переместить файл вместо его усечения, в надежде, что rtlamr воссоздает файл fre sh, но это только приводит к остановке канала.

РЕДАКТИРОВАТЬ Я заметил, что кодировка меняется с us-ascii на binary, но попытка обрезать файл с помощью file = open(dir_path+'/log/readings.log', "w",encoding="us-ascii") ничего не делает.

1 Ответ

1 голос
/ 02 февраля 2020

Если вы truncate файл 1 , в то время как другой процесс открывает его в режиме w, этот процесс продолжит запись с теми же смещениями, что сделает файл разреженным. Таким образом, низкие смещения будут считываться как 0 с.

Согласно x11 - одновременная запись в файл журнала многих процессов - Unix & Linux Stack Exchange и Могут ли два Unix обрабатывать одновременную запись в разные позиции в одном файле? , каждый процесс с открытым файлом имеет свое собственное смещение, и ftruncate() не меняет этого.

Если вы хотите, чтобы другой процесс реагировал на усечение, он должен быть открыт в режиме a.


В вашем подходе также есть основные ошибки , Например, это не атомы c: вы можете (= в конечном итоге) обрезать файл после того, как производитель добавил данные, но до того, как вы прочитали их, чтобы они потерялись.

Попробуйте вместо этого использовать специальные утилиты буферизации данных как buffer или pv согласно Добавить большой буфер в канал между двумя командами .


1 Что излишне, потому что open(mode='w') уже делает это. Либо truncate, либо откройте заново, нет необходимости делать оба.

...