파이썬 바이너리 파일에 쓰는 방법?


128

정수로 바이트 목록이 있습니다.

[120, 3, 255, 0, 100]

이 목록을 바이너리로 파일에 어떻게 쓸 수 있습니까?

작동할까요?

newFileBytes = [123, 3, 255, 0, 100]
# make file
newFile = open("filename.txt", "wb")
# write to file
newFile.write(newFileBytes)

60
"이게 작동할까요?"라고 묻는다. 시도해 보셨습니까?
StephenTG 2013-08-21

1
이어야 TypeError: argument 1 must be string or buffer, not list합니다.
anatoly techtonik

답변:


128

이 정확히 무엇을 bytearray위한 것입니다 :

newFileByteArray = bytearray(newFileBytes)
newFile.write(newFileByteArray)

Python 3.x를 사용 bytes하는 경우 대신 사용할 수 있습니다 (의도를 더 잘 알릴 수 있으므로 그래야합니다). 그러나 파이썬 2.x에서, 즉하지 않습니다 작품은, 때문에이 bytes단지의 별칭입니다 str. 평소와 같이 인터랙티브 인터프리터로 보여주는 것이 텍스트로 설명하는 것보다 쉽기 때문에 그렇게하겠습니다.

Python 3.x :

>>> bytearray(newFileBytes)
bytearray(b'{\x03\xff\x00d')
>>> bytes(newFileBytes)
b'{\x03\xff\x00d'

Python 2.x :

>>> bytearray(newFileBytes)
bytearray(b'{\x03\xff\x00d')
>>> bytes(newFileBytes)
'[123, 3, 255, 0, 100]'

1
내장 유형을 잘 사용합니다. bytearray는 2.6에서 추가되었으므로 레거시 시스템을 지원하려면 피해야합니다.
Perkins

7
@Perkins는 : 물론, 그리고 당신은 당신이 2.3에서 작업해야하는 경우, 발전기 식을 피하기 모두 조심해야 str.encode하고 struct.pack당신은 2.2에 대한 작업을해야하는 경우. 하지만 2.6은 5 년 동안 나왔습니다. 세 가지 Ubuntu LTS 모두 아직 지원 중이며, 세 가지 OS X 버전 모두 지원, 이전 주요 CentOS / RHEL 버전 등이 모두 기본 제공됩니다. 2.5, 2.1 또는 1.6 등을 지원해야하는 경우 아마도 알아요…
abarnert abarnert

4
Windows에서 Python 2를 사용할 때 파일을 열 때 "b"플래그가 전달되지 않으면 a 를 작성하면 bytearray여전히으로 변환 \n되어 \r\n이진 데이터에 만족스럽지 않습니다.
feersum

6
@feersum : 물론입니다. 이것이 2.x에서 바이너리 대 텍스트 모드의 의미 입니다. 바이트의 유형은 중요하지 않습니다. (물론 3.x에서 바이너리 대 텍스트 모드는 바이트 대 유니 코드를 작성한다는 것을 의미 \r\n
하며이

bytearray ()가 파일 쓰기에 좋은 선택인지 잘 모르겠습니다. 크기를 관리 가능한 청크로 제한해야합니다. 그렇지 않으면 파일 크기가 너무 높아지면 메모리가 부족합니다.
mckenzm

31

사용 struct.pack후 바이트 쓰기, 이진 바이트로 정수 값을 변환 할 수 있습니다. 예

newFile.write(struct.pack('5B', *newFileBytes))

그러나 바이너리 파일에 .txt확장자를 주지 않을 것 입니다.

이 방법의 장점은 다른 유형에서도 작동한다는 것입니다. 예를 들어 값이 255보다 큰 경우 '5i'전체 32 비트 정수를 가져 오는 대신 형식에 사용할 수 있습니다 .


.txt는 작성중인 데이터가 모두 인쇄 가능한 ASCII 범위에 속하는지 알 수있는 방법이 있으면 괜찮습니다. 그러나 예제 데이터에 인쇄 할 수없는 문자가 포함되어 있기 때문에이 경우에는 정확하다고 생각합니다.
Perkins

@Perkins 나는 ASCII 범위에서 값이 256보다 훨씬 적을 것이라고 가정하지 않았습니다. 그렇더라도 .txt 파일은 이진 데이터에 적용되지 않는 사람이 이해할 수있는 파일을 위해 예약해야합니다.
마크 랜섬

1
맞습니다. bytearray도 chr도 더 큰 정수 값을 처리 할 수 ​​없기 때문에 255 이상의 값으로 데이터를 작성하려는 경우 struct.pack도 사용할 수 있습니다.
Perkins

1
@MarkRansom : 음, 이것은 "임의이지만 고정 된 크기의 정수 목록이 있습니다. 어떻게 이진 파일에 쓸 수 있습니까?"라는 일반적인 문제에 대한 좋은 해결책입니다. 나는 사람들이 ... 그 질문에 대한 검색이 하나를 찾아 볼 수 있습니다
abarnert

1
struct.pack이 더 나은 대답입니다. 단순히 바이트 배열을 만드는 것보다 훨씬 더 유연합니다.
Seth

12

256 미만의 정수에서 이진수로 변환하려면 chr함수를 사용하십시오 . 그래서 당신은 다음을보고 있습니다.

newFileBytes=[123,3,255,0,100]
newfile=open(path,'wb')
newfile.write((''.join(chr(i) for i in newFileBytes)).encode('charmap'))

1
<128을 의미해야합니다. python3이 불평하는 것처럼 UnicodeEncodeError : 'ascii'코덱은 위치 0에서 '\ x89'문자를 인코딩 할 수 없습니다 : 서 수가 범위 (128)에 없습니다
elig

2
아니, <256을 의미하지만 인코딩해야 charmap보다는 ascii, 그리고 작품뿐만 아니라 python3로 python2있다. ascii인코딩은 python2에서 작동합니다.
Perkins

9

Python 3.2 이상에서는 to_bytes기본 int 메서드를 사용하여이 작업을 수행 할 수도 있습니다 .

newFileBytes = [123, 3, 255, 0, 100]
# make file
newFile = open("filename.txt", "wb")
# write to file
for byte in newFileBytes:
    newFile.write(byte.to_bytes(1, byteorder='big'))

즉, to_bytes이 경우에 대한 각 단일 호출 은 정수 값을 나타내는 빅 엔디안 순서 (길이 1 문자열의 경우 사소함)로 배열 된 문자를 사용하여 길이 1의 문자열을 생성합니다 byte. 마지막 두 줄을 단일 줄로 줄일 수도 있습니다.

newFile.write(''.join([byte.to_bytes(1, byteorder='big') for byte in newFileBytes]))

8

Python 3 구문을 사용하여 다음 코드 예제를 사용할 수 있습니다.

from struct import pack
with open("foo.bin", "wb") as file:
  file.write(pack("<IIIII", *bytearray([120, 3, 255, 0, 100])))

다음은 쉘 한 줄짜리입니다.

python -c $'from struct import pack\nwith open("foo.bin", "wb") as file: file.write(pack("<IIIII", *bytearray([120, 3, 255, 0, 100])))'

1

다음과 같이 pickle을 사용하십시오. import pickle

코드는 다음과 같습니다.

import pickle
mybytes = [120, 3, 255, 0, 100]
with open("bytesfile", "wb") as mypicklefile:
    pickle.dump(mybytes, mypicklefile)

데이터를 다시 읽으려면 pickle.load 메소드를 사용하십시오.


3
이것은 5 바이트 길이의 바이너리 파일을 생성하지 않습니다. 여기서 유일한 내용은 120, 3, 255, 0, 100입니다. 폐쇄 형 시스템에서는 허용 될 수 있습니다.
parvus
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.