保持C#文件流长时间打开是否安全?

14

在我的Web服务中,我打开了一个指向本地磁盘文件的文件流,并将其保留到服务生命周期结束。对于每个查询,我使用该文件流来读取磁盘上的数据。我这样做是为了避免在每个查询时重新打开文件流。这条路径的延迟很关键(应该小于几毫秒)。我使用SSD来保持磁盘IO时间在0.1毫秒以下。

长时间(数天)后,文件流是否会失效?每次查询重新打开文件流是否更安全?如果我必须重新打开文件流,每秒频繁重新打开文件流会产生多少开销?


2
如果你担心延迟,为什么不将文件内容加载到静态内存中?我认为问题应该是,你应该使用哪种模式来快速访问内容。 - AdamV
2
文件太大,无法放入内存。我有一个索引,可以直接寻找正确的偏移量并从那里读取。这不应该超过1个IO。读取的数据量很小。 - user201511
一个基本测试显示性能没有显著差异。但我还没有创建一个发送真实查询的压力测试,所以不确定在负载下会如何表现。你是对的,我应该这样做。 - user201511
如果文件过大而无法放入内存,并且您希望每个请求都能够随机访问整个文件,那么我会立即考虑使用内存映射文件。否则,您肯定必须对实际的FileStream对象进行序列化以便让所有访问都是串行的。 - Damien_The_Unbeliever
是的,你说得完全正确。当从磁盘读取时,我确实进行序列化访问。内存映射会占用一些非微不足道的内存,对吗?这是一个25GB的文件,不应该一次加载到内存中的全部内容。我不太清楚如何管理加载它的部分(哪些部分、多大等等)。那该怎么做呢? - user201511
显示剩余3条评论
2个回答

9

只要您需要,保持文件开启是安全的。

是否适合您的情况,您需要自己决定。重新打开文件不应该很慢(即使在常规驱动器上),但是您需要尝试并进行测量,因为除了您以外没有人知道您的确切性能目标。


选择这个作为答案,尽管其他的回答也给了很好的建议,但这是我问题唯一的直接回答。 - user201511

7
我唯一的担忧是,如果应用程序因任何原因而失败,并且无法从其当前位置恢复以关闭流,则保持文件打开状态。在使用用于打开文件的KERNEL32中的CreateFile入口时,会出现以下情况:

当应用程序使用CreateFile返回的对象句柄完成操作后,请使用CloseHandle函数关闭句柄。这不仅释放系统资源,还可以对共享文件或设备以及提交数据到磁盘等事项产生更广泛的影响。必要的详细信息将在本主题中适当地说明。

因此,我认为每次打开和关闭FileStream都更为合适。

我同意,长时间保持文件处于打开状态以供读取似乎存在风险,并且违反了开放、读取和关闭资源的最佳实践。 - AdamV
谢谢,听起来重新打开每次确实是正确的做法。 - user201511
@user201511,请记得将其标记为答案,以便我和社区的其他成员能够看到。 - Mike Perrenoud
我不确定你所说的“将其标记为自己和社区的答案”是什么意思。你是指将其标记为被接受的答案吗?我已经选择了一个答案。 - user201511

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接