Lance Collins
Lance Collins

Reputation: 3445

python zipfile module with TextIOWrapper

I wrote the following piece of code to read a text file inside of a zipped directory. Since I don't want the output in bytes I added the TextIOWrapper to display the output as a string. Assuming that this is the right way to read a zip file line by line (if it isn't let me know), then why does the output print a blank line? Is there any way to get rid of it?

import zipfile
import io

def test():
    zf = zipfile.ZipFile(r'C:\Users\test\Desktop\zip1.zip')
    for filename in zf.namelist():
        words = io.TextIOWrapper(zf.open(filename, 'r'))
        for line in words:
            print (line)
    zf.close()

test()

>>> 
This is a test line...

This is a test line...
>>> 

The two lines in the file inside of the zipped folder are:
This is a test line...
This is a test line...

Thanks!

Upvotes: 6

Views: 3337

Answers (1)

Eryk Sun
Eryk Sun

Reputation: 34260

zipfile.open opens the zipped file in binary mode, which doesn't strip out carriage returns (i.e. '\r'), and neither did the defaults for TextIOWrapper in my test. Try configuring TextIOWrapper to use universal newlines (i.e. newline=None):

import zipfile
import io

zf = zipfile.ZipFile('data/test_zip.zip')
for filename in zf.namelist():
    with zf.open(filename, 'r') as f:
        words = io.TextIOWrapper(f, newline=None)
        for line in words:
            print(repr(line))

Output:

'This is a test line...\n'
'This is a test line...'

The normal behavior when iterating a file by line in Python is to retain the newline at the end. The print function also adds a newline, so you'll get a blank line. To just print the file you could instead use print(words.read()). Or you could use the end option of the print function: print(line, end='').

Upvotes: 5

Related Questions