Как стать автором
Обновить

А в чем проблема работать с файлами?

Уровень сложностиСредний
Время на прочтение53 мин
Количество просмотров28K
Всего голосов 171: ↑170 и ↓1+169
Комментарии23

Комментарии 23

Наверное, не совсем по теме, но ложится в проблему «А в чем проблема работать с файлами?»

Нужно открывать файл pdf на третьей странице (windows):  

С:\1.pdf#page3

Или через запись в ячейке в excel:

\\С:\1.pdf#page3

Без использования браузера открыть pdf на нужной странице через #page (или подобное) вообще можно?

Открыть файл с точки зрения пользователя или с точки зрения программиста?

#page3 - это вообще указание фрагмента в семантике URI, браузеры ее поддерживают (для PDF-документов - не всегда), а остальные приложения - не факт

Excel тоже поддерживает открытие файлов по URL, как минимум HTTP(S), но помнится, Excel 2010 падал, если указать в URL фрагмент после #

Открыть файл с точки зрения пользователя или с точки зрения программиста?

С любой, но для начала "с точки зрения программиста".

#page3 - это вообще указание фрагмента в семантике URI, браузеры ее поддерживают (для PDF-документов - не всегда), а остальные приложения - не факт

Так и вопрос в этом "не факт". Может быть есть какие - либо хитрости. Хитрый BAT или Excel или VBA Excel или еще что-то, чтобы без браузера открыть pdf на нужной странице. Любопытно, но ранее считал, что нельзя. Вдруг ошибался?

Я посмотрел: _commit дергает FlushFileBuffers с дополнительными проверками и т.д. Учитывая, что FlushFileBuffers работает с хэндлом ОС, а _commit с файловыми дескрипторами, первая быстрее: не нужно переводить fd в handle. Тут надо написать замечание, что WinAPI функции надо описывать с параметрами hFile, а не fd, но это я занудствую.

Касательно NtFlushBuffersFileEx и того, что она работает только с NT-файловыми системами у меня есть вопрос - где про это написано? Я глянул в MSDN, там ни слова нет о различных ФС :-/


Про открытие в винде каталога - это сделать точно можно, даже документация на CreateFile про это говорит. Плюс есть всякие неочевидные Nt... и Zw... функции, которые могут с каталогами работать

Спасибо за замечание, исправил.

Насчет NtFlushBuffersFileEx - в черновике оставил это замечание и забыл перепроверить: скорее всего где-то прочитал, но найти заново не смог. Удалил на всякий случай, чтобы не дезинформировать

В общем, данные надо хранить не просто в виде файла, а внутри базы SQLite - там большинство проблем уже решено.

там большинство проблем уже решено

Пока приложение однопоточное - может быть. Как только приложение многопоточное - появляются весьма интересные способы выстрелить себе в ногу.

Ну многопоточные приложения вообще заметно интереснее однопоточных)

Эпичный труд. Но самому важному ответу на вопрос «отказоустойчивость» == «избыточность» уделено меньше чем стоило бы

Любопытно, что началось всё с отказоустойчивости приложений. Не смотрели на Phantom OS
https://habr.com/ru/companies/selectel/articles/598679/ ? Там эту проблему решают на уровне ОС, но исходники то открыты.

Для HDD единица чтения и записи - сектор

На HDD с черепичной записью данные пишутся поблочно.

из того что читал - такое поведение скорее редкость, обычно пишутся по секторам, как обычно, которые потом в бекграунде уплотняются. иначе будут жуткие тормоза при записи

Хорошая, полезная и интересная статья. Проведена большая работа. Спасибо.

Замечательный обзор. А с сетевыми фс всё действительно веселее - даже если локально файл создан, записан, закрыт и буфер сброшен, на соседнем хосте в данном каталоге он может ещё даже не появиться.

Дополню немного про Advanced Format и ECC на HDD. Раньше почти у всех дисков был размер сектора 512 байт, но затем производители перешли на 4096, для оптимизации внутренней логики работы диска. При этом многие диски с "физическим" сектором 4096 поддерживают эмуляцию сектора 512 для совместимости со старым оборудованием и ПО, этот размер называют "логическим" размером сектора. Также встречаются диски, у которых и физический и логический размер сектора 4096 байт.

В отдельном ряду стоят серверные SCSI и SAS накопители с размерами сектора 520, 524, 4160 байт и тому подобное. Такой сектор раскладывается на основную часть (512 или 4096) и добавку к ней (8, 16 байт и так далее). Для хранения "пользовательских" данных используется основная часть, а добавка используется СХД (не самим диском, а именно СХД) для дополнительного контроля содержимого.

При всем при этом, если мы пойдем внутрь самого диска, то там каждый сектор, независимо от его размера, тоже снабжается несколькими байтами контрольной суммы, но к этим байтам нет никакого доступа извне. Если при чтении сектора не получится скорректировать все ошибки, том мы получим ошибку чтения.

PS. Работу проделали, конечно, монументальную. Был приятно удивлен в процессе чтения!

Спасибо, интересно. Вот из таких статей должен быть хабр..

Отличная статья!

Можно давать джунам вместе со статьей о работе со временем чтобы сразу приходило осознание того, что мир сложнее, чем кажется на первый взгляд.

Я правильно понимаю, что если писать в базу только мелкие независимые порции данных (до 4кб), то все эти проблемы не страшны: все обновления пройдут атомарно и не надо жонглировать файлами и чексуммами? Единственное, что тут может быть: при ресайзе может остаться куча нулей в конце файла, что легко детектируется.

Не совсем. Да, может только увеличиться размер файла успеть, но:

  • Никто не гарантирует, что там будут 0 - скорее будет случайный мусор

  • Если 4Кб имеется ввиду сектор, то тут больше про атомарность и PSOW - записаться может только часть. Например, корректно инициализируется заголовок, но остальное будет мусором. Без чек-сумм тут не обойтись

  • Писать независимые порции данных - дозапись или перезапись? Перезапись может быть атомарной (в исследовании все были атомарны), но не гарантируется. Дозапись - уже вряд-ли атомарна

  • Дополнительно, необходимо понимать размер сектора - где-то это 512 байт, а где-то 4096. Причем, некоторые диски могут работать в эмулируемом режиме (512e), что затруднит работу

  • Ко всему прочему, в процессе хранения целостность может быть нарушена и без чек-сумм тут не обойтись (накопитель может не справиться с исправлением)

  1. Мусор вместо нулей - это была бы огромная дыра в безопасности. Она точно существует?

  2. Разве современные накопители не обеспечивают атомарность и PSOW?

  3. Дозапись - это же просто ресайз + запись, разве нет?

  4. 512 разве ещё встречаются в дикой природе?

  5. Ну так и мы можем не справиться. Особенно, если накопитель использует тот же алгоритм, что и мы.

  1. Выделение новых блоков памяти - это не тоже самое что и выделение новой памяти. Здесь нельзя просто взять и занулить целую область. В ext режиме ordered сначала может обновиться длина, а что в выделенной области - неизвестно, т.к. предполагается что запись будет успешной.

  2. Про накопители говорить не буду, но из предоставленной таблицы ясно что приложения не преполагают полную атомарность и PSOW. Поэтому их можно использовать в различной инфраструктуре и не покупать специальное оборудование

  3. Да, но тут уже важен порядок этих операций.

  4. Встречается, но как уже писал, на это лучше не полагаться

  5. Какой алгоритм? Накопитель исправляет ошибки, а мы - только обнаруживаем

"Выделение нового участка файла", вместо "Выделение новых блоков памяти" в 1

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории