File.Exists("") 和 FileInfo 存在有什么区别

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

我在 \ProgramFiles(x86)\MyAppFolder 中有一个 *.exe 文件。

在 x86 应用程序中,我检查文件是否存在(64 位系统)。 简单:

bool fileExists = File.Exists(@"\ProgramFiles(x86)\MyAppFolder\Manager.exe");

结果是: “fileExists == false”(文件确实存在)。据我了解,这是虚拟化。here描述了这个问题,没关系。 但下一个代码:

bool fileExists = new FileInfo("\\Path").Exists;

“文件存在== true”

为什么第一种情况和第二种情况的结果不同?

var controller = new ServiceController(Product.ServiceName);
_manager.Enabled = controller.Status == ServiceControllerStatus.Running;

var info = new DirectoryInfo(Assembly.GetExecutingAssembly().Location);

var s = File.Exists(@"D:\TFS\GL_SOURCES\Teklynx_LPM\Dev\Server\Debug\Manager.exe");

string pathToManager = string.Empty;

if (info.Parent != null)
{
    var pathToModule = info.Parent.FullName;
    pathToManager = Path.Combine(pathToModule,"Manager.exe").Replace(" ",string.Empty);
}

//效果很好

var fileInfo = new FileInfo(pathToManager);
var managerSeparator = new ToolStripSeparator()
{
    Visible = _manager.Visible = fileInfo.Exists // true
};

//不起作用

var managerSeparator = new ToolStripSeparator()
{
    Visible = _manager.Visible = File.Exists(pathToManager ) // false
};

谢谢!

c# .net virtualization
7个回答
33
投票

这是唯一的区别,它与

FileInfo
的性质有更多关系:

FileInfo fileInfo = new FileInfo("myFile.txt"); // non-existent file
Console.WriteLine(fileInfo.Exists);             // false
File.Create("myFile.txt");
Console.WriteLine(File.Exists("myFile.txt"));   // true
Console.WriteLine(fileInfo.Exists);             // false

因此,正如您所看到的,

fileInfo.Exists
的值在您第一次使用时被缓存。

除此之外,他们在幕后做同样的事情。


17
投票

没有区别,这些方法在 .NET Framework 中使用完全相同的内部帮助器方法。您可以通过反编译器或参考源代码看到一些内容,辅助方法名称是 File.FillAttributeInfo()。

在 .NET Framework 中出现这样的重复是很不寻常的,拥有多种方法来完成同一件事并不完全是一件好事。然而 File 类很特殊,它是在 .NET 1.0 发布时进行的“可用性研究”后添加的。测试对象仅具有可使用的基本 BCL 类,例如 FileStream 和 FileInfo,否则仅具有可用的 MSDN 文档。测试结果不是很好,添加了 File 类,以帮助程序员在编写非常基本的文件操作代码时陷入成功的陷阱。就像 File.Exists() 和 File.ReadAllLines() 一样。 所以它与类没有任何关系,你只是错误地使用了它们。就像实际上没有使用相同的路径一样。请轻松处理正斜杠,到反斜杠的映射发生在 Windows 内部,并且在其他代码中实现不一致。使用 // 肯定不会达到您希望的效果。


2
投票

让我们考虑一个场景,为 UNC 共享上当前不存在的文件创建一个 fileinfo 对象。

bool fileInfo = new FileInfo(@"\\uncshare\name\filename.txt");

此时,该文件不存在,但如果我使用其他工具(其他代码或在我的应用程序之外)创建它,然后执行此操作...

fileInfo.Refresh(); bool exists = fileInfo.Exists;

结果为 false,它不存在,即使它存在并且 fileInfo 已刷新。

要获得正确的结果需要..

bool exists = File.Exists(f);

希望对其他人有帮助。


1
投票
Linqpad

脚本复制了您的场景 var f = @"C:\Program Files (x86)\MyAppFolder\manager.exe"; bool fileExists = File.Exists(f); bool fileInfoExists = new FileInfo(f).Exists; fileExists.Dump(); fileInfoExists.Dump();

在文件存在和不存在时都运行此命令,并且每次都会产生相同的输出。
 也许在您的系统上尝试一下,看看您是否仍然看到差异。


1
投票
"Program Files (x86)"

中添加空格。


其次,Path.Combine 将返回一个目录路径,因此您最终会得到类似

"C:\Program Files (x86)\MyAppFolder\Manager.exe\"

的内容 所以这是一个坏主意。


两种方法的工作原理相同,因此请确保检查路径是否正确。


1
投票
File.Exists()

new FileInfo().Exists
之间的行为差异:

var f = @"C:\Program Files (x86)\MyAppFolder\many_subfolders\manager.exe"; //f.length > 260 characters bool fileExists = File.Exists(f); //return false, even if the file exists // Throw exception: "The specified path, file name, or both are too long. The fully qualified file name must be less than 260 characters, and the directory name must be less than 248 characters." bool fileInfoExists = new FileInfo(f).Exists;



0
投票

fileInfo.Exists();

воспользуйтесь

fileInfo.Refresh();

Это обновит информацию о файле。

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