2010-03-16 2 views
3

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

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

+0

Это полностью зависит от ОС и файловой системы. «Правильное» поведение (при обычном, асинхронном монтаже) заключается в немедленном возврате функции close(); он должен ждать только флеш, если вы явно fdatasync(). Вероятно, вы вряд ли найдете переносной способ изменить это поведение, так как оно будет сильно различаться в разных системах. (Начиная с XP или около того, Windows даже не записывает кеш на USB-диски по умолчанию.) –

ответ

2

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

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

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

+0

Хммм ... это интересно, позвольте мне попробовать ... – Therealstubot

2

Предполагая, что я понимаю это правильно, вы хотите иметь возможность «прервать» и НЕ промывать данные. Это возможно, используя ctype и немного pokery. Это очень зависимые от ОС, так что я дам вам версию 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() не выполняется, и ничего не очищается.

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

+0

Ли, похоже, что он должен работать, однако, я не может получить желаемое поведение. Я вызвал x.close (f.fileno()), и он по-прежнему выполнил флеш, блокируя вызов close(), точно так же, как и команда python close(). – Therealstubot

+0

Если это произошло, то .close() на самом деле не вызвали. Вы можете проверить, проверив код возврата. Если вы получаете None или число, это не сработало - если вы получите 0 (ноль), то это произошло. – Lee

1

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

Смежные вопросы