Domanda

Ho bisogno di essere in grado di memorizzare alcuni dati in un formato di file binario personalizzato. Non ho mai progettato il mio formato di file prima. Ha bisogno di essere un formato adatto per viaggiare tra il C #, Java mondi e Ruby / Perl / Python.

Per iniziare con il file sarà composto da record. Un campo GUID e un / / campo pacchetto XML YAML JSON. Non sono sicuro che cosa da usare come delimitatori. Una virgola, tabulazione o nuova riga genere di cose sembra troppo fragile. Cosa fa Excel fare? oi formati OpenOffice pre-XML? Se si utilizza caratteri ASCII 0 o 1. Non sai da dove cominciare. Eventuali articoli o libri sul tema?

Questo formato di file può espandersi successivamente per includere una "sezione di intestazione".

Nota: Per iniziare con lavorerò in .NET, ma mi piacerebbe il formato per essere facilmente trasportabili

.

UPDATE:
Il trattamento dei "pacchetti" può essere lento, ma la navigazione all'interno del formato di file non può. Quindi penso che XML è fuori dal tavolo.

È stato utile?

Soluzione

cercherò di aggiungere alcuni suggerimenti generali per la creazione di un formato portatile file binario.

Si noti che a inventare un formato di file binario significa per documentare, come i bit in esso devono andare e che cosa significano. Non è la codifica, ma la documentazione.

Ora i suggerimenti:

  1. decidere cosa fare con il endianess . Buono e semplice modo per andare è quello di decidere una volta e per sempre. La scelta sarebbe preferibilmente little endian quando viene utilizzato su PC comune (cioè 86) per salvare le conversioni (performance).

  2. Crea intestazione . Sì, è una buona idea avere sempre un colpo di testa. I primi byte del file dovrebbe essere in grado di dirvi, quale formato si sta scherzi con.

    • Inizia con la magia di essere in grado di riconoscere il formato (stringa ASCII farà il trucco)
    • Aggiungi versione. La versione del formato di file non farà male per aggiungere e vi permetterà di fare la compatibilità a ritroso in seguito.
  3. Infine, aggiungere i dati. Ora, il formato dei dati sarà specifico e sarà sempre in base alle proprie esigenze. Fondamentalmente, i dati vengono memorizzati in un'immagine binaria di qualche struttura dati. La struttura dei dati è ciò che è necessario trovare.

Se avete bisogno di accesso casuale ai dati da una sorta di indici, B-Alberi sono strada da percorrere, mentre se avete solo bisogno di un sacco di numeri di scrivere tutti e poi li legge tutti un "allineamento" farà il trucco.

Inoltre, è possibile utilizzare un TLV (Type-Lunghezza-Valore ) concetto di compatibilità in avanti.

Altri suggerimenti

Che ne dite di guardare con "buffer" di protocollo? Progettato come un formato efficiente, portatile versione tollerante uso generale binario, ti dà C ++, Java e Python nel google biblioteca e C #, Perl, Ruby e altri nella porti comunitari ?

Si noti che Guid non ha un tipo di dati specifici, ma è possibile shim come un messaggio con (essenzialmente) un byte[].

Normalmente per il lavoro NET, io consiglierei di protobuf- net (ma come l'autore, io sono un po 'prevenuto) - tuttavia, se si intende utilizzare altri linguaggi successivamente si potrebbe fare meglio (a lungo termine) con Jon dotnet-protobufs ; che ti do un API familiare attraversato le piattaforme (dove-come protobuf-net usa linguaggi .NET).

ASCII caratteri 0 o 1 ciascuno occupano più bit (come qualsiasi altro carattere), quindi se siete di riporlo in quel modo il file "binario" sarà parecchie volte più grande di quanto dovrebbe essere. Al file di testo di zero e uno non è esattamente un file binario:)

È possibile utilizzare il BinaryWriter di scrivere dati grezzi direttamente ad un stream file . L'unica parte che dovete capire è tradurre il formato in-memory (di solito un qualche tipo di oggetto grafico) in una sequenza di byte che il BinaryWriter può consumare.

Tuttavia , se il vostro interesse primario è la portabilità, vi consiglio contro un formato binario a tutti. XML è stato progettato proprio per risolvere il problema di portabilità e l'interoperabilità. E 'prolisso e pesante come un formato di file, ma questo è il trade-off si fanno per ottenere quei problemi risolti per voi Se un formato leggibile è fuori dal tavolo, Marc risposta è la strada da percorrere. Non c'è bisogno di reinventare la ruota portabilità!

Dipende da che tipo di dati verrà scrittura al file binario e qual è lo scopo del file binario. Sono oggetto classe o solo i dati dei record? Se si tratta di dati del record mi sento di raccomandare a metterlo in formato XML. In questo modo è possibile includere una convalida dello schema per convalidare che il file sia conforme con voi standard. Ci sono strumenti in Java e .NET per importare ed esportare dati da / in formato XML.

Supponiamo che il vostro formato è:

    struct Format
    {
        struct Header // 1
        {
            byte a;
            bool b1, b2, b3, b4, b5, b6, b7, b8;
            string name;
        }
        struct Container // 1...*
        {
            MyTypeEnum Type;
            byte[] data;
        }
    }

    enum MyTypeEnum
    {
        Sound,
        Video,
        Image
    }

Poi avrei un file sequenziale con:


byte // a

byte // b

int // dimensioni nome

char [] // nome (che ha le dimensioni sopra specificato, ricordare un char è di 16 bit in NET)

int tipo // MyTypeEnum

int size // dati

byte [] // dati (che ha le dimensioni sopra specificato)


Quindi è possibile ripetere le ultime tre righe come molti come si desidera.

Per leggere si utilizza il BinaryReader, che ha il supporto per la lettura di byte, interi e serie di byte. V'è anche un BinaryWriter.

Inoltre, ricordate che Microsoft .NET (quindi su una macchina Windows / Intel) è little-endian. Così è la BinaryReader e BinaryWriter.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top