Транзакционная обработка текстовых файлов в Windows
У меня есть несколько программ Windows (работает на Windows 2000, XP и 7), которые обрабатывают текстовые файлы разных форматов (csv, tsv, ini и xml). Очень важно не повредить содержимое этих файлов во время ввода-вывода файла. Каждый файл должен быть безопасно доступен несколькими программами одновременно и должен быть устойчив к сбоям системы. Это так ответ предлагает использовать базу данных в процессе, поэтому я рассматриваю возможность использования Microsoft Jet Database Engine, который способен обрабатывать текстовые файлы с разделителями (csv, tsv), и поддерживает транзакции. Я использовал Jet раньше, но я не знаю, действительно ли транзакции Jet допускают неожиданные сбои или остановки на этапе фиксации, и я не знаю, что делать с текстовыми файлами без разделителей (ini, xml). Я не думаю, что это хорошая идея, чтобы попытаться реализовать полностью кислотный файл IO вручную.
каков наилучший способ реализации транзакционной обработки текстовых файлов в Windows? Я должен иметь возможность делать это как в Delphi, так и в C#.
Спасибо за вашу помощь заранее.
редактировать
давайте посмотрим пример, основанный на идее @SirRufo. Забудьте о параллелизме на секунду, и давайте сосредоточимся на отказоустойчивости.
Я прочитал содержимое файла в структуру данных, чтобы изменить некоторые поля. Когда я в процессе записи измененных данных обратно в файл, система может аварийно завершить работу.
повреждение файла можно избежать, если я никогда не буду записывать данные обратно в исходный файл. Это может быть легко достигнуто путем создания нового файла с меткой времени в имени файла при каждом сохранении изменения. Но этого недостаточно: исходный файл останется нетронутым, но вновь написанный может быть поврежден.
Я могу решить эту проблему, поставив символ " 0 " после метки времени, что означало бы, что файл не был проверен. Я бы закончил процесс записи шагом проверки: я бы прочитал новый файл, сравнил его содержимое со структурой в памяти, которую я пытаюсь сохранить, и если они одинаковы, то измените флаг на "1". Каждый раз, когда программа должна прочитать файл, она выбирает самую новую версию, сравнивая временные метки в имени файла. Должна быть только последней версии, старые версии могут быть удалены.
параллелизм может быть обработан ожиданием именованного мьютекса перед чтением или писать файл. Когда программа получает доступ к файлу, она должна начать с проверки списка имен файлов. Если он хочет прочитать файл, он будет читать новую версию. С другой стороны, запись может быть запущена только в том случае, если нет версии более новой, чем та, что была прочитана в прошлый раз.
это грубый, упрощенный и неэффективный подход, но он показывает, о чем я думаю. Написание файлов небезопасно, но, возможно, есть простые трюки, такие как тот, который выше может помочь избежать повреждения файлов.
обновление
решения с открытым исходным кодом, написанные на Java:
- Атомарные Файловые Транзакции:статьи-1, статья 2, исходный код
- Java Atomic File Transaction (JAFT): проект дома
- XADisk: учебник, исходный код
- AtomicFile: описание, исходный код
6 ответов
Как насчет использования потоков файлов NTFS? Запишите несколько именованных (пронумерованных/помеченных временем) потоков в одно и то же имя файла. Каждая версия может храниться в другом потоке, но на самом деле хранится в том же "файле" или куче файлов, сохраняя данные и обеспечивая механизм отката... когда вы достигнете определенной точки, удалите некоторые из предыдущих потоков.
введено в NT 4? Она охватывает все версии. Должно быть доказательство сбоя, у вас всегда будет предыдущая версия / поток плюс оригинал для восстановления / отката.
просто поздняя ночная мысль.
http://msdn.microsoft.com/en-gb/library/windows/desktop/aa364404%28v=vs.85%29.aspx
то, что вы просите, - это транзакционность, которая невозможна без разработки механизма базы данных РСУБД в соответствии с вашими требованиями:
"очень важно не повредить содержимое этих файлов во время ввода-вывода файла"
пикап СУБД.
см. связанный пост доступ к одному файлу с несколькими потоками Однако мое мнение заключается в том, чтобы использовать базу данных, такую как Raven DB для таких транзакций, Raven DB поддерживает параллельный доступ к одному и тому же файлу, а также поддерживает пакетирование нескольких операций в один запрос. Однако все сохраняется как документы JSON, а не текстовые файлы. Он поддерживает .NET / C# очень хорошо, включая Javascript и HTML, но не Delphi.
прежде всего, этот вопрос не имеет ничего общего с C# или Delphi. Вы должны имитировать свою файловую структуру, как если бы она была базой данных.
предположения;
перемещение файлов-это дешевый процесс и оп система гарантирует, что файлы не будут повреждены во время перемещения.
у вас есть один каталог файлов, которые необходимо обработать. (d:\filesDB*.*)
приложение контроллера это необходимо.
Упрощенный Рабочий Процесс;
-инициализации
- получает processID из операционной системы.
-
создает каталоги в d:\filesDB
d:\filesDB\<processID> d:\filesDB\<processID>\inBox d:\filesDB\<processID>\outBox
-процесс для каждого файла
- Выберите файл для обработки.
- переместить его в каталог "входящие" (обеспечивает единый доступ к файлам)
- открыть файл
- создать новый файл в "исходящие" и закрыть его должным образом
- удалить файл в каталоге "входящие".
- переместить вновь созданный файл, расположенный в" исходящие " обратно в d:\filesDB
-finallization
- удалить созданные папки.
Приложение
запускается только при запуске системы и инициализирует приложения, которые будут выполнять эту работу.
- сканирование d:\filesDB каталог для подкаталогов,
- для каждого подкаталога 2.1 если файл существует в папке "Входящие", переместите его в d:\filesDB и пропустить "исходящие". 2.2 если файл существует в папке "исходящие", переместите его в d:\filesDB 2.3 удалите весь подкаталог.
- запустите каждый рабочий процесс, который необходимо запустить.
Я надеюсь, что это решит вашу проблему.
хорошо, вы мертвы-если вы не можете бросить XP. Вот так просто.
поскольку после XP Windows поддерживает транзакционные NTFS-хотя он не подвергается .NET (изначально - вы все еще можете использовать его). Это позволяет откатывать или фиксировать изменения в файловой системе NTFS с помощью DTC даже в координации с базой данных. Очень мило. XP, хотя-нет, не там.
начинаются любой реальный опыт корпоративного уровня с транзакционными NTFS (TxF)? как начинающий. Вопрос есть много ресурсов, чтобы вы начали, как это сделать.
обратите внимание, что у этого есть накладные расходы на производительность - очевидно. Это не так плохо, хотя, если вам не нужен второй транзакционный ресурс, так как там есть очень тонкий координатор транзакций уровня ядра, транзакции только повышаются до полного DTC, когда добавляется второй ресурс.
для прямой связи -http://msdn.microsoft.com/en-us/magazine/cc163388.aspx есть хорошая информация.
вы создаете кошмар для себя, пытаясь обрабатывать эти транзакции и состояния в своем собственном коде в нескольких системах. Вот почему Ларри Эллисон (генеральный директор Oracle) - миллиардер, а большинство из нас-нет. Если вам абсолютно необходимо использовать файлы, настройте Oracle или другую базу данных, поддерживающую объекты LOB и CLOB. Я храню очень большие SVG файлы в такой таблице для моей компании, чтобы мы могли добавлять и отображать большие карты в наши системы без каких-либо изменений кода. Файлы могут быть извлекается из таблицы и передается пользователям в буфере, а затем возвращается в базу данных, когда они закончат. Настройте соответствующую защиту и блокировку записи, и ваша проблема будет решена.