4

I am trying to send myself PDF files per E-mail with Python. I am able to send myself the binary code of a PDF file, but I am not able to reconstruct the PDF file from this binary code.

Here is how I obtain the binary code of a PDF file:

file = open('code.txt', 'w')
for line in open('somefile.pdf', 'rb').readlines():
    file.write(str(line))
file.close()

Here is how I try to create a PDF file from the binary code:

file = open('new.pdf', 'wb')
for line in open('code.txt', 'r').readlines():
    file.write(bytes(line))
file.close()

I then recieve this error:

Traceback (most recent call last): File "something.py", line 3, in file.write(bytes(line)) TypeError: string argument without an encoding

What did I do wrong?

jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
Ron Lauterbach
  • 107
  • 1
  • 1
  • 12

2 Answers2

4

In your first block, open file in binary write mode (wb), since you are writing binary to it. Also, you don't need to convert it explicitly to str. It should look like this:

file = open('code.txt', 'wb')
for line in open('somefile.pdf', 'rb').readlines():
    file.write(line)
file.close()

For second block, open file in read binary mode (rb). Here also, no need to explicitly convert to bytes. It should look like this:

file = open('new.pdf', 'wb')
for line in open('code.txt', 'rb').readlines():
    file.write(line)
file.close()

This should do the trick. But why do you need to convert it in the first place? Keeping file intact will save your hardwork and computational power.

Jay Bhavsar
  • 159
  • 1
  • 14
3

Just to add. In my case, I was downloading the pdf file from an API and the 'response.content' came in base64 format. I also didn't need to write line by line I needed to convert the byte array first using:

import requests
import base64

response = requests.get(self.download_url,
                        allow_redirects=True,
                        headers=headers,
                        params=query_params)

bytes = base64.b64decode(response.content)

with open('file.pdf', 'wb') as f:
  f.write(bytes)

Danilo Marques
  • 136
  • 1
  • 1
  • 8