Estou trabalhando com um problema em Programming Pearls - especificamente, a implementação de um programa que classifica um arquivo que contém, no máximo, 10.000.000 de números inteiros (coluna 1, problema 3). Como o livro não especifica como os dados devem ser armazenados no arquivo, estou pensando em armazenar os números inteiros como bytes brutos (existem outras restrições que tornam os bytes brutos uma boa opção). Eu nunca trabalhei nesse nível mais baixo antes, então quero saber se há algo perigoso que eu deva prestar atenção. Preciso me preocupar em usar acidentalmente algum tipo de sequência de fim de arquivo ao gravar bytes brutos em um arquivo, por exemplo?
Editar:
Agora percebo o quão ampla minha pergunta foi. Eu realmente quis dizer problemas do tipo mais catastrófico, como substituir acidentalmente outros arquivos no disco. Desculpe, eu não estava mais claro originalmente.
Respostas:
O único perigo em que você se depara é pouca ou grande resistência (se o byte mais ou menos significativo é escrito primeiro). No entanto, se você permanecer no mesmo ambiente, não haverá problema. além da garantia geral de escrever / analisar ida e volta.
O sistema de arquivos foi projetado para lidar com qualquer sequência de bytes.
fonte
Não, na verdade é assim que muitos formatos de arquivo funcionam. Exemplos comuns de arquivos binários como este incluem imagens e arquivos de música / áudio.
Para manter a integridade do arquivo e os dados lidos, certifique-se de seguir estas diretrizes:
Os detalhes específicos variarão com base na estrutura, plataforma e idioma, mas isso deve cobrir as "dicas" básicas do arquivo de E / S.
fonte
int
pode estar em qualquer lugar entre 2 e 8 ou mais bytes (octetos, na verdade).int
em duas máquinas diferentes possam ser considerados tipos de dados diferentes.Além de todas as dicas já mencionadas, se você estiver criando um novo formato de arquivo binário em vez de ler e gravar dados em um formato existente, é absolutamente vital que você inclua um cabeçalho de arquivo : um bloco de dados no início do arquivo que identifica inequivocamente o formato do arquivo e registra todos os metadados necessários.
Bons cabeçalhos de arquivo incluem pelo menos três coisas:
Um " número mágico ", de pelo menos quatro bytes. O número mágico DEVE rfc2119 ser os primeiros N bytes no arquivo, nunca deve ter sido usado para qualquer outro formato de arquivo que você possa desenterrar e DEVE conter pelo menos um byte que não seja um caractere ASCII imprimível. Veja a especificação PNG para saber como criar um número mágico realmente completo . Veja o código-fonte do
file(1)
comando para obter um banco de dados de números mágicos existentes, tão abrangente quanto você provavelmente encontrará.O objetivo de um número mágico é rotular inequivocamente o arquivo, dentro da banda, com seu formato. Se você não incluir um número mágico ou não for a primeira coisa no arquivo, você corre o risco de os programas identificarem incorretamente seu arquivo como algum outro tipo de arquivo, o que leva à perda de dados, à fuga de vírus e à detecção de outros. catástrofes.
Uma indicação da versão do formato do arquivo. Mesmo que você ache que nunca precisará revisar drasticamente o formato do arquivo, crie os próximos dois bytes após o número mágico
00 00
e documente que esse é um número de versão de 16 bits com alguma definição definitiva (o que você quiser, mas escolha um e cole-o ao longo do arquivo ) e será incrementado se o significado dos dados subsequentes mudar radicalmente. Seu futuro eu agradecerá.(A especificação PNG segue uma rota diferente aqui, especificando que os formatos de bloco são congelados e que todas as alterações futuras no formato terão a forma de novos tipos de bloco. Isso também é válido, mas eu recomendo a abordagem simples de número mágico + número de versão para iniciantes no processamento de dados binários. As pessoas que criaram o PNG usavam décadas de experiência coletiva com formatos de imagem.)
Algum tipo de mecanismo para incorporar metadados arbitrários no arquivo. Isso pode ser tão simples quanto fazer com que os próximos dois bytes sejam um deslocamento de 16 bits do final do cabeçalho até o início dos dados reais, com tudo entre os dois a ser interpretado como pares de valores-chave UTF-8 na RFC 822 (ou seja, "
Tag: value\n
" - se você seguir esse caminho, recomendo não permitir dobrar linhas longas). Mais uma vez, PNG é consideravelmente mais inteligente.fonte
Arquiteturas diferentes têm representações diferentes para números inteiros. O principal risco aqui é salvar a representação de bytes de um número inteiro na máquina A e, em seguida, tentar lê-lo e interpretar o conteúdo como números inteiros na máquina B. Se as máquinas A e B tiverem tamanhos diferentes para números inteiros e / ou endianidade diferente , você ' Muito provavelmente, causará um comportamento indefinido (por exemplo, em C) ou uma exceção.
Como este é apenas um exemplo de programação e não um programa "real", não é realmente um problema. Se esse fosse um programa real, rolar o seu próprio formato binário específico do aplicativo geralmente não é uma boa ideia; existem soluções melhores, como SQLite ou formatos de serialização baseados em string, como JSON, YAML, XML, etc. Para valores únicos, transformá-lo em uma string seria suficiente; para listas simples, você pode salvar uma string por linha e simplesmente dividir a entrada em novas linhas quando a ler novamente.
fonte