防止 BufferedReader 关闭文件列表的文件
我有一个扩展 BufferedReader 的类和一个文件流列表 除了最后一个流之外的所有流都调用 b.close() ,我想保持流打开 我该怎么做?
谢谢
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()
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()
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
即使在实现中
BufferedIOBase
类包装了IOBase
对象,它们的接口是一个流(一切都继承自IOBase
),因此 IOBase 对象的普通行为是在超出范围时关闭自身。BufferedIOBase
只是将close()
调用委托给底层流。您不应该将
BufferedReader
视为流包装器(尽管这就是它的实现方式),而应将其视为现有流的类型转换。两个流完全绑定在一起。但是,您可以使用 detach() 解除包装流的绑定,但这会使 BufferedIOBase 对象变得无用。此外,当模式为
rb
时,io.open
已经返回一个BufferedReader
,因此您是双缓冲的。您应该使用 io.FileIO 来代替。您有几个选择:
创建一个新的流和一个新的底层文件描述符,并传递文件名而不是流。这是最简单、最安全的选项。
创建原始文件描述符并根据需要从中创建流。这需要一些
注意多个流不要同时使用相同的文件描述符。例如:
BufferedIOBase
对象关闭其流之前,detach()
底层流。 (记得快退流!)您甚至可以在析构函数中实现它:
或者如果您认为语义错误,则完全禁用
close()
委托:我不知道什么是大局你正在做的(可能你需要不同的设计),但这就是我实现我看到的代码的方式:
Even though in the implementation
BufferedIOBase
classes wrap anIOBase
object, their interface is a stream (everything inherits fromIOBase
), so the ordinary behavior of aIOBase
object is to close themselves when they go out of scope.BufferedIOBase
just delegates theclose()
call to the underlying stream.You shouldn't view a
BufferedReader
as 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 theBufferedIOBase
object useless.Additionally,
io.open
returns aBufferedReader
already when mode isrb
, so you are double-buffering. You should useio.FileIO
instead.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 yourBufferedIOBase
object 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: