Considerazioni sulla progettazione di un tipo di file

8

Sto per iniziare a scrivere un processo per salvare alcune strutture dati dal codice in un file di un tipo proprietario, non ancora definito. Tuttavia, non ho mai progettato un tipo o struttura di file prima.

  • Ci sono delle cose, in generale, che dovrei prendere in considerazione prima di iniziare la mia progettazione?
  • Ci sono buone pratiche accettate qui? Cattive pratiche che dovrei evitare?
  • Qualche cosa di assoluto da fare e cosa non fare?
posta Andy Hunt 24.10.2012 - 15:56
fonte

4 risposte

20

Per prima cosa, prova a trovare un formato abbastanza vicino a quello che stai per costruire. In generale, è meglio usare il formato di qualcuno che inventare il tuo, anche se il formato sembra essere leggermente più complesso di quello che ti serve 1 .

Se non riesci a trovare un formato ready-made adatto, verifica se è possibile crearne uno in aggiunta a un formato generico esistente, ad esempio XML o XML binario . Questo dovrebbe essere possibile in quasi tutti i casi in cui stai per iniziare un nuovo formato di file. L'XML basato su testo occupa più spazio, ma offre agli utenti una certa misura di leggibilità. Tuttavia, se ti trovi a utilizzare la codifica Base-64 all'interno di un file XML, è una chiara indicazione che dovresti usare una codifica binaria.

Per quanto riguarda le buone e cattive pratiche, assicurati di non "inserire" la funzionalità hardware della tua piattaforma di destinazione iniziale nella progettazione del tuo formato di file. In particolare, assicurati che i tuoi numeri siano memorizzati in un formato che possa essere letto correttamente su piattaforme con endianness diverso da quello dello scrittore e che le stringhe rivolte all'utente siano archiviate in UNICODE.

Un'altra buona pratica è includere un'intestazione da cui è possibile determinare il tipo di file nel caso in cui la sua estensione sia mancante o errata. È una buona idea includere una versione del tuo formato di file nell'intestazione. Ciò ti consente di modificare il formato in un secondo momento e di rimanere compatibile con le versioni precedenti.

Se possibile, non rendere il tuo formato dipendente dalle specifiche del meccanismo di serializzazione predefinito incorporato nella tua piattaforma. Ad esempio, gli oggetti Java con serializzazione binaria non formano un buon formato di file 2 .

Infine, decidi se i tuoi file devono essere trasmissibili . Ciò introduce una complessità aggiuntiva, in quanto si dovrebbe essere in grado di interpretare singoli "frame" del file in isolamento. Nei casi in cui è necessario lo streaming, tuttavia, si dovrebbe quasi sempre essere in grado di individuare un formato file adatto che esiste già.

1 D'altro canto, dovresti evitare formati che richiedono sforzi straordinari per supportare la complessità richiesta dall'applicazione.

2 Ciò non significa, tuttavia, che non si debba tentare di integrare in modo personalizzato la lettura e la scrittura del nuovo formato con lo schema di serializzazione della propria piattaforma, solo che non si deve fare affidamento sul meccanismi di serializzazione predefiniti.

    
risposta data 24.10.2012 - 16:29
fonte
12

La prima cosa che dovresti considerare è se hai effettivamente bisogno di un nuovo formato o se puoi ottenere usando un formato già esistente. Prendi in considerazione l'utilizzo di SQLite; se riesci ad adattare le tue esigenze al modello RDBMS, questo potrebbe farti risparmiare molti mal di testa. Inoltre, considera l'utilizzo di XML o JSON, questo ti eviterà di dover scrivere il tuo parser.

Se devi creare il tuo formato, la prima considerazione è se vuoi un formato di testo o un formato binario. Ci sono vantaggi per entrambi. Un formato di testo è un grande vantaggio per la portabilità e ha il vantaggio di essere più semplice da leggere o modificare per un essere umano. Un formato binario potrebbe essere più efficiente, ma ha molti problemi di portabilità che ne derivano. Non essere tentato di leggere i byte direttamente nelle variabili, te ne pentirai se devi portare il codice su un'altra piattaforma.

    
risposta data 24.10.2012 - 16:30
fonte
1

La prima e più importante decisione è se utilizzare un formato binario o uno basato su testo. Il binario è la strada da percorrere quando devi scaricare grandi quantità su dati non stringa. Ma ha degli svantaggi significativi:

  • I dati binari non sono leggibili dall'uomo. Di conseguenza, rende più difficile il debug e / o il tweaking dei dati già presenti su disco. Questo è uno dei motivi per cui la filosofia UNIX abbraccia così strongmente i file basati su testo.

  • I formati binari non si prestano all'espansione futura. Mentre ciò può essere fatto, i punti per l'espandibilità devono essere incorporati nel formato fin dall'inizio. In genere, questi sono

    1. un numero / stringa magico che identifica il formato

    2. un numero di versione del formato

    3. campi riservati in posizioni strategiche, che devono essere inizializzati a zero

    I primi due appaiono in genere all'inizio del file, mentre i campi riservati sono solitamente sparsi sul file.

Ora, se segui il percorso basato sul testo, ecco alcune cose a cui pensare:

  • Qualsiasi formato di testo definisce un nuovo mini-linguaggio. Conoscilo e usalo a tuo vantaggio.

  • Cerca di mantenere le regole del tuo mini-linguaggio il più semplice possibile. Non c'è posto dove il principio KISS sia più importante di quando si progetta un formato di file basato su testo.

  • Cerca di rendere i tuoi file autoesplicativi.

  • Non imporre restrizioni inutili, ad esempio dove possono apparire spazi bianchi e quanto di.

  • Dai un'occhiata a una serie di formati di file differenti sviluppati per UNIX. Questo può darti alcune buone idee.

  • Se possibile usa o adatta / espandi / costruisci un formato di file esistente. Il formato json è un buon punto di partenza abbastanza leggibile. (Almeno molto meglio di XML, che è un dolore da leggere per gli umani.)

  • Se la dimensione del file è un problema, potresti prendere in considerazione l'idea di utilizzare un formato basato sul testo, ma passarlo attraverso uno dei compressori standard come gzip o lzma . I compressori standard amano l'input in questo modo.

Se segui il percorso binario, ecco alcune cose a cui prestare attenzione:

  • Dovresti avere un'intestazione con un numero / stringa magico e un numero di versione. Di solito questo va all'inizio del file, ma può anche andare alla fine del file. Alcuni file potrebbero anche avere due diverse intestazioni davanti e dietro, dando due viste indipendenti sui dati all'interno.

  • Dovresti avere un indice e dovresti cercare di mantenere le sue parti vicine tra loro. Ciò consente al lettore di scoprire rapidamente cosa c'è dentro il file, senza dover eseguire la scansione dell'intera cosa. Se non lo fai, potresti finire a leggere tutto due volte.

  • Se si dispone di bit del file che sono accessibili solo come sequenza anziché tramite una struttura di indice, includere almeno un campo lunghezza per ogni record nella sequenza. O un indice o campi di lunghezza di questo tipo sono requisiti per i lettori che non comprendono tutti i dettagli del formato e devono saltare parti di esso come caselle nere. (Grazie a Jules per questo.)

  • Ogni oggetto dati all'interno del file deve contenere almeno un campo riservato per l'espansione futura. Questo non ha bisogno di essere grande, ma deve essere lì. Perché, in caso contrario, non esiste un luogo in cui sia possibile riconoscere le funzionalità future.

  • È necessario tenere in considerazione l'endianess. In genere ciò significa che decidi una volta se i tuoi file debbano essere codificati in big endian o little endian byte order e attenersi a tale decisione: gestire endianess come questa è una seccatura, ma non è neanche lontanamente così male come dover tenere conto di due diverse versioni di endianess nel file.

  • Sii generoso nelle larghezze dei campi che fornisci. Soprattutto, quando hai bisogno di codificare gli offset all'interno del file, usa sempre 64 bit. Molti mal di testa sono stati causati da progettisti di formati di file che erano troppo conservativi con la quantità di bit che hanno allocato.

risposta data 03.03.2016 - 22:59
fonte
0

Dipende davvero da cosa stai facendo. Dovrebbe essere il più semplice possibile e non più semplice. Vedo un sacco di altre persone che spingono XML. Sconsiglio vivamente l'uso di XML. XML è un pasticcio sovrascritto. La prima domanda sarebbe se le tue strutture di dati fossero filiali. Significato sono liste di liste o elenchi di mappe o simili? Se no, allora una semplice sequenza di record di testo potrebbe essere buona. CSV forse.

Se hai bisogno di prestazioni o accesso casuale, il binario è buono. Definire una sequenza di record in cui ogni record contiene una sequenza di riferimenti che hanno una dimensione specifica come un intero little endian di 4 byte per un numero o un intero di 2 byte che specifica il numero di byte per una stringa UTF-8. Ogni record inizia con un numero intero che specifica la dimensione del record in modo che l'intero file possa essere scansionato senza effettivamente leggere il contenuto dei record. Ciò consente anche di codificare i record in-situ (ovvero è possibile decomprimere il file, codificare il record e quindi aggiornare la dimensione in modo da ridurre al minimo la copia non necessaria). Questo è il genere di cose che non puoi fare con XML.

    
risposta data 04.03.2016 - 03:51
fonte

Leggi altre domande sui tag