13

I need to read whole source data from file something.zip (not uncompress it)

I tried

f = open('file.zip')
s = f.read()
f.close()
return s

but it returns only few bytes and not whole source data. Any idea how to achieve it? Thanks

ivanleoncz
  • 9,070
  • 7
  • 57
  • 49
peter
  • 4,289
  • 12
  • 44
  • 67
  • 18
    Use binary mode when you're dealing with binary file. `open('file.zip', 'rb')` – falsetru Oct 08 '13 at 15:19
  • If I understand correctly, binary mode only deals with new lines and only on Windows, so it won't solve the problem. How are you counting the bytes? – Vlad Oct 08 '13 at 15:21
  • 4
    @Vlad there is an EOF (end of file character) that can terminate a read in text only mode on Windows – Jon Clements Oct 08 '13 at 15:22
  • thanks guys! could you please post short example how to do it correctly? – peter Oct 08 '13 at 15:23
  • 1
    `.read()` should read the whole file. How do you know you have only part of it? What does `len(s)` return? And warning: If Python thinks that `s` should contain human-readable text, it will pitch a fit if it encounters poorly encoded characters beyond ASCII. Aaand, if your `s` contains a \0 nil character, Python might end the string there. – Phlip Oct 08 '13 at 15:25
  • Binary mode works for me! Now I updated my code with open('file.zip', 'rb') then read it to variable and then I save it to new file with 'wb'. Now everything reads my content correctly and I can continue working with source data from source file. Thank you! – peter Oct 08 '13 at 15:30

3 Answers3

35

Use binary mode(b) when you're dealing with binary file.

def read_zipfile(path):
    with open(path, 'rb') as f:
        return f.read()

BTW, use with statement instead of manual close.

falsetru
  • 357,413
  • 63
  • 732
  • 636
6

As mentioned there is an EOF character (0x1A) that terminates the .read() operation. To reproduce this and demonstrate:

# Create file of 256 bytes
with open('testfile', 'wb') as fout:
    fout.write(''.join(map(chr, range(256))))

# Text mode
with open('testfile') as fin:
    print 'Opened in text mode is:', len(fin.read())
    # Opened in text mode is: 26

# Binary mode - note 'rb'
with open('testfile', 'rb') as fin:
    print 'Opened in binary mode is:', len(fin.read())
    # Opened in binary mode is: 256
Jon Clements
  • 138,671
  • 33
  • 247
  • 280
3

This should do it:

In [1]: f = open('/usr/bin/ping', 'rb')   

In [2]: bytes = f.read()

In [3]: len(bytes)
Out[3]: 9728

For comparison, here's the file I opened in the code above:

-rwx------+ 1 xx yy 9.5K Jan 19  2005 /usr/bin/ping*
AlG
  • 14,697
  • 4
  • 41
  • 54