
Мне интересно, если у вас есть особенно большой файл, скажем, 64 МБ, возможно ли выяснить физическое расположение файла на жестком диске, а затем считать байты с определенного смещения в файл?
Допустим, меня интересуют 100 байт со смещением 60 МБ от начала файла. Я не хочу неэффективности сотен дисковых поисков, которые потребовались бы для перехода от начала файла к его концу, если бы я использовал какую-то функцию seek() уровня приложения.
Есть ли решение?
Спасибо!
решение1
Похоже, у вас неправильное представление о том, как seek()
себя ведет. Он находит место, где данные по этому смещению хранятся максимально эффективно, без чтения промежуточных байтов. Будет несколько поисков (вероятно, не сотни), чтобы обойти индекс блока.
Чего вы не можете сделать, так это сохранить обход индекса блока с одного момента открытия файла до следующего. ОС пришлось бы помнить, что файл не был изменен или перемещен с момента последнего открытия, что потребовало бы запоминания большого объема данных для очень небольшого потенциального выигрыша.
Обратите внимание, что содержимое файла не находится в последовательных позициях на диске, в общем случае. Файлы, как правило, фрагментированы. Файловые системы обычно пытаются уменьшить фрагментацию, но в общем случае это не может быть гарантировано.
решение2
Перечитывая, мне кажется, что я не ответил на основной вопрос:
Использование «seek» на уровне приложения (на самом деле, ядра) не обязательно требует каких-либо «поисков» на диске — все, что он делает, это обновляет номер смещения, связанный с дескриптором файла.
Как только вы попросите ядро выполнить чтение или запись, оно преобразует это смещение в смещение на диске, что может потребовать чтения блоков для его определения, но в лучшем случае будет иметь стоимость одного поиска — как и при прямом доступе.
Это абсолютно возможно: это именно то, что делает драйвер файловой системы, в конце концов, так что это должно быть возможно для кого-то еще. Все, что вам нужно, это доступ к сырому диску.
Там являются из Примерылюдей, которые делают это для существующих форматов файловой системы. Вы также можете сделать это вручную, если хотите.
Если файловая система активно используется, у вас возникнут некоторые технические проблемы, которые усложнят задачу (потому что содержимое на диске меняется таким образом, что вы не можете этого увидеть), но это все равно возможно.
Вы также можете напрямую обратиться к ядру;xfs_bmapинструмент делает это, и по крайней мере некоторые файловые системы реализуют тот же интерфейс, так что вы можете задать его напрямую.
Однако вычисление местоположения займет столько же операций поиска, сколько потребовалось бы ядру, поэтому вы вряд ли сэкономитечто-либоделая это.
решение3
Я так не думаю.
Если вы откроете файл, вы окажетесь либо в начале (для чтения/записи), либо в конце (для добавления). Даже в «режиме обновления» вы не просто попадете в какое-то указанное место в середине файла.
Я думаю, лучшее, что вы можете сделать, это то, от чего вы уже уклонились: если вы можете вычислить смещение с самого начала, вы можете напрямую обратиться к этому месту и прочитать данные. Я не думаю, что это повлечет за собой какие-либо чрезмерные операции чтения между ними. Следующее чтение после открытия файла должно быть с вычисленным смещением.