Перенаправление чтения из файла (Reparse Points?)
От: Albeoris  
Дата: 21.02.16 19:32
Оценка: 24 (2)
Доброго времени суток.

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

С недавних пор стал поглядывать в сторону dokany.
Уже написал обвязку для маунта архива на файловую систему и чтения из него. Но потребуется написать и отладить ещё много кода для поддержки многопоточной записи, дефрагментации и т.д.

И тут подумалось — а за каким лешим я реализую собственную файловую систему с поддержкой записи, когда мне нужно просто распаковать архив в папочку и перенаправить все обращения к оригинальному файлу на эти самые распакованные?

И вот встал вопрос — какими инструментами это можно сделать? На ум приходят в первую очередь Reparse Points с самописным драйвером.
Но есть минусы:
1) Это сложно.
2) Я этого никогда не делал.

В связи с чем вопросы:
1) Есть ли альтернативы?
2) Есть ли возможность описать всё средствами .NET (всевозможные фреймворки и сторонние драйверы с любой лицензией, подобные dokany, привествтуются).
3) Если всё-таки придётся идти сложным путём, может быть кто-нибудь поделится примером кода, который делает описанное выше? Например, первые пять байт из файла D:\archive.bin считываются из файла D:\archive\1.bin, а всё остальное из D:\archive\2.bin ?

Ограничения:
Платформа — Windows
Совместимость с Memory Mapped File
Поддержка многопоточного случайного доступа

Спасибо за любую помощь!
"Хаос всегда побеждает порядок, поскольку лучше организован." (с) Терри Пратчетт
Отредактировано 21.02.2016 19:44 Albeoris . Предыдущая версия .
.net file system reparse points ntfs windows
Re: Перенаправление чтения из файла (Reparse Points?)
От: Михаил Романов Удмуртия https://mihailromanov.wordpress.com/
Дата: 22.02.16 09:36
Оценка: +1 -1
Здравствуйте, Albeoris, Вы писали:

А почему не подходит просто упаковка и распаковка файла через какую-нибудь библиотеку или утилиту?
Почему нужно обязательно это делать "на лету"?
Отредактировано 22.02.2016 11:00 Михаил Романов . Предыдущая версия .
Re[2]: Перенаправление чтения из файла (Reparse Points?)
От: Albeoris  
Дата: 22.02.16 11:49
Оценка:
Здравствуйте, Михаил Романов, Вы писали:

МР>Здравствуйте, Albeoris, Вы писали:


МР>А почему не подходит просто упаковка и распаковка файла через какую-нибудь библиотеку или утилиту?

МР>Почему нужно обязательно это делать "на лету"?
Потому что файл весит 28 Гб и на данный момент приходится поддерживать много инфраструктурного кода в "какой-нибудь утилите", чтобы обеспечить чтение и вставку файлов.
"Хаос всегда побеждает порядок, поскольку лучше организован." (с) Терри Пратчетт
Re[3]: Перенаправление чтения из файла (Reparse Points?)
От: Михаил Романов Удмуртия https://mihailromanov.wordpress.com/
Дата: 22.02.16 12:40
Оценка: +1
Здравствуйте, Albeoris, Вы писали:

A>Потому что файл весит 28 Гб и на данный момент приходится поддерживать много инфраструктурного кода в "какой-нибудь утилите", чтобы обеспечить чтение и вставку файлов.

Я не очень понял оба аргумента.

Что именно плохого в 28 Гб? Ну будет у вас лежать на диске 60Гб... Мне всё же кажется, что покупка винчестера выйдет дешевле человеко-часов на разработку драйвера вашей FS (а у вас в любом случае будет что-то сравнимое по сложности, если вы собираетесь перекрывать стандартный файловый ввод-вывод).
Какие еще сложности помимо удвоения объема?

И еще менее понятен тезис про поддержку инфраструктурного кода. У вас ведь в любом случае есть код для парсинга/создания этого файла. Неужели, утилита на основе этой библиотеки выполняющая всего 2 операции — выложить файл как структуру папок и собрать из структуры папок новый файл будет такой сложной в поддержке?

Может я просто не понимаю специфики вашего случая, но мне казалось что самое простое, это:

Я бы попытался остановиться на таком сценарии и никак не сложнее.
Re[4]: Перенаправление чтения из файла (Reparse Points?)
От: Albeoris  
Дата: 22.02.16 15:28
Оценка:
Здравствуйте, Михаил Романов, Вы писали:

МР>Я не очень понял оба аргумента.

Аргумент номер 0: Я спрашиваю как перенаправить вызов к файлу в другое место, а не как этого не делать.
Аргумент номер 1: Для того чтобы вытащить файл из зишфрованного сжатого архива, необходимо его расшифровать и разжать. Ждать по 5 минут для того чтобы получить один единственный файл — накладно.
Аргумент номер 2: Для того чтобы воткнуть файл в зашифрованный сжатый архив с механизмом контроля целостности, необходимо его расшифровать и разжать, посчитать контрольные суммы всех файлов, заменить один из них своим, если он не помещается в старое место — переложить его в конец архива, если это происходит в архиве второго уровня вложенности, проделать это ещё и с ним, после чего собрать все файлы в архив, сжать и зашифровать их, обновить индексы. Ждать по 40 минут и занимать по 60Гб места на диске для того чтобы добавить в архив один файл — очень накладно. Синхронизировать чтение и запись в это архив — ещё веселее.

Зачем делать это, если можно просто положить рядом новый файл, читать из него, если он есть, или из оригинала, если его нет?

МР>Что именно плохого в 28 Гб? Ну будет у вас лежать на диске 60Гб... Мне всё же кажется, что покупка винчестера выйдет дешевле человеко-часов на разработку драйвера вашей FS (а у вас в любом случае будет что-то сравнимое по сложности, если вы собираетесь перекрывать стандартный файловый ввод-вывод).

Я морально не готов покупать винчестер каждому пользователю. Как я писал ранее, мне не нужно перекрывать стандартный файловый ввод, только вывод, что упрощает задачу до примитивного уровня. Осталось лишь найти подходящий инструмент.

МР>И еще менее понятен тезис про поддержку инфраструктурного кода. У вас ведь в любом случае есть код для парсинга/создания этого файла. Неужели, утилита на основе этой библиотеки выполняющая всего 2 операции — выложить файл как структуру папок и собрать из структуры папок новый файл будет такой сложной в поддержке?

Эта утилита также представляет содержимое многомерного архива в виде файлового древа, умеет работать в режиме случайного доступа и параллельного чтения/записи. И, фактически, 80% кода, который сейчас написан (включая интерфейс — окна, диалоги) направлен на поддержку именно этой части.

МР>Может я просто не понимаю специфики вашего случая, но мне казалось что самое простое, это:

МР> Так происходит сейчас.

МР>Я бы попытался остановиться на таком сценарии и никак не сложнее.

Я пробовал, мне не понравилось.
"Хаос всегда побеждает порядок, поскольку лучше организован." (с) Терри Пратчетт
Re: Перенаправление чтения из файла (Reparse Points?)
От: Albeoris  
Дата: 22.02.16 21:55
Оценка:
Собственно, сейчас вернулся к dokany.
Он, к сожалению, не умеет монтировать виртуальные файлы на файловую ситсему, а примаунченая папка считается другим диском, на который NTFS не может создать hard link. Но если пропускать все обращения к конкретной папке через драйвер, то это работает.

http://i.imgur.com/FAGMC9y.png
Оригинальные файлы лежат в папочке "_sys". Все обращения к "sys" пропускаются через драйвер, который отдаёт то, что нужно мне.
Не самое красивое решение, так как при необходимости заменить 1-2 файла приходится виртуализировать всю папку.

Также был найден некий CallbackFilter, который делает примерно тоже самое, но уже за деньги.
Так что я всё ещё в поиске.
"Хаос всегда побеждает порядок, поскольку лучше организован." (с) Терри Пратчетт
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.