I have a class which extends BufferedReader, and a list of file streams
b.close() is called for all except the last stream, I want to keep the streams open
How do I do this?
thanks
class TestReader(BufferedReader):
pass
def test(streams):
for stream in streams:
b=TestReader(stream)
do_something(b)
#all the streams except streams[-1] are closed, how do I prevent this?
streams=[open('test1.txt','rb'),open('test2.txt','rb')]
test(streams)
streams.do_something_else()
Even though in the implementation
BufferedIOBaseclasses wrap anIOBaseobject, their interface is a stream (everything inherits fromIOBase), so the ordinary behavior of aIOBaseobject is to close themselves when they go out of scope.BufferedIOBasejust delegates theclose()call to the underlying stream.You shouldn’t view a
BufferedReaderas a stream wrapper (although that is how it is implemented), but as a type-casting of an existing stream. The state of the two streams is completely bound together. However, you can unbind the wrapped stream withdetach(), but this leaves theBufferedIOBaseobject useless.Additionally,
io.openreturns aBufferedReaderalready when mode isrb, so you are double-buffering. You should useio.FileIOinstead.You have a few choices:
Create a new stream and a new underlying file descriptor, and pass around file names instead of streams. This is your easiest and safest option.
Create raw file descriptors and create streams from them as needed. This requires some
care that multiple streams are not using the same file descriptor at the same time. For example:
detach()the underlying stream before yourBufferedIOBaseobject closes its stream. (Remember to rewind the stream!)You can even implement this in your destructor:
Or just disable
close()delegation completely if you think the semantics are wrong:I don’t have the big picture of what you are doing (possibly you need a different design), but this is how I would implement the code I see: