‘File.Open()’和‘new FileStream()’之间的区别

问题描述 投票:0回答:4

有什么区别(如果有的话)?

c# .net file-io
4个回答
31
投票

没有。

File.Open()
,内部无非是:

public static FileStream Open(string path, FileMode mode, FileAccess access, FileShare share)
{
    return new FileStream(path, mode, access, share);
}

如果您不使用指定

FileAccess
FileShare
的重载,它会为您指定这一点(在附加上使用
FileShare.None
FileAccess.Write
,否则使用
ReadWrite
)。

话虽这么说,这是一个实现细节,而不是文档的一部分。从技术上讲,未来的 .NET Framework 版本可以使用不同的实现,尽管我发现这不太可能。


27
投票

这种重复在.NET框架中非常罕见。 但有一个关于这个的故事,由 Krzysztof Cwalina 在“本次讲座”中讲述。 他们对该框架的早期版本进行了可用性研究,要求一群经验丰富(但与 .NET 无关)的程序员使用 FileStream 和 StreamReader/Writer 类编写一些代码。 进展并不顺利,他们的失败率是100%。 他们的回应是向 System.IO.File 类添加方法,使用“最有可能陷入成功的陷阱”的方法。

顺便说一句,很酷的视频,如果您完全了解框架看起来如此的原因。

最好发布一个真正的答案:File.Open() 方法调用 FileStream 构造函数,传递最有可能执行正确操作的 FileAccess 和 FileShare 值(如果您未指定它们)。 这是 FileAccess.ReadWrite 和 FileShare.None。


7
投票
File.Open()

是一种方便的方法。在内部它的实现为:

public static FileStream Open(string path, FileMode mode, FileAccess access, FileShare share)
{
    return new FileStream(path, mode, access, share);
}



4
投票

这是由于

FileShare

标志拒绝共享当前文件,并且在文件关闭之前打开将失败。该标志可以

可选地
传递给new FileStream(...)的构造函数。在 Windows 计算机上,IOException 将始终抛出,而在 Linux 计算机上,仅当标志设置为
FileShare.None
时。这可能是由于 Linux 上处理文件的方式不同所致(例如,您可以做一些疯狂的事情,例如在 Linux 操作系统上删除文件但仍然写入文件)。
要使您的代码在 Linux 和 Windows 计算机上运行,请确保您使用便利函数 

File.Open(...)

,它会自动设置

FileShare.None
标志或将正确的
FileShare
标志传递给构造函数。
我在使用以下两个版本打开文件时偶然发现了这个问题:

var fileStreamSource = new FileStream(uploadFilePath, FileMode.Open);

var fileStreamSource = File.Open(uploadFilePath, FileMode.Open);

前一套
FileShare.Read

,后一套

FileShare.None
。它们在 Windows 计算机上相同,但在 Linux 计算机上不同。
我不知道这是故意的还是错误。然而,这让我很烦恼。

© www.soinside.com 2019 - 2024. All rights reserved.