我正在尝试编写一个函数来确定文件是否存在.这两种方法证明返回不一致的结果(fileExists()似乎提供了准确的结果,与isFileFound()相比,它返回误报 - 我试图创建实例时会发生异常).
protected bool isFileFound(string path, string fileName) { System.IO.FileInfo fi = null; bool found = false; try { fi = new System.IO.FileInfo(path + fileName); found = true; } catch (Exception e) { baselogger.Fatal(e.Message + " " + e.StackTrace + " \n" + path + fileName); } return found; } protected bool fileExists(string path, string pattern) { bool success = false; try { success = File.Exists(path + pattern); } catch (Exception e) { baselogger.Warn(e.Message + " " + e.StackTrace + " " + e.Source); } return success; }
似乎都无法解析以下语法的UNC路径:\\ abcserver\c $\xyzfolder\foo.bar
任何想法为什么unc路径失败的这些方法将不胜感激.
您可以为不存在的文件创建FileInfo.但是,您可以检查FileInfo.Exists属性以确定该文件是否存在,例如:
FileInfo fi = new FileInfo(somePath); bool exists = fi.Exists;
更新:在一个简短的测试中,这也适用于UNC路径,例如:
FileInfo fi = new FileInfo(@"\\server\share\file.txt"); bool exists = fi.Exists;
您确定该帐户(运行您的应用程序)可以访问该共享.我认为(默认情况下)管理权限是访问共享"c $"所必需的.
看到这个问题:
如何轻松检查.NET中的文件是否被拒绝访问?
该问题的简短版本是您没有,因为文件系统是易变的.只是尝试打开文件并在失败时捕获异常.
您的isFileFound
方法不起作用的原因是因为FileInfo
您使用的结构也可用于创建文件.您可以创建一个FileInfo对象,其中包含非现有文件的所需信息,调用它的.Create()
方法,并且您可以一次性设置所需的属性.
我怀疑UNC路径失败的原因是1)从运行你的应用程序的用户访问管理员共享的权限问题,或者 2)$
符号正在抛出该方法,因为它没有正确输入或者因为有错误底层的.Exists()实现.
更新:
当我发布这个建议时,我几乎总是会对异常表现抱怨.我们来谈谈这个.是的,处理异常是昂贵的:非常昂贵.在编程中你可以做的事情很少.但是你知道那些东西是什么吗?磁盘和网络I/O. 这是一个链接,演示了磁盘I/O和网络I/O成本:
https://gist.github.com/jboner/2841832
Latency Comparison Numbers -------------------------- L1 cache reference 0.5 ns Branch mispredict 5 ns L2 cache reference 7 ns 14x L1 cache Mutex lock/unlock 25 ns Main memory reference 100 ns 20x L2 cache, 200x L1 cache Compress 1K bytes with Zippy 3,000 ns Send 1K bytes over 1 Gbps network 10,000 ns 0.01 ms Read 4K randomly from SSD* 150,000 ns 0.15 ms Read 1 MB sequentially from memory 250,000 ns 0.25 ms Round trip within same datacenter 500,000 ns 0.5 ms Read 1 MB sequentially from SSD* 1,000,000 ns 1 ms 4X memory Disk seek 10,000,000 ns 10 ms 20x datacenter roundtrip Read 1 MB sequentially from disk 20,000,000 ns 20 ms 80x memory, 20X SSD Send packet CA->Netherlands->CA 150,000,000 ns 150 ms
如果在纳秒内思考不是你的事情,那么这是另一个将一个CPU周期标准化为1秒并从那里扩展的链接:
http://blog.codinghorror.com/the-infinite-space-between-words/
1 CPU cycle 0.3 ns 1 s Level 1 cache access 0.9 ns 3 s Level 2 cache access 2.8 ns 9 s Level 3 cache access 12.9 ns 43 s Main memory access 120 ns 6 min Solid-state disk I/O 50-150 ?s 2-6 days Rotational disk I/O 1-10 ms 1-12 months Internet: SF to NYC 40 ms 4 years Internet: SF to UK 81 ms 8 years Internet: SF to AUS 183 ms 19 years OS virt. reboot 4 s 423 years SCSI command time-out 30 s 3000 years Hardware virt. reboot 40 s 4000 years Physical system reboot 5 m 32 millenia
考虑到异常的最佳情况,您可以在等待磁盘的第一个响应时访问内存至少480次,并且假设SSD速度非常快.我们中的许多人仍然需要旋转硬盘,事情变得更糟,更糟糕.
这只是故事的开始.当你使用时.Exists()
,你会产生这个额外的费用(而且这是一个补充:你必须在每次尝试时再次执行相同的工作).无论文件是否存在,您都要支付这笔费用,因为磁盘仍然需要在文件表中查找.使用异常方法,您只需支付在失败的情况下展开调用堆栈的额外成本.
换句话说,是的:例外是非常昂贵的.但与磁盘检查相比,它仍然更快:而不仅仅是一小部分.值得庆幸的是,这不太可能推动您的应用程序的一般性能...但我仍然想要为这个特定任务上床"异常缓慢"的论点.