![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Чтение файлов от конца к началу [D7, WinXP]
X_Tra © (2005-03-15 20:04:00)Вот тут такой вопрос меня интересует.
Насколько я знаю, все существующие в Дельфи функции/процедуры чтения файлов читают блок байт из файла от начала блока к концу и переводят файловый указатель вперёд, устанавливая его на позицию сразу после конца блока.
Хотелось бы узнать, можно ли эту операцию обратить, то есть: прочитать блок байт с конца к началу, сразу заполняя буфер соответствующим образом? А можно ли таким же образом организовать запись в файл? Если можно, то как?
X_Tra (2005-03-16 19:15:00) [21]> Использовать временный файл.
Я не хочу этого делать, см. пояснение в X_Tra (15.03.05 22:24) [7]
Игорь Шевченко (2005-03-16 19:07:00) [22]Alexander Panov © (16.03.05 19:05) [12]
> Но пишется-то в соответствии с направлением вращения диска
Кто сказал ? :)
Alexander Panov (2005-03-16 19:05:00) [23]Игорь Шевченко © (16.03.05 19:01) [11]
Винчестеру вообще-то пофиг, как с него данные читают.
Но пишется-то в соответствии с направлением вращения диска.;)
Игорь Шевченко (2005-03-16 19:01:00) [24]Defunct © (16.03.05 01:24) [9]
Винчестеру вообще-то пофиг, как с него данные читают.
X_Tra © (16.03.05 18:51) [10]
> А как быть с удалением/вставкой блока байт в уже имеющийся
> файл
Использовать временный файл.
X_Tra (2005-03-16 18:51:00) [25]> Defunct © (16.03.05 01:24) [9]
Спасибо, теперь всё ясно: про то, что винчестер в одну сторону вращается, я как-то не подумал :)
А как быть с удалением/вставкой блока байт в уже имеющийся файл (см. мой вопрос выше)?
Defunct (2005-03-16 01:24:00) [26]Винчестер не поддерживает такую дурь на самом низком уровне, потому что диск вращается всегда в одну сторону. Если же Вам приспичило читать "назад" тогда эффективнее всего оперировать блоками равными одному кластеру. Однако Вы лишитесь очень полезной фичи, ускоряющей работу дисковых операций - упреждающего чтения секторов, которое работает только в одном направлении.
Последний кластер будет заполнен не полностью. Поэтому для начала определите объем информации последнего кластера файла, прочитайте его назовем его "остатком", а дальше дело техники FileSeek( FileHandle, <Длина файла - №Блока * Размер кластера - Остаток>, soFromEnd)
llirik (2005-03-16 00:42:00) [27]самый быстрый способ чтения это мэпировать файл, а там можно низкоуровнево читать куда хотите, так как работа происходит к набором байт оперативной памяти
оперировать придется указателями
CreateFile
CreateFileMapping
X_Tra (2005-03-15 22:24:00) [28]> А кто Вам сказал что ОС разрешит нечто низкоуровневое ?
Никто мне этого не говорил, я и сам прекрасно понимаю, что в ОС таких возможностей быть не может
> Я бы и на старый компах не заметил, если использовать потоки
> размещенные в оперативной памяти...
Это потому, что в потоке это всё уже оптимизировано. Но если отвлечься от всех уловок и сделать чтение втупую по одному байту, да ещё взять файл пожирнее, то процесс чтения назад займёт больше времени, чем такой же процесс чтения вперёд (я понимаю, что это глупо и никому не нужно, и никто так делать не будет)...
Ладно, ещё один вопрос: можно ли как-то просто удалить кусок из середины файла? Можно читать из одного файла, а писать в другой, но если файл жирный, а вам надо удалить 5 байт где-то в конце, но не самые последние 5 байт, то использование временного файла неоправданно. Если отречься от использования временного файла и работать только с одним файлом, то это сделать сложнее: нужно всё, что находится после этого вырезаемого блока байт, подвинуть влево, а потом обрезать файл, причём двигать надо через не очень большой буфер, иначе всё подвиснет... Но ведь известно, что файл занимает совокупность кластеров, которые связаны между собой в файловой таблице жёсткого диска. Так что удалить блок байт на низком уровне намного быстрее: задача сводится всего лишь к переприсвоению номеров кластеров в таблице. То же самое, если вы хотите вставить в имеющийся файл блок байт, начиная с определённой позиции.
Подскажите, где я могу найти дельную информацию по низкоуровневому доступу к кластерам на диске (желательно с работающим примером)? Я написал одну программу, которая умеет делать такие специфические операции с файлами (удаление/извлечение/вставка/замещение блока байт другим блоком из другого файла/буфера), и я хочу улучшить её производительность
Fay (2005-03-15 21:59:00) [29]CreateFileMapping & K
Sphinx (2005-03-15 21:47:00) [30]А кто Вам сказал что ОС разрешит нечто низкоуровневое?
Времена когда это было просто сделать канули в лету вместе с DOS-ом...
Зачем вообще такизвращаться ?
Ответ Вам дали, чемSeekне устраивает ?
Если хочешь чтобы это делалось автоматически - создай свой класс - наследник TStream и реализуй в нем " Побайтовое чтение и перемещение указателя на два байта назад." а потом используй где хочешь....
> Я понимаю, что с нынешними HDD (с их скоростями и буферизацией)
> замедление операции будет совершенно незаметно
Я бы и на старый компах не заметил, если использовать потоки, размещенные в оперативной памяти...
X_Tra (2005-03-15 21:29:00) [31]Мда, два раза я получаю идентичный ответ. Ничего не скажешь, спасибо за помощь... :-(
Я понимаю, что с нынешними HDD (с их скоростями и буферизацией) замедление операции будет совершенно незаметно, но всё же: если я читаю один байт, как сделать, чтобы указатель после чтения переместился не вперёд, а назад (без использования FileSeek)?
Anatoly Podgoretsky (2005-03-15 20:28:00) [32]Если знаешь, то зачем спрашиваешь.
Сделать это так " Побайтовое чтение и перемещение указателя на два байта назад."
X_Tra (2005-03-15 20:19:00) [33]Да это-то я и так знаю, но это ведь будет работать немного медленнее. Имеется ввиду нечто низкоуровневое, когда файловый указатель после чтения перемещается не вперёд, а наоборот назад, и буфер, куда производится чтение, заполняется также задом наперёд. Как такое сделать? Прямым обращением к жёсткому диску?
Anatoly Podgoretsky (2005-03-15 20:12:00) [34]Побайтовое чтение и перемещение указателя на два байта назад.