somerandomguy
somerandomguy

Reputation: 323

[File IO Error in porting from python2 to python 3]

I port my project from python 2.7 to python 3.6

What I was doing in python 2.7

1)Decode from Base 64

2)Uncompress using Gzip

3)Read line by line and add in file

    bytes_array = base64.b64decode(encryptedData)
    fio = StringIO.StringIO(bytes_array)
    f = gzip.GzipFile(fileobj=fio)
    decoded_data = f.read()
    f.close()
    f = file("DecodedData.log",'w')
    for item in decoded_data:
        f.write(item)
    f.close()

I tried the same thing using python 3 changes but It is not working giving one error or the other.

I am not able to use StringIO giving error

#initial_value must be str or None, not bytes

So I try this

    bytes_array = base64.b64decode(encryptedData)

    #initial_value must be str or None, not bytes

    fio = io.BytesIO(bytes_array)
    f = gzip.GzipFile(fileobj=fio)
    decoded_data =f.read()
    f= open("DecodedData.log",'w')
    for item in decoded_data:

        f.write(item)
    f.close()

This gives error in the line f.write(item) that

    write() argument must be str, not int

To my surprsie,item actually contains an integer when i print it.(83,83,61,62)

I think it as I have not given the limit,it is reading as many as it can. So I try to read file line by line

   f= open("DecodedData.log",'w')
   with open(decoded_data) as l:
    for line in l:    
        f.write(line)

But it still not working and \n also printing in file. Can some suggest what I am missing.

Upvotes: 2

Views: 121

Answers (1)

Tom Dalton
Tom Dalton

Reputation: 6190

decoded_data = f.read()

Will result in decoded_data being a bytes object. bytes objects are iterable, when you iterate them they will return each byte value from the data as an integer (0-255). That means when you do

for item in decoded_data:
    f.write(item)

then item will be each integer byte value from your raw data.

f.write(decoded_data)

You've opened f in text mode, so you'll need to open it in binary mode if you want to write raw binary data into it. But the fact you've called the file DecodedData.log suggests you want it to be a (human readable?) text file.

So I think overall this will be more readable:

gzipped_data = base64.b64decode(encryptedData)
data = gzip.decompress(gzipped_data)  
with open("DecodedData.log",'wb') as f:
    f.write(data)

There's no need for the intermediate BytesIO at all, gzip has a decompress method (https://docs.python.org/3/library/gzip.html#gzip.decompress)

Upvotes: 2

Related Questions