Прервать медленную запись на диск после записи?

StackOverflow https://stackoverflow.com/questions/2458624

  •  20-09-2019
  •  | 
  •  

Вопрос

Есть ли способ прервать операцию записи Python таким образом, чтобы ОС не считала необходимым сбрасывать незаписанные данные на диск?

Я записываю данные на USB-устройство, обычно много мегабайт.Я использую размер блока при записи 4096 байт, но похоже, что Linux заранее кэширует кучу данных и медленно записывает их на USB-устройство.Если в какой-то момент во время записи мой пользователь решит отменить запись, я хочу, чтобы приложение немедленно прекратило запись.Я вижу задержку между моментом, когда данные перестают поступать из приложения, и индикатор активности USB перестает мигать.Несколько секунд, обычно до 10 секунд.Я обнаружил, что приложение удерживает метод close(), я предполагаю, ожидая, пока ОС завершит запись буферизованных данных.Я вызываю флеш() после каждой записи, но это, похоже, не влияет на задержку.Я просмотрел документацию по Python в поисках ответа, но ничего не нашел.

Это было полезно?

Решение

Это в некоторой степени зависит от файловой системы, но в некоторых файловых системах, если вы удалите файл до того, как он (весь) будет выделен, ввод-вывод для записи блоков никогда не произойдет.Это также может быть правдой, если вы обрежете его так, чтобы часть, которая все еще пишется, была отрезана.

Не уверен, что вы действительно можете прервать запись, если хотите по-прежнему иметь доступ к данным.Также типы файловых систем, которые это поддерживают (например.xfs, ext4) обычно не используются на USB-накопителях.

Если вы хотите сбросить данные на диск, используйте fdatasync().Простая очистка буфера вашей библиотеки ввода-вывода в ОС не приведет к физической очистке.

Другие советы

Предполагая, что я правильно понимаю, вы хотите иметь возможность «прервать», а НЕ сбрасывать данные.Это возможно, используя ctype и немного покера.Это очень зависит от ОС, поэтому я сообщу вам версию OSX и то, что вы можете сделать, чтобы изменить ее на Linux:

f = open('flibble1.txt', 'w')
f.write("hello world")
import ctypes
x = ctypes.cdll.LoadLibrary('/usr/lib/libc.dylib')
x.close(f.fileno())
try:
  del f
catch IOError:
  pass

Если вы измените /usr/lib/libc.dylib на libc.so.6 в /usr/lib для Linux, то все будет в порядке.По сути, при вызове close() вместо fclose() вызов fsync() не выполняется и ничего не сбрасывается.

Надеюсь, это полезно.

Когда вы прерываете операцию записи, пытаясь выполнить file.truncate(0); прежде чем закрыть его.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top