我看到很多代码使用字符串来传递目录信息,然后他们使用"split"、"mid"和"instr"等长且难以理解的语句,直到找到他们所需的目录部分。
有什么好的理由将路径作为字符串传递吗?
总的来说,我认为保留在FileInfo/DirectoryInfo中的信息更好。这些类中有很多有用的功能,并且在检查文件是否存在、查看最初指定的文件等方面有很多安全性。
我唯一会(潜在地)将路径作为字符串传递而不使用FileInfo和DirectoryInfo的情况是,如果该路径要在应用程序域之间或进程之间传递等。
FileInfo和DirectoryInfo在应用程序域边界上都可以正常工作(因为它们是可序列化的),但是在这种情况下它们具有相当多的开销。如果数据来回传输频繁,可能会产生影响。
在这种情况下,我会坚持使用FileInfo和DirectoryInfo,除非我在分析过程中发现性能问题,并且我正在尝试减少序列化数据的量。如果我没有遇到性能问题,我会继续使用这些类,因为它们提供了很多安全和功能。
DirectoryInfo
和FileInfo
如果你只需要一个路径,那么它们使用起来非常繁重。我更关心"split and mid and instr"这些琐碎的东西。学习如何使用:
Path.GetFileName
Path.GetDirectoryName
Path.Combine
等等...
这些都是来自于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);
}
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类进行操作。然而,我不认为DirectoryInfo和FileInfo适合, 因为它们似乎更适用于进行文件/目录操作而不是路径操作。如果您为路径操作创建自定义类,则可以提供更用户友好的路径操作功能。
在将FileInfo传递给DMZ时,我遇到了问题。据我所知 - 如果我错了,请纠正我 - FileInfo在反序列化时执行权限检查,而这在DMZ中不起作用,会导致“路径未找到”的错误。相反,创建并传递一个带有您需要的数据的自定义对象。
我找到了一个不使用它们的好理由。 归根结底,路径是一种类型,通常通过字符串表示,但它本身不是字符串,它有一些行为,如在这个视频中(只需检查60秒后的几秒钟)所解释。
这个视频本身提供了一个很好的文件路径管理解决方案,这是一个很好的起点,无论您正在寻找什么其他行为。
唯一的缺点可能是在极高性能环境下会有一些内存开销,但如果您不创建数百个路径对象,则大多数情况下没有理由不使用以下代码:
//This class provides all the rules for your application about how to handle a path as a value
public record FilePath
{
public string Path { get; }
public FilePath (string path) =>
Path =
string.IsNullOrWhiteSpace (path)
? throw new ArgumentException ("path cannot be null or empty") :
System.IO.Path.GetInvalidPathChars().Intersect (path).Any()
? throw new ArgumentException ("Path contains illegal characters")
: System.IO.Path.GetFullPath (path.Trim());
public override string ToString() => Path;
//Note on linux environments you would make it case sensitive
public virtual bool Equals (FilePath? other) =>
(Path).Equals (other?.Path, StringComparison.InvariantCultureIgnoreCase);
public override int GetHashCode() => Path.ToLowerInvariant().GetHashCode();
public static implicit operator FilePath (string name) => new FilePath (name);
public FileInfo GetInfo() => new FileInfo (Path);
public FilePath Combine (params string[] paths) =>
System.IO.Path.Combine (paths.Prepend (Path).ToArray());
}
感谢Joe Albahari,视频中有关于C#更多有趣的内容可以了解。
示例取自LinQPad 7源代码样例。