I want to use a buffered stream because I want to use a peek() method to peek ahead but use my stream with another method that expects a file-like object. (I'd use seek() but may have to handle piped-in I/O that doesn't support random access.)
But this test case fails:
AttributeError: 'file' object has no attribute '_checkReadable'
import sys
import io
srcfile = sys.argv[1]
with open(srcfile, 'rb') as f:
    fbuf = io.BufferedReader(f)
    print fbuf.read(20)
What's going on and how do I fix it? I thought BufferedReader was intended to buffer a stream. If so, why does the open() function not return something that's compatible with it?
Introduction. The Java.io.BufferedReader class reads text from a character-input stream, buffering characters so as to provide for the efficient reading of characters, arrays, and lines.Following are the important points about BufferedReader − The buffer size may be specified, or the default size may be used.
With the BufferdRreader nothing but if you loose the reference to stream and cannot close it and this leads to a memory leak.
By the looks of your print statement, you're using Python 2. On that version, a file is not a valid argument to the BufferedReader constructor:
Under Python 2.x, this is proposed as an alternative to the built-in
fileobject, but in Python 3.x it is the default interface to access files and streams. (1)
You should use io.open instead:
>>> f = io.open(".bashrc", "rb")
If you do this, there's no need to explicitly wrap it in a BufferedReader since that's exactly what io.open returns by default:
>>> type(f)
<type '_io.BufferedReader'>
See its docs for details; there's a buffering argument that controls the buffering.
In Python 3, open is io.open so the two I/O libraries have been merged back into one. It seems that io was added to Python 2.6 mostly for forward compatibility.
You can set the amount of buffering in bytes by passing the buffering argument to open:
import sys
srcfile = sys.argv[1]
with open(srcfile, 'rb', buffering=30) as f:
    print(f.peek(30))
    print(f.read(20))
This is a BufferedReader:
>>> with open("test.txt", 'rb', buffering=30) as f:
...     type(f)
<class '_io.BufferedReader'>
Note that, by default, it's buffered to 1 - line buffered.
In Python2, if you have to use file object as returned by open (or e.g. provided by some module routines which you cannot modify), you can use file descriptor obtained by fileno() for io.FileIO constructor, then pass io.FileIO object to io.BufferedReader constructor. 
So, you sample code can be rewritten as follows:
import sys
import io
srcfile = sys.argv[1]
with open(srcfile, 'rb') as f:
    fio  = io.FileIO(f.fileno())
    fbuf = io.BufferedReader(fio)
    print fbuf.read(20)
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With