Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2009.09.27;
Скачать: CL | DM;

Вниз

Чтение/запись файла в отдельном потоке   Найти похожие ветки 

 
DevilDevil ©   (2009-07-22 11:01) [0]

Есть ли какие рекомендации? Код?
Как обработать ошибки, отменить, "сделать паузу"?
Какими блоками читать/писать?


 
Юрий Зотов ©   (2009-07-22 11:15) [1]

Что-то типа этого:

Execute:

while not Terminated do
try
 while Pause do // Pause - булевское поле (или свойство) потока
   Sleep(1);
 Читать (или писать) блок
except
 Передать в GUI сообщение об ошибке
 Terminate
end;

GUI:

Кнопка "Пауза": Thread.Pause := True;
Кнопка "Продолжить": Thread.Pause := False;
Кнопка "Прервать": Thread.Terminate;


 
DevilDevil ©   (2009-07-22 11:21) [2]

какой размер блока нужно выставлять? 16кб?
при чтении/записи на CD/флешки/ломаного винта может возникать ошибка. Как её отловить? Ничего не зависнит?


 
Palladin ©   (2009-07-22 11:33) [3]


> какой размер блока нужно выставлять? 16кб?

А какая разница в размере блока при использовании основного или дополнительного потока?


> Как её отловить?

А как ты ее в основном отлавливаешь?


> Ничего не зависнит?

А что зависнит? Основной поток виснит?


 
DevilDevil ©   (2009-07-22 11:37) [4]

> А какая разница в размере блока при использовании основного
> или дополнительного потока?

если не ошибаюсь, чтение/запись файлов происходит по 16кб. Или 32. Или как-то по другому

> А как ты ее в основном отлавливаешь?
Никак
С такими вещами ещё не сталкивался


 
Palladin ©   (2009-07-22 11:40) [5]


> [4] DevilDevil ©   (22.07.09 11:37)


Так ты вообще получается читать/писать не умеешь. С этого и надо начинать.


 
Юрий Зотов ©   (2009-07-22 11:46) [6]

> DevilDevil ©   (22.07.09 11:37) [4]

Сначала сделайте пробную программу, где все происходит в одном потоке. Отладьте ее. Затем код чтения/записи вынесите в отдельный поток.

Размер блока может быть любым, Вы должны выбрать его сами (например, один байт - система сама все прокэширует как ей нужно). Он определяется структурой читаемых/записываемых данных, а не потоками.

Отлов ошибок: try-except, либо проверка IOResult (детали - в справке). От потоков это тоже не зависит.


 
DevilDevil ©   (2009-07-22 12:12) [7]

Использую всегда TFileStream
и не парюсь с IOResult, try/except... или тем более слуачаями, когда тупой юзер вынул сидиром в момент чтения


 
Sapersky   (2009-07-22 13:21) [8]

например, один байт - система сама все прокэширует как ей нужно

Насколько помню собственные опыты - плохо она кэширует. Разница между чтением по одному байту и большими фрагментами всегда была заметна. Т.е. при повторном чтении - да, будет и по одному байту быстро (относительно - лишние вызовы функций тоже скорости не добавляют), но кому нужно читать одно и то же несколько раз?
Аналогично с записью.
В D2009, кстати, к TFileStream наконец-то прикрутили буферизацию. Интересно, зачем, если можно читать по одному байту и разницы никакой нет...
Паскалевский TextFile тоже использует буфер.


 
clickmaker ©   (2009-07-22 13:27) [9]

> [2] DevilDevil ©   (22.07.09 11:21)
> какой размер блока нужно выставлять? 16кб?

размер блока в идеале должен быть кратен размеру кластера.
Но есть нюансы. Запись по сети, на флэшку и т.д. Разные контроллеры по-разному буферизуют.
При записи на локальный диск лучше брать буфер побольше, н-р 1/5-1/10 размера файла, учитывая количество свободной оперативки. Потому как при недостатке пойдет своп и толку от буфера - ноль.
При записи по сети можно фиксированного размера 2048 или 4096.
При записи на съемный носитель я замечал притормаживание при большом размере буфера.


 
Anatoly Podgoretsky ©   (2009-07-22 13:41) [10]


> Sapersky   (22.07.09 13:21) [8]

Кеширует она хорошо, потери идут за счет вызова функции, толи вызвать 4096 раз по байту, толи один раз, но 4096 байт. Вызов функции занимает много времени.

В 2009 это перевели на уровень программы, а не ОС, на уровне ОС также кеширование продолжается.


 
Игорь Шевченко ©   (2009-07-22 14:01) [11]

clickmaker ©   (22.07.09 13:27) [9]


> размер блока в идеале должен быть кратен размеру кластера.


размеру страницы, раз уж на то пошло.


> При записи на локальный диск лучше брать буфер побольше,
>  н-р 1/5-1/10 размера файла, учитывая количество свободной
> оперативки. Потому как при недостатке пойдет своп и толку
> от буфера - ноль.


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


> При записи по сети можно фиксированного размера 2048 или
> 4096.


Опять же, товарищ проводник использует 65536 байт.


> При записи на съемный носитель я замечал притормаживание
> при большом размере буфера.


А это зависит исключительно от возможности безопасного извлечения съемного носителя.


 
clickmaker ©   (2009-07-22 14:22) [12]

> А это зависит исключительно от возможности безопасного извлечения
> съемного носителя.

возможно. Но вот при чтении с сидюка большими блоками я неоднократно замечал тормоза.


 
Игорь Шевченко ©   (2009-07-22 14:40) [13]

clickmaker ©   (22.07.09 14:22) [12]

Так может сидюк того, поцарапанный ? :) Я досконально не знаю, как система в этом случае делает retry, только на сбойное место с размером блока CDFS или на размер всей операции ввода-вывода.


 
DevilDevil ©   (2009-07-22 15:31) [14]

Так по сколько буферизировать: 4кб или 64 ? Или как?

Как отловить ситуацию, если в процессе записи юзер вынимает флешку или диск? Или диск царапан?


 
clickmaker ©   (2009-07-22 15:53) [15]

> Как отловить ситуацию, если в процессе записи юзер вынимает
> флешку или диск?

try-except или по результату пишущей функции + GetLastError

либо WM_DEVICECHANGE, но это отдельно


 
DevilDevil ©   (2009-07-22 16:03) [16]

> try-except или по результату пишущей функции + GetLastError
Примерчик бы где посмотреть )


 
DVM ©   (2009-07-22 16:05) [17]


> Как отловить ситуацию, если в процессе записи юзер вынимает
> флешку или диск? Или диск царапан?

Операционная система все отловит и оповестит тебя.  Анализируй результаты функций WinAPI и будет все ок.


 
Anatoly Podgoretsky ©   (2009-07-22 16:24) [18]


> Примерчик бы где посмотреть )

А в [1] это не пример?


 
clickmaker ©   (2009-07-22 16:39) [19]

> Примерчик бы где посмотреть )

try
...
if not WriteFile(hFile, Data, BytesToWrite, BytesWritten, nil) then
  RaiseLastWin32Error();
except
  on E: Exception do ShowMessage("юзер вынимает флешку или диск? Или диск царапан? Короче, вот: " + E.Message);
end;


 
DevilDevil ©   (2009-07-22 16:42) [20]

>clickmaker ©   (22.07.09 16:39) [19]
Тема
А с FileStream не получится, да?


 
clickmaker ©   (2009-07-22 16:48) [21]

давно бы уже попробовал...
тоже самое: try-except-finally для закрытия стрима в любом случае


 
DevilDevil ©   (2009-07-22 16:59) [22]

В Read/Write судя по всему результат будет 0
Тогда можно RaiseLastWin32Error


 
DevilDevil ©   (2009-07-24 15:43) [23]

Всем спасибо!
Судя по всему - всё получается



Страницы: 1 вся ветка

Текущий архив: 2009.09.27;
Скачать: CL | DM;

Наверх




Память: 0.53 MB
Время: 0.015 c
2-1248165639
bag
2009-07-21 12:40
2009.09.27
рисовать в ondrawcell


1-1216545032
jurez
2008-07-20 13:10
2009.09.27
работа в BASIC с объектом из DELPHI DLL


15-1248465837
dbng
2009-07-25 00:03
2009.09.27
А вот скажите, кому принадлежат права на информацию


2-1248203029
Тимур
2009-07-21 23:03
2009.09.27
Как упрощенно вносить изменения в реестре


15-1248650332
Petr V. Abramov
2009-07-27 03:18
2009.09.27
Центры НТТМ