Estou criando um formato de arquivo proprietário para um aplicativo que escrevi em C # .NET para armazenar informações salvas e, talvez, os ativos do projeto na linha. Existe um padrão sobre como fazer isso de alguma maneira? Eu estava simplesmente indo para Serialize
meus objetos em binário e criando um cabeçalho que me diria como analisar o arquivo. Esta é uma abordagem ruim?
c#
.net
file-structure
corylulu
fonte
fonte
BinaryFormatter
.Respostas:
O método mais direto é provavelmente serializar sua estrutura para XML usando a
XMLSerializer
classe Você provavelmente não precisaria criar um cabeçalho e uma estrutura de corpo separados - mas serialize todos os ativos em XML. Isso permite que você inspecione / edite facilmente sua estrutura de arquivos fora do seu próprio programa, e é facilmente gerenciável.No entanto, se sua estrutura de arquivos for realmente complexa, contendo muitos ativos diferentes de tipos diferentes, como serializar toda a estrutura para XML é muito onerosa, você pode serializar cada ativo separadamente e compilá-los em um único pacote usando a
Packaging
biblioteca em C # . É basicamente assim que são construídos os formatos .docx, .xslx, .pptx e outros arquivos de escritório.fonte
protobuf-net
para serializar meus dados e isso funciona muito bem. Mas tenho que serializar peças separadamente, para que você esteja falando com a biblioteca de empacotamento parece o que eu preciso.De alguém que teve que analisar muitos formatos de arquivo, tenho opiniões sobre isso de um ponto de vista diferente para a maioria.
Torne o número mágico muito exclusivo, para que os detectores de formato de arquivo de outras pessoas não o identifiquem como o seu. Se você usar binário, aloque 8 ou 16 bytes gerados aleatoriamente no início de um formato binário para o número mágico. Se você usa XML, aloque um espaço para nome adequado no seu domínio para que ele não possa entrar em conflito com outras pessoas. Se você usa JSON, Deus o ajude. Talvez alguém tenha resolvido uma solução para essa abominação de um formato até agora.
Planeje a compatibilidade com versões anteriores. Armazene o número da versão do formato de alguma forma, para que versões posteriores do seu software possam lidar com diferenças.
Se o arquivo puder ser grande ou houver seções que as pessoas possam ignorar por algum motivo, verifique se há uma boa maneira de fazer isso. XML, JSON e a maioria dos outros formatos de texto são particularmente terríveis para isso, porque forçam o leitor a analisar todos os dados entre o elemento inicial e final, mesmo que não se importem com isso. A EBML é um pouco melhor porque armazena o comprimento dos elementos, permitindo que você pule todo o caminho até o fim. Se você criar um formato binário personalizado, existe um design bastante comum em que você armazena um identificador de pedaço e um comprimento como a primeira coisa no cabeçalho e, em seguida, o leitor pode pular o pedaço inteiro.
Armazene todas as seqüências de caracteres em UTF-8.
Se você se preocupa com a extensibilidade a longo prazo, armazene todos os números inteiros em um formato de tamanho variável.
As somas de verificação são boas porque permitem que o leitor aborte imediatamente dados inválidos, em vez de entrar em seções do arquivo que possam produzir resultados confusos.
fonte
Bem, há momentos em que você descreve pode ser uma abordagem muito ruim. Isso pressupõe que, quando você diz 'serializar', está falando sobre o uso da capacidade de uma linguagem / estrutura para simplesmente pegar um objeto e enviar diretamente para algum tipo de fluxo binário. O problema é que as estruturas de classes mudam ao longo dos anos. Você poderá recarregar um arquivo criado em uma versão anterior do seu aplicativo se todas as suas classes mudarem para uma mais nova?
Para estabilidade a longo prazo de um formato de arquivo, achei melhor arregaçar as mangas agora e escrever especificamente seus próprios métodos de 'serialização' / 'streaming' dentro de suas classes. ou seja, manipule manualmente a gravação de valores em um fluxo. Escreva um cabeçalho como você descreve, descrevendo a versão do formato e, em seguida, os dados que você deseja salvar na ordem em que deseja. No lado da leitura, manipular versões diferentes do formato do arquivo fica muito mais fácil.
A outra opção, é claro, é XML ou JSON. Não necessariamente o melhor para conteúdo pesado binário, mas simples e legível por humanos ... uma grande vantagem para a viabilidade a longo prazo.
fonte
Eu também adoraria ouvir respostas a esta pergunta de pessoas com anos de experiência mais do que eu.
Eu pessoalmente implementei vários formatos de arquivo para o meu trabalho e passei a usar um formato de arquivo XML. Meus requisitos e hardware com os quais interajo mudam o tempo todo e não há como dizer o que precisarei adicionar ao formato no futuro. Uma das principais vantagens do XML é que ele é semiestruturado . Por esse motivo, geralmente evito a serialização XML automática que o .NET fornece porque acredito que obriga a esperar um formato exato.
Meu objetivo era criar um formato XML que permitisse adicionar novos elementos e atributos no futuro e que a ordem das tags não importasse sempre que possível. Se você tem certeza de que pode carregar todo o arquivo na memória, o XPATH é provavelmente uma boa escolha.
Se você estiver lidando com arquivos particularmente grandes ou por outros motivos não puder carregar o arquivo de uma só vez, provavelmente ficará com o uso de um XmlStreamReader e a varredura de elementos conhecidos e a recursão nesses elementos com o ReadSubtree e a varredura novamente ...
fonte