Qual é o melhor método para ler uma dupla de um arquivo binário criado em C?
Pergunta
Um programa C cospe duplos consecutivos em um arquivo binário. Eu gostaria de lê-los em Python. Eu tentei usar struct.unpack('d',f.read(8))
EDIT: Eu usei o seguinte em C para escrever um número double aleatória
r = drand48();
fwrite((void*)&r, sizeof(double), 1, data);
Os erros são fixos, mas eu não consigo ler o primeiro valor. para um todo 0.000 .. Número lê-lo como 3,90798504668055 mas o resto está bem.
Solução
Eu acho que você está realmente lendo o número corretamente, mas estão a ficar confuso com a exibição. Quando leio o número do seu arquivo fornecido, eu recebo "3.907985046680551e-14
" - isso é quase, mas não completamente zero (,000000000000039 em forma expandida). Eu suspeito que o seu código C é apenas imprimi-lo com menos precisão do que python é.
[Edit] Eu apenas tentei ler o arquivo em C, e eu obter o mesmo resultado (embora um pouco menos de precisão: 3.90799e-14) (usando printf ( "% g", val)), então eu acho Se esse valor estiver incorreto, isso aconteceu no lado da escrita, ao invés da leitura.
Outras dicas
Você poderia por favor elaborar sobre "não funcionou"? Será que o acidente de comando? Será que os dados saem errado? O que realmente aconteceu?
Se o comando caiu:
- Por favor, compartilhe a saída de erro do comando
Se os dados simplesmente saiu errado:
-
Será que os sistemas que criar e ler os dados têm a mesma ordenação? Se um é big-endian, eo outro é little-endian, então você precisa especificar uma conversão endianness em sua cadeia de formato.
-
Se a ordenação dos dois computadores são os mesmos, como foi os dados gravados no arquivo, exatamente ? Você sabe? Se o fizer, então o que era o valor escrito para o arquivo e qual foi o valor incorreto você saiu?
Em primeiro lugar, você já tentou picles ? Ninguém mostrou qualquer código Python ainda ... Aqui está um código para a leitura em binário em python:
import Numeric as N
import array
filename = "tmp.bin"
file = open(filename, mode='rb')
binvalues = array.array('f')
binvalues.read(file, num_lon * num_lat)
data = N.array(binvalues, typecode=N.Float)
file.close()
Quando o f aqui especificado de precisão simples, de 4 bytes flutuante, números. Encontrar o tamanho de seus dados é por entrada e uso isso.
Para dados não binários que você poderia fazer algo simples como isto:
tmp=[]
for line in open("data.dat"):
tmp.append(float(line))
-
f.read(8)
pode retornar menos de 8 bytes -
Os dados podem ter diferentes alinhamento e / ou endianness:
>>> for c in '@=<>': ... print repr(struct.pack(c+'d', -1.05)) ... '\xcd\xcc\xcc\xcc\xcc\xcc\xf0\xbf' '\xcd\xcc\xcc\xcc\xcc\xcc\xf0\xbf' '\xcd\xcc\xcc\xcc\xcc\xcc\xf0\xbf' '\xbf\xf0\xcc\xcc\xcc\xcc\xcc\xcd' >>> struct.unpack('<d', '\xbf\xf0\xcc\xcc\xcc\xcc\xcc\xcd') (-6.0659880001157799e+066,) >>> struct.unpack('>d', '\xbf\xf0\xcc\xcc\xcc\xcc\xcc\xcd') (-1.05,)
O melhor método seria a utilização de um arquivo de texto ASCII:
0.0
3,1416
3,90798504668055
em que seria portátil e trabalhar com qualquer tipo de flutuar implementação apontam para um grau.
Leitura de dados binários brutos de endereço de memória de uma double
não é portátil em tudo, e é obrigado a falhar em alguns implementação diferente.
Você pode usar de curso de um formato binário para compacidade, mas uma função C escrita portátil nesse formato não seria parecido com o trecho em tudo.
No mínimo, o código deve ser cercada por uma série de ifs / IFDEFs verificando que a representação da memória de double
s usados ??pela máquina atual corresponde exatamente o esperado pelo interpretador Python.
Escrevendo esse código seria difícil, que é por isso que eu estou sugerindo que a solução fácil, limpo, portátil e legível do texto ASCII.
Este seria minha definição de "melhor".