【发布时间】:2010-10-14 14:48:50
【问题描述】:
在我的新代码中,我不使用字符串来传递目录路径或文件名。相反,我使用的是 DirectoryInfo 和 FileInfo,因为它们似乎封装了很多信息。
我见过很多代码使用字符串来传递目录信息,然后它们在冗长的难以理解的语句中“拆分”、“中间”和“instr”,直到他们得到他们正在寻找的目录部分。
是否有充分的理由将路径作为字符串传递?
【问题讨论】:
在我的新代码中,我不使用字符串来传递目录路径或文件名。相反,我使用的是 DirectoryInfo 和 FileInfo,因为它们似乎封装了很多信息。
我见过很多代码使用字符串来传递目录信息,然后它们在冗长的难以理解的语句中“拆分”、“中间”和“instr”,直到他们得到他们正在寻找的目录部分。
是否有充分的理由将路径作为字符串传递?
【问题讨论】:
一旦路径在应用程序中(即不在纯文本配置文件中),不,没有充分的理由。
唯一可能有用的时候(我能想到)是与只接受路径作为字符串的代码进行互操作时。
【讨论】:
DirectoryInfo 和FileInfo 如果您只需要一条路径,那么在四处走走就太重了。我会更关心“分裂和中间和instr”的垃圾。了解以下方法:
Path.GetFileName
Path.GetDirectoryName
路径.组合
等等……
这些来自System.IO.Path 类,顺便说一句。
【讨论】:
要记住路径字符串和 FileInfo 之间的一个显着区别,可以在下面的测试中总结:
FileInfo 反映了文件实例化时的信息 - 它可以被删除/修改,而 FileInfo 不会反映这一点。
[TestMethod]
public void TestFileInfo()
{
var path = @"C:\Users\bjarmuz\Desktop\aybabtu.txt";
File.WriteAllText(path, "All your base are belong to us!");
var file = new FileInfo(path);
Assert.IsTrue(file.Exists);
File.Delete(file.FullName);
Assert.IsTrue(file.Exists);
Assert.IsFalse(File.Exists(file.FullName));
}
[TestMethod]
public void TestFileInfo()
{
var path = @"C:\Users\bjarmuz\Desktop\aybabtu.txt";
File.WriteAllText(path, "All your base are belong to us!");
Thread.Sleep(1000);
var file = new FileInfo(path);
var date = DateTime.UtcNow;
Assert.IsTrue(file.LastWriteTimeUtc< date);
File.WriteAllText(path, "No!");
Assert.IsTrue(File.GetLastWriteTimeUtc(file.FullName)> date);
Assert.IsFalse(file.LastWriteTimeUtc > date);
}
这可能有点误导,如果您的代码传递 FileInfos 而不是字符串,您可能会看到属性的错误结果,例如 Exists 或 Last[..]Time - 如果您使用 @987654325,则不会发生这种情况@方法。
但是,另一方面,您也不应该依赖 File.Exists() 方法 - 因为可以在运行测试后立即创建/删除文件。正确的方法是不要做这个检查,而是接受它可以抛出 IO 异常(并准备好正确处理它)。这篇很棒的文章中的更多信息https://blogs.msdn.microsoft.com/ericlippert/2008/09/10/vexing-exceptions/
此外,FileInfo/DirectoryInfo 的一个重要“优势”是它可以保护您的方法(和方法使用者)免受以下情况的影响:
void SaveEntity(Entity theThing, string path)
{
//now, based on the signature, you don't know whether you need file path or directory path
}
//void SaveEntity(Entity theThing, DirectoryInfo path) {}
//void SaveEntity(Entity theThing, FileInfo path) {}
【讨论】:
我认为您确实需要一个类来封装文件或目录路径,而不是使用原始字符串并使用静态 System.IO.Path 类来操作它们。但是,I don't find DirectoryInfo and FileInfo suitable,因为它们似乎更多地用于执行文件/目录操作而不是路径操作。如果您为路径操作制作自定义类,您可以提供more user friendly path manipulation functionality。
【讨论】:
我在将 FileInfo 传递给 DMZ 时遇到了问题。据我所见 - 如果我错了,请纠正我 - FileInfo 在反序列化时执行权限检查,这在 DMZ 中不起作用并导致“找不到路径”。使用您的数据创建并传递自定义对象。
【讨论】:
总的来说,我认为将信息保存在 FileInfo/DirectoryInfo 中会更好。这些类中有很多有用的功能,以及很多安全性,因为它更容易检查文件是否存在、查看最初指定的文件等。
如果路径要跨 AppDomains 或在进程之间传递等,我将(可能)将路径作为字符串传递而不是使用 FileInfo 和 DirectoryInfo 的唯一地方。
FileInfo 和 DirectoryInfo 都可以跨 AppDomain 边界正常工作(因为它们是可序列化的),但在这种情况下它们的开销要大得多。如果事情来回频繁,它可能会产生影响。
在这种情况下,我会坚持使用 FileInfo 和 DirectoryInfo,除非我发现在我的分析过程中存在明显的问题,并且我试图减少序列化数据的数量。如果我没有遇到性能问题,我会坚持使用这些类,因为它们提供了很多安全性和功能性。
【讨论】: