Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2009.09.27;
Скачать: [xml.tar.bz2];

Вниз

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

 
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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.51 MB
Время: 0.005 c
15-1248550533
Эстет
2009-07-25 23:35
2009.09.27
Футболки?


4-1217571568
mistic
2008-08-01 10:19
2009.09.27
непростое контекстное меню


2-1248414854
Abcdef123
2009-07-24 09:54
2009.09.27
2 вопроса.


15-1248820391
DillerXX
2009-07-29 02:33
2009.09.27
экспортировать плейлисты из библиотеки винампа


2-1248255936
Bruth
2009-07-22 13:45
2009.09.27
Помогите сделать поиск всех папок в папке





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский