2013-06-27 1 views
0

파일에 바이너리 데이터 (ints, double, raw bytes)를 쓰는 응용 프로그램에서 작업하고 있습니다. 그냥 잘 작동 것처럼파이썬은 디스크에 쓰여진 struct.pack 문자열을 mangles합니다.

>>> import struct 
>>> import io 
>>> out = io.open("123.bin", "wb+") 
>>> format = "!i" 
>>> data = struct.pack(format, 1) 
>>> out.write(data) 
4L 
>>> data 
'\x00\x00\x00\x01' 
>>> out.close() 
>>> infile = io.open("123.bin", "rb") 
>>> instr = infile.read() 
>>> instr 
'\x00\x00\x00\x01' 
>>> struct.unpack("!I", instr) 
(1,) 

그래서 모든 것이 같습니다

문제는 데이터가 실제로 파일에 나는 그것이 될 것으로 기대 방법을 작성되지 않는다는 것이다. 그러나 자세히 살펴보면시에, 123.bin 파일 내용을 다음 있습니다 : 바이트가 io.write()로 바꾼 것처럼

$ hexdump 123.bin 
0000000 0000 0100        
0000004 

그래서이 보인다!

>>> type(struct.pack(format, 1)) 
<type 'str'> 

그럼, 내가 잘못하고 있어요 : io.write()struct.packstr를 반환 않습니다, 문제가, "주어진 바이트 된 ByteArray 객체를"받아들이는

파이썬 문서 말한다? 문자셋 변환없이 strbytes으로 변환하려면 어떻게해야하나요?

답변

4

이 모양은 이상한 표현 인 hexdump(1)입니다. xxd(1)을 사용하면 ...

$ xxd 123.bin 
0000000: 0000 0001        .... 

... 올바르게 보입니다.

당신이 제정신 형식으로 출력 hexdump(1)를 얻기 위해 -C 옵션을 사용해야처럼 ...

$ hexdump -C 123.bin 
00000000 00 00 00 01          |....| 
00000004 

같은데 ... 나 대신 hd로 호출합니다.

+0

'hexdump -C'는'00000000 00 00 00 01 | .... |'을 반환합니다. 그래서'hexdump'의 기본 모드가 "broken"인 것처럼 보입니다. –

1

여기의 문제는 파이썬에서는 아니지만 hexdump와 함께 있습니다. 파일의 데이터를 16 비트 리틀 엔디안 값으로 취급합니다. 당신이해야 할 일은 8 비트 값으로 데이터를 처리하도록 hexdump에게 알려주는 것입니다. 그것을 보지 않고서는 '-c'옵션이라고 생각합니다.

1

hexdump의 기본 출력 형식은 그 사람이 페이지에 따르면,의 -x 옵션을 사용하는 것과 동일합니다 : 아키텍처 엔디안

-x  Two-byte hexadecimal display. Display the input offset in hexadecimal, 
     followed by eight, space separated, four column, zero-filled, two-byte 
     quantities of input data, in hexadecimal, per line. 

그리고 hexdump에서 사용 엔디안한다 (여기 가능성이 little- 엔디안), 파이썬에 네트워크 순위 (빅 엔디안)로 값을 저장하도록 요청하는 동안.

따라서 값은 정확하게 저장되지만 hexdump으로 잘못 해석됩니다. hexdump 대신 -C 옵션이나 xxd을 사용할 수 있습니다.

$ hexdump 123.bin 
0000000 0000 0100        
0000004 
$ hexdump -C 123.bin 
00000000 00 00 00 01          |....| 
00000004