![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Чтение/запись файла в отдельном потоке
DevilDevil © (2009-07-22 11:01:00)Есть ли какие рекомендации? Код?
Как обработать ошибки, отменить, "сделать паузу"?
Какими блоками читать/писать?
DevilDevil (2009-07-24 15:43:00) [1]Всем спасибо!
Судя по всему - всё получается
DevilDevil (2009-07-22 16:59:00) [2]В Read/Write судя по всему результат будет 0
Тогда можно RaiseLastWin32Error
clickmaker (2009-07-22 16:48:00) [3]давно бы уже попробовал...
тоже самое: try-except-finally для закрытия стрима в любом случае
DevilDevil (2009-07-22 16:42:00) [4]>clickmaker © (22.07.09 16:39) [19]
Тема
А с FileStream не получится, да?
clickmaker (2009-07-22 16:39:00) [5]> Примерчик бы где посмотреть )
try
...
if not WriteFile(hFile, Data, BytesToWrite, BytesWritten, nil) then
RaiseLastWin32Error();
except
on E: Exception do ShowMessage('юзер вынимает флешку или диск? Или диск царапан? Короче, вот: ' + E.Message);
end;
Anatoly Podgoretsky (2009-07-22 16:24:00) [6]
> Примерчик бы где посмотреть )
А в [1] это не пример?
DVM (2009-07-22 16:05:00) [7]
> Как отловить ситуацию, если в процессе записи юзер вынимает
> флешку или диск? Или диск царапан?
Операционная система все отловит и оповестит тебя. Анализируй результаты функций WinAPI и будет все ок.
DevilDevil (2009-07-22 16:03:00) [8]> try-except или по результату пишущей функции + GetLastError
Примерчик бы где посмотреть )
clickmaker (2009-07-22 15:53:00) [9]> Как отловить ситуацию, если в процессе записи юзер вынимает
> флешку или диск?
try-except или по результату пишущей функции + GetLastError
либо WM_DEVICECHANGE, но это отдельно
DevilDevil (2009-07-22 15:31:00) [10]Так по сколько буферизировать: 4кб или 64 ? Или как?
Как отловить ситуацию, если в процессе записи юзер вынимает флешку или диск? Или диск царапан?
Игорь Шевченко (2009-07-22 14:40:00) [11]clickmaker © (22.07.09 14:22) [12]
Так может сидюк того, поцарапанный ? :) Я досконально не знаю, как система в этом случае делает retry, только на сбойное место с размером блока CDFS или на размер всей операции ввода-вывода.
clickmaker (2009-07-22 14:22:00) [12]> А это зависит исключительно от возможности безопасного извлечения
> съемного носителя.
возможно. Но вот при чтении с сидюка большими блоками я неоднократно замечал тормоза.
Игорь Шевченко (2009-07-22 14:01:00) [13]clickmaker © (22.07.09 13:27) [9]
> размер блока в идеале должен быть кратен размеру кластера.
размеру страницы, раз уж на то пошло.
> При записи на локальный диск лучше брать буфер побольше,
> н-р 1/5-1/10 размера файла, учитывая количество свободной
> оперативки. Потому как при недостатке пойдет своп и толку
> от буфера - ноль.
Товарищ Оракл вывел цифру в 1 мегабайт для единичной операции ввода-вывода. Товарищ проводник, который Explorer, использует буфер в 65536 байт.
> При записи по сети можно фиксированного размера 2048 или
> 4096.
Опять же, товарищ проводник использует 65536 байт.
> При записи на съемный носитель я замечал притормаживание
> при большом размере буфера.
А это зависит исключительно от возможности безопасного извлечения съемного носителя.
Anatoly Podgoretsky (2009-07-22 13:41:00) [14]
> Sapersky (22.07.09 13:21) [8]
Кеширует она хорошо, потери идут за счет вызова функции, толи вызвать 4096 раз по байту, толи один раз, но 4096 байт. Вызов функции занимает много времени.
В 2009 это перевели на уровень программы, а не ОС, на уровне ОС также кеширование продолжается.
clickmaker (2009-07-22 13:27:00) [15]> [2] DevilDevil © (22.07.09 11:21)
> какой размер блока нужно выставлять? 16кб?
размер блока в идеале должен быть кратен размеру кластера.
Но есть нюансы. Запись по сети, на флэшку и т.д. Разные контроллеры по-разному буферизуют.
При записи на локальный диск лучше брать буфер побольше, н-р 1/5-1/10 размера файла, учитывая количество свободной оперативки. Потому как при недостатке пойдет своп и толку от буфера - ноль.
При записи по сети можно фиксированного размера 2048 или 4096.
При записи на съемный носитель я замечал притормаживание при большом размере буфера.
Sapersky (2009-07-22 13:21:00) [16]например, один байт - система сама все прокэширует как ей нужно
Насколько помню собственные опыты - плохо она кэширует. Разница между чтением по одному байту и большими фрагментами всегда была заметна. Т.е. при повторном чтении - да, будет и по одному байту быстро (относительно - лишние вызовы функций тоже скорости не добавляют), но кому нужно читать одно и то же несколько раз?
Аналогично с записью.
В D2009, кстати, к TFileStream наконец-то прикрутили буферизацию. Интересно, зачем, если можно читать по одному байту и разницы никакой нет...
Паскалевский TextFile тоже использует буфер.
DevilDevil (2009-07-22 12:12:00) [17]Использую всегда TFileStream
и не парюсь с IOResult, try/except... или тем более слуачаями, когда тупой юзер вынул сидиром в момент чтения
Юрий Зотов (2009-07-22 11:46:00) [18]> DevilDevil © (22.07.09 11:37) [4]
Сначала сделайте пробную программу, где все происходит в одном потоке. Отладьте ее. Затем код чтения/записи вынесите в отдельный поток.
Размер блока может быть любым, Вы должны выбрать его сами (например, один байт - система сама все прокэширует как ей нужно). Он определяется структурой читаемых/записываемых данных, а не потоками.
Отлов ошибок: try-except, либо проверка IOResult (детали - в справке). От потоков это тоже не зависит.
Palladin (2009-07-22 11:40:00) [19]
> [4] DevilDevil © (22.07.09 11:37)
Так ты вообще получается читать/писать не умеешь. С этого и надо начинать.
DevilDevil (2009-07-22 11:37:00) [20]> А какая разница в размере блока при использовании основного
> или дополнительного потока?
если не ошибаюсь, чтение/запись файлов происходит по 16кб. Или 32. Или как-то по другому
> А как ты ее в основном отлавливаешь?
Никак
С такими вещами ещё не сталкивался