Чи є правильний спосіб створити формат файлу?


12

Я будую фірмовий формат файлу для програми, яку я написав у C # .NET, щоб зберігати інформацію про збереження та, можливо, внизу лінійних активів проекту. Чи існує стандарт, як це зробити будь-яким способом? Я просто збирався до Serializeсвоїх об'єктів у бінарний файл і створив заголовок, який би розповів, як розібрати файл. Це поганий підхід?


2
Я б уникнув BinaryFormatter.
CodesInChaos

3
Який би підхід (з відповідей) ви не вибрали, завжди додайте номер версії у форматі! Ваше запитання вже підказує, що воно може змінитися, і номер версії заощадить вам багато зусиль, якщо вам доведеться підтримувати зворотній режим.
Ян Догген

Не забудьте правильно задокументувати формат
Basile Starynkevitch

Відповіді:


11

Найбільш прямий метод - це, ймовірно, серіалізація вашої структури до XML за допомогою XMLSerializerкласу. Можливо, вам не потрібно буде створювати окремий заголовок та структуру тіла - але серіалізувати всі активи в XML. Це дозволяє легко перевіряти / редагувати вашу файлову структуру за межами власної програми та легко управляти.

Однак якщо ваша файлова структура дійсно складна, містить безліч різних активів різних типів, наприклад, серіалізація всієї структури в XML є занадто обтяжливою, ви можете подивитися на серіалізацію кожного ресурсу окремо та компіляцію їх в один пакет за допомогою Packagingбібліотеки в C # . По суті, так побудовані формати .docx, .xslx, .pptx та інших офісних файлів.


Так, мій проект набагато складніше, ніж просто це, але я також намагаюся зробити його менш зрозумілим для користувачів, оскільки ми можемо розгорнути їх у полі в ліцензованому контексті. Зараз я використовую protobuf-netдля серіалізації своїх даних, і це дуже добре працює. Але я мушу серіалізувати шматки окремо, тому те, про що ви говорите з бібліотекою Packaging, звучить як те, що мені потрібно.
корилулу

7
Шановний бог, не XML
Джеймс

2
@James так, звичайно, XML має свої мінуси. Я віддаю перевагу упаковці та XML у більшості випадків з тих же причин: 1. це вже існуюча рамка, тому вимагає малих зусиль. 2. Підтримувати інші системи легко, оскільки це загальноприйнятий стандарт. 3. Людині легко перевірити отриманий файл, щоб перевірити процес серіалізації.
pswg

XML має переваги, але саме через ті переваги мені не подобається використовувати серіалізатор XML. Я вважаю, що для цього потрібен XML у певному форматі. XML - це напівструктурований формат, який дозволяє мій формат файлів змінюватися з часом і все ще бути сумісним назад і навіть вперед. Раніше я писав власний аналіз XML, остерігаючись, щоб не робити припущень щодо замовлення або не бути тегів, про які я не знаю в майбутньому. Якщо ви можете завантажити весь XML-файл, XPATH, ймовірно, буде працювати досить добре. Інакше ліворуч з дещо складнішим потоковим розбором
Алан

Я б запропонував заглянути в JSON
Basile Starynkevitch

7

У когось, кому довелося розібрати безліч форматів файлів, я маю на це думку з більшої точки зору більшості.

  • Зробіть магічне число дуже унікальним, щоб люди-детектори форматів файлів для інших форматів не неправильно ідентифікували його як ваш. Якщо ви використовуєте двійковий код, виділіть 8 або 16 випадково генерованих байтів на початку бінарного формату для магічного числа. Якщо ви використовуєте XML, виділіть належне простір імен у вашому домені, щоб він не міг зіткнутися з іншими людьми. Якщо ви використовуєте JSON, Бог вам допоможе. Можливо, хтось уже розібрався з рішенням цієї гидоти формату.

  • План зворотної сумісності. Зберігайте номер версії формату якось так, щоб пізніші версії програмного забезпечення могли вирішувати відмінності.

  • Якщо файл може бути великим або в ньому є його розділи, які люди могли б хотіти пропустити через якусь причину, переконайтеся, що є хороший спосіб це зробити. XML, JSON та більшість інших текстових форматів особливо жахливі для цього, оскільки вони змушують читача проаналізувати всі дані між початковим та кінцевим елементом, навіть якщо вони не переймаються цим. EBML дещо кращий, оскільки він зберігає довжину елементів, що дозволяє пропускати до кінця. Якщо ви робите нестандартний бінарний формат, є досить поширений дизайн, де ви зберігаєте ідентифікатор фрагменту та довжину як першу річ у заголовку, і тоді читач може пропустити весь фрагмент.

  • Зберігайте всі рядки в UTF-8.

  • Якщо ви дбаєте про довгострокову розширюваність, зберігайте всі цілі числа у формі змінної довжини.

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


+1 за те, що я дав мені зрозуміти, що я не єдина людина, яка вважає, що json - це гидота формату.
RubberDuck

Чому ненависть до json? Просто поставте відому рядок у відоме місце, щоб визначити формат. Проблема вирішена.
Есбен Сков Педерсен

Це не ідеально, але він працює безперешкодно з javascript, швидший розбір, ніж XML та менший розмір, і все ще читається людиною.
корилулу

1
"Чому ненависть до JSON?" Немає підтримки для читаних людьми коментарів, виходу з ладу Unicode та дивного синтаксису, який вимагає від мене цитування ключів, хоча вони ніколи не містять пробілу. Плюс звичайна неможливість розширювати речі, тому що ніхто не думав про простору імен ... до того моменту, коли ви вирішите це, ви закінчите щось, що виглядає навіть гірше, ніж XML в першу чергу, все для чого, вигода уникати певного кута дужки?
Трежказ

Так, але як і у всіх випадках програмування, використовуйте правильний інструмент для роботи. Є програми, де XML кращий, ніж JSON, і навпаки.
корилулу

4

Що ж, бувають випадки, які ви описуєте, може бути дуже поганим підходом. Це припущення, коли ви говорите "серіалізувати", ви говорите про використання здатності мови / рамки просто брати об'єкт і виводити безпосередньо в якийсь бінарний потік. Проблема полягає в зміні класових структур з роками. Чи зможете ви завантажити файл, створений у попередній версії програми, якщо всі ваші класи змінитимуться на новішу?

Для довгострокової стабільності файлового формату я вважаю, що краще трохи засунути рукави зараз і спеціально написати свої власні методи "серіалізації" / "потокової передачі" у своїх класах. тобто вручну обробляти запис значень у потоці. Напишіть заголовок, коли ви описуєте форматну версію, а потім дані, які ви хочете зберегти у тому порядку, в якому ви хочете. З боку читання, обробляти різні версії файлового формату стає набагато простіше.

Інший варіант, звичайно, XML або JSON. Не обов'язково найбільший для бінарного важкого контенту, але простий і зрозумілий для людини ... великий плюс для довготривалої життєздатності.


Я серіалізую за допомогою protobuf-net ( code.google.com/p/protobuf-net ), який можна розширити. Але ваші бали справедливі, проте, я не думаю, що це будь-який метод формату файлу, який не захищений від цього.
корилулу

Так ... ось чому я кажу, що іноді потрібно просто забруднити руки та обробляти порядок, коли дані записуються та завантажуються вручну.
GrandmasterB

Додаток, який я будую, далеко динамічний і має занадто багато значень для чогось подібного.
корилулу

1
Чим складніше додаток, тим важливіше мати дуже тонкий контроль над форматом файлу. Майте на увазі, я не кажу, що кожен клас не повинен мати власний об'ємний результат ... просто, що ви повинні контролювати це для кожного класу. Тоді просто зателефонуйте до цих процедур.
гросмайстерB

Так, у мене є методи, які модернізують застарілі версії до сучасних версій, і я маю дуже чітке розташування моїх класів. Я не надто переживаю з цього приводу, але я згоден, що це важливо. Я працюю над цим майже рік, тож маю досить чітке уявлення про те, як працює структура.
корилулу

1

Я також люблю , щоб почути відповіді на це питання від людей з великим досвідом років , ніж я.

Я особисто реалізував кілька форматів файлів для своєї роботи, і перейшов до використання формату файлів XML. Мої вимоги та обладнання, з яким я взаємодію, постійно змінюються, і немає жодної інформації про те, що мені потрібно буде додати до формату в майбутньому. Однією з головних переваг XML є те, що він напівструктурований . З цієї причини я, як правило, уникаю автоматичної XML-серіалізації, яку надає .NET, оскільки я вважаю, що вона змушує її очікувати точного формату.

Моєю метою було створити формат XML, який дозволив би додавати нові елементи та атрибути в майбутньому, а порядок тегів не матиме значення, коли це можливо. Якщо ви впевнені, що можете завантажити весь файл у пам'ять, то XPATH - це, мабуть, хороший вибір.

Якщо ви маєте справу з особливо великими файлами, або з інших причин не можете завантажувати файл відразу, тоді, ймовірно, вам залишається використовувати XmlStreamReader і сканувати відомі елементи та повторювати їх у ReadSubtree та сканувати знову ...


Ця відповідь не дуже спрямована на Q, цей сайт не призначений для обговорення, а призначений для неспекулятивних запитань та запитань. У вашій відповіді є деякі вагомі моменти, які можуть бути використані для аргументації причин, чому підхід допитуваного є непоганим, але це не дуже зосереджено. Будь ласка, сфокусуйте свою відповідь на запитання ще трохи, дякую!
Джиммі Хоффа

@JimmyHoffa Хоча моя відповідь також підтримувала питання ОП, я зрозумів, що пропоную напівструктурований підхід XML. Але я розумію, що ви маєте на увазі, я можу відредагувати
Алан,
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.