Esiste un modo corretto per creare un formato di file?


12

Sto creando un formato di file proprietario per un'applicazione che ho scritto in C # .NET per archiviare informazioni di salvataggio e forse risorse del progetto. Esiste uno standard su come farlo in qualche modo? Stavo semplicemente andando ai Serializemiei oggetti in binario e creavo un'intestazione che mi avrebbe spiegato come analizzare il file. È un cattivo approccio?


2
Vorrei evitare BinaryFormatter.
CodesInChaos,

3
Qualunque sia l'approccio (dalle risposte) che scegli, includi sempre un numero di versione nel formato! La tua domanda suggerisce già che potrebbe cambiare e il numero di versione ti farà risparmiare molto sforzo se devi essere compatibile con backwarsd.
Jan Doggen,

Non dimenticare di documentare correttamente il formato
Basile Starynkevitch il

Risposte:


11

Il metodo più diretto è probabilmente serializzare la struttura in XML usando la XMLSerializerclasse. Probabilmente non è necessario creare un'intestazione e una struttura del corpo separate, ma serializzare tutte le risorse in XML. Ciò consente di ispezionare / modificare facilmente la struttura dei file al di fuori del proprio programma ed è facilmente gestibile.

Tuttavia, se la struttura dei file è davvero complessa, contenente molte risorse diverse di tipi diversi, in modo tale che la serializzazione dell'intera struttura in XML sia troppo onerosa, è possibile esaminare la serializzazione di ciascuna risorsa separatamente e la loro compilazione in un singolo pacchetto utilizzando la Packaginglibreria in C # . Questo è essenzialmente il modo in cui sono costruiti .docx, .xslx, .pptx e altri formati di file di Office.


Sì, il mio progetto è molto più complesso di quello, ma sto anche cercando di renderlo meno leggibile dall'utente poiché potremmo distribuirli in un campo in un contesto concesso in licenza. Attualmente sto usando protobuf-netper serializzare i miei dati e funziona molto bene. Ma devo serializzare i pezzi separatamente, quindi quello di cui stai parlando con la libreria Packaging sembra quello di cui ho bisogno.
Corylulu,

7
Caro dio non XML
James,

2
@James yeah XML ha i suoi lati negativi, ovviamente. Prediligo il packaging e XML nella maggior parte dei casi per gli stessi motivi: 1. è un framework preesistente, quindi richiede uno sforzo minimo. 2. È facile da supportare per altri sistemi, poiché è uno standard ampiamente accettato. 3. È facile per un essere umano ispezionare il file risultante per verificare il processo di serializzazione.
pswg,

XML ha dei vantaggi, ma è a causa di quei vantaggi che non mi piace usare il serializzatore XML. Credo che richieda che l'XML sia in un formato specifico. XML è un formato semi-strutturato, che consente al mio formato di file di cambiare nel tempo e di essere comunque compatibile con le versioni precedenti. In passato, ho scritto il mio proprio analisi XML facendo attenzione a non fare ipotesi sull'ordinamento o non essendoci tag di cui non sono a conoscenza in futuro. Se riesci a caricare l'intero file XML, XPATH probabilmente funzionerebbe abbastanza bene. Altrimenti la tua sinistra con qualche analisi del flusso più complicata
Alan

Suggerirei di esaminare JSON
Basile Starynkevitch il

7

Da qualcuno che ha dovuto analizzare molti formati di file, ho opinioni su questo da un punto di vista diverso rispetto alla maggior parte.

  • Rendi il numero magico univoco in modo che i rilevatori di formato di file delle persone per altri formati non lo identificino erroneamente come tuo. Se usi il binario, alloca 8 o 16 byte generati casualmente all'inizio di un formato binario per il numero magico. Se usi XML, alloca uno spazio dei nomi appropriato nel tuo dominio in modo che non possa scontrarsi con altre persone. Se usi JSON, dio ti aiuti. Forse qualcuno ha risolto una soluzione per quell'abominio di un formato ormai.

  • Pianificare la compatibilità con le versioni precedenti. Memorizza il numero di versione del formato in qualche modo in modo che le versioni successive del tuo software possano gestire le differenze.

  • Se il file può essere di grandi dimensioni o se ci sono sezioni che le persone potrebbero voler saltare per qualche motivo, assicurati che ci sia un buon modo per farlo. XML, JSON e la maggior parte degli altri formati di testo sono particolarmente terribili per questo, perché costringono il lettore a analizzare tutti i dati tra l'elemento iniziale e quello finale anche se non gli interessano. EBML è in qualche modo migliore perché memorizza la lunghezza degli elementi, permettendoti di saltare fino alla fine. Se si crea un formato binario personalizzato, esiste un design abbastanza comune in cui si memorizza un identificatore di blocco e una lunghezza come prima cosa nell'intestazione, quindi il lettore può saltare l'intero blocco.

  • Memorizza tutte le stringhe in UTF-8.

  • Se ti interessa l'estensione a lungo termine, archivia tutti i numeri interi in un formato a lunghezza variabile.

  • I checksum sono utili perché consentono al lettore di interrompere immediatamente i dati non validi, anziché potenzialmente passare a sezioni del file che potrebbero produrre risultati confusi.


+1 per avermi fatto capire che non sono l'unica persona che pensa che Json sia un abominio di un formato.
RubberDuck,

Perché l'odio per Json? Inserisci una stringa nota in una posizione nota per identificare il formato. Problema risolto.
Esben Skov Pedersen,

Non è perfetto, ma funziona perfettamente con JavaScript, più veloce da analizzare rispetto a XML e dimensioni inferiori, e comunque leggibile dall'uomo.
Corylulu,

1
"Perché l'odio per JSON?" Nessun supporto per i commenti leggibili dall'uomo, la fuga di merda di Unicode e una strana sintassi che mi richiede di citare le chiavi anche se non contengono mai spazi bianchi. Inoltre la solita incapacità di estendere le cose perché nessuno pensava allo spazio dei nomi ... quando lo risolvi, finisci con qualcosa che sembra anche peggio di XML in primo luogo, tutto per quello, il vantaggio di evitare qualche angolo parentesi?
Trejkaz,

Sì, ma come per tutte le cose con la programmazione, usa lo strumento giusto per il lavoro. Esistono applicazioni in cui XML è migliore di JSON e viceversa.
corylulu,

4

Bene, ci sono volte che ciò che descrivi può essere un pessimo approccio. Questo presuppone che quando si dice "serializza" si sta parlando dell'abilità di un linguaggio / framework di prendere semplicemente un oggetto e inviarlo direttamente a una sorta di flusso binario. Il problema è che le strutture di classe cambiano nel corso degli anni. Sarai in grado di ricaricare un file creato in una versione precedente dell'app se tutte le tue classi cambiano in una nuova?

Per la stabilità a lungo termine di un formato di file, ho trovato meglio rimboccarmi le maniche un po 'ora e in particolare scrivere i tuoi metodi di "serializzazione" / "streaming" all'interno delle tue classi. vale a dire, gestire manualmente la scrittura di valori in un flusso. Scrivi un'intestazione mentre dichiari che descrive la versione del formato, quindi i dati che desideri vengano salvati nell'ordine in cui li desideri. Sul lato di lettura, gestire diverse versioni del formato del file diventa molto più semplice.

L'altra opzione ovviamente è XML o JSON. Non necessariamente il massimo per i contenuti binari pesanti, ma semplice e leggibile dall'uomo ... un grande vantaggio per la fattibilità a lungo termine.


Sto serializzando usando protobuf-net ( code.google.com/p/protobuf-net ) che è estensibile. Ma i tuoi punti sono validi, tuttavia, non penso che il loro sia un metodo di formato file immune da questo.
Corylulu,

Sì ... ecco perché a volte dico che devi solo sporcarti le mani e gestire l'ordine in cui i dati vengono scritti e caricati manualmente.
GrandmasterB,

L'applicazione che sto costruendo è molto dinamica e ha troppi valori per qualcosa del genere.
Corylulu,

1
Più complicata è l'applicazione, più è importante avere un controllo molto preciso sul formato del file. Tieni presente che non sto dicendo che ogni classe non dovrebbe avere un proprio output streaming ... solo che dovresti controllarlo per ogni classe. Quindi chiama quelle routine.
GrandmasterB,

Sì, ho messo in atto metodi che aggiornano le versioni legacy alle versioni moderne e ho un layout molto chiaro di come sono strutturate le mie lezioni. Non sono eccessivamente preoccupato per questo, ma sono d'accordo che sia importante. Ci lavoro da quasi un anno, quindi ho una visione abbastanza chiara di come funziona la sua struttura.
Corylulu,

1

Vorrei anche piacerebbe sentire le risposte a questa domanda da parte di persone con gli anni più esperienza di me stesso.

Ho implementato personalmente diversi formati di file per il mio lavoro e sono passato all'utilizzo di un formato di file XML. I miei requisiti e hardware con cui interagisco cambiano continuamente, e non si può dire cosa dovrò aggiungere al formato in futuro. Uno dei principali vantaggi di XML è che è semi-strutturato . Per questo motivo, in genere evito la serializzazione XML automatica fornita da .NET perché credo che lo costringa ad aspettarsi un formato esatto.

Il mio obiettivo era quello di creare un formato XML che consentisse di aggiungere nuovi elementi e attributi in futuro e che l'ordine dei tag non importasse quando possibile. Se sei sicuro di poter caricare l'intero file in memoria, XPATH è probabilmente una buona scelta.

Se hai a che fare con file particolarmente grandi, o per altri motivi non puoi caricare il file tutto in una volta, allora probabilmente ti rimane con l'uso di un XmlStreamReader e la scansione di elementi noti e la ricorrenza in quegli elementi con ReadSubtree e la scansione di nuovo ...


Questa risposta non è molto diretta al Q, questo sito non è pensato per essere un forum di discussione, ma piuttosto è destinato a domande e risposte non speculative. Hai alcuni punti validi nella tua risposta che potrebbero essere usati per sostenere un suggerimento sul perché l'approccio dell'interrogatore è o non è buono, ma non è molto focalizzato. Per favore, focalizza la tua risposta sulla domanda un po 'di più, grazie!
Jimmy Hoffa,

@JimmyHoffa Anche se la mia risposta supportava anche la domanda del PO, ho chiarito che stavo suggerendo un approccio semi-strutturato XML .. ma capisco cosa intendi, potrei modificare
Alan
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.