【问题标题】:How can I reliably guarantee access to a file/folder?如何可靠地保证对文件/文件夹的访问?
【发布时间】:2009-02-20 20:41:29
【问题描述】:

-确保我要操作的文件夹或文件可访问(非只读)的最简单方法是什么?

-我知道我可以使用 ACL 添加/设置条目(使文件/文件夹非只读),但是我怎么知道我是否需要使用安全权限来确保文件访问?或者我可以将其添加为额外措施并处理异常/负面情况吗?

-我如何知道何时关闭或只刷新流?例如,我是否应该尝试在方法中使用一次流,然后在最后刷新/关闭/丢弃?如果我使用 dispose(),是否还需要显式调用 flush() 和 close()?

我问这个问题是因为不断确保文件可用是核心要求,但很难保证这一点,所以我的代码设计中的一些技巧会很好。

谢谢

【问题讨论】:

    标签: c# file


    【解决方案1】:

    无法保证对文件的访问。我知道这不是一个受欢迎的回应,但它是 100% 正确的。即使您在 Win32 机器上打开了独占的非共享文件,您也永远无法保证对文件的访问。

    失败的方式太多,您根本无法控制。经典示例是通过网络打开的文件。使用任何帐户以任何方式打开它,我只需走过并拉动网线即可。这将终止您对文件的访问。

    我并不是说这是刻薄或傲慢。我这样说是为了确保人们理解对文件系统进行操作是一项非常危险的操作。您必须接受该操作可能并且将会失败。任何涉及磁盘的操作都必须有一个备用方案。

    【讨论】:

    • +1。尽管无论如何您都应该始终捕获异常,但对于文件等非托管资源尤其重要。很多事情都可能出错,.NET 也救不了你。当他们的 2 小时网络同步因电缆被拉断而中断时,您的用户将欣赏正确的错误处理。
    【解决方案2】:

    -确保我要操作的文件夹或文件可访问(非只读)的最简单方法是什么?

    以写入模式打开它们?

    【讨论】:

      【解决方案3】:
      • 尝试将新文件写入文件夹并捕获任何异常。除此之外,还会进行正常的完整性检查,例如文件夹/文件是否存在等。

      • 您永远不应更改代码中的文件夹安全性,因为环境可能会发生巨大变化并导致严重的问题。而是确保事先对安全性进行充分记录和配置。或者,在您自己的代码中使用模拟,以确保您始终以对文件夹/文件具有完全权限的用户身份运行所需的代码。

      • 除非您别无选择,否则切勿调用 Dispose()。您总是在关闭文件之前或想要将流的内容提交到文件/磁盘时刷新。何时执行此操作的选择取决于需要写入的数据量以及写入数据所涉及的时间。

      【讨论】:

        【解决方案4】:

        确保文件夹可写的 100% 万无一失的方法 - 创建一个文件,关闭它,验证它是否存在,然后删除它。有点乏味,但你要求万无一失=)

        如果您无法写入文件,最好的办法是处理各种异常,其中涵盖了您关于 ACL 的问题。

        另外,我总是显式调用 Close,除非我需要在完成写入之前从文件中读取(在这种情况下,我调用 flush 然后 close)。

        【讨论】:

          【解决方案5】:
          • Flush() - 将内存缓冲区与磁盘同步。当您想将缓冲区写入磁盘但保持文件打开以供进一步使用时调用。
          • Dispose(bool) - 释放非托管资源(即操作系统文件句柄),如果传递为 true,则还释放托管资源。
          • Close() - 在对象上调用 Dispose(true)。

          此外,Dispose 在关闭句柄之前会刷新数据,因此无需显式调用刷新(尽管根据您正在处理的数据的数量和类型,频繁刷新可能是个好主意)。

          如果您正在对文件进行相对原子的操作并且不需要长时间运行的句柄,则“使用”范例有助于确保您正确处理文件,例如:

          using (StreamReader reader = new StreamReader("filepath"))
          {
              // Do some stuff
          } // CLR automagically handles flushing and releasing resources
          

          【讨论】:

          • 谢谢。如何决定将 Dispose() 的布尔值设置为真还是假?谢谢。
          • 我想大多数时候你会设置它为真。如果在某些情况下您需要释放非托管资源(如文件句柄)但仍想访问托管 .NET 对象(您必须小心),请传递 false。不过这不太可能,我会避免它。
          • 如果你没有做任何非标准的事情,你可以坚持 Close()。如果您正在做一些真正自定义的文件系统工作,您绝对应该阅读并重新阅读 MSDN 文档“清理非托管资源”和 IDisposable 接口。也许以后再读一遍;这可能会令人困惑。 :)
          猜你喜欢
          • 1970-01-01
          • 2014-05-28
          • 2019-03-19
          • 1970-01-01
          • 1970-01-01
          • 2020-08-30
          • 2012-08-28
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多