存在,读取和写入只需一步

本文关键字:一步 读取 存在 | 更新日期: 2023-09-27 18:12:02

我试图找出一个文件是否存在,如果它存在,验证css样式是否已经存在,如果不存在,将它们写在文件的末尾…

我已经在做这些了,但是分三步:

文件存在吗?

FileInfo fi= new FileInfo(Path.Combine(rootPath, "DefaultStyles.css");

如果是,我使用TextReader来获取内容

using (TextReader tr = new StreamReader(file))
{
    r = tr.ReadToEnd().Contains(".onebyonecard");
    tr.Close();
}

如果没有找到style,则写入

using (TextWriter tw = new StreamWriter(file))
{
    tw.Write(cssStyle);
    tw.Close();
}

有没有一种方法可以在一个简单的打开/关闭中做到这一点,而不是需要一遍又一遍地打开文件?

存在,读取和写入只需一步

你可以打开一个流来读和写——但是考虑到你要读整个文件,我个人会打开它两次。请注意,您当前的代码将覆盖文件,而不是追加到它。

我个人会使用File类中的静态方法:

// Elide this into the "if" condition if you want. I've separated it out here,
// but obviously it makes no difference.
bool present = File.Exists(path) &&
               File.ReadAllText(path).Contains(".onebyonecard);
if (!present)
{
    File.AppendAllText(path, cssStyle);
}

这比拥有一个读/写流并在其上创建TextReaderTextWriter要简单。

注意事项:

  • 通过分隔文件访问,存在出现竞争条件的轻微风险。我们可以打开文件,读取内容,然后在我们决定下一步做什么的时候进行更新。同样,当我们执行检查时,文件也可能存在,但在读取之前被删除。在大多数应用程序中,此风险非常小,以至于无关紧要——只有您才能确定。
  • 上面的代码仍然可能抛出异常,如果文件存在,但不能被相关用户读写,或者正在被其他进程使用。正常的异常处理风格适用-决定你认为你可以从这种情况中恢复到什么程度,并采取适当的行动。

好吧,既然你使用的是ReadToEnd(),你不妨使用:

if (!File.Exists(file) || !File.ReadAllText(file).Contains(".onebyonecard"))
    File.AppendAllText(file, cssStyle);

,但这仍然打开它两次。有一些api允许它只打开一次,但那些是二进制api (Stream等)-这将工作,但对于您的场景可能是多余的

try
{
TextReader tr = new StreamReader(file);
r = tr.ReadToEnd().Contains(".onebyonecard");
tr.Close();
tr.Dispose ();
}
catch { //File is not exists or is used by another application
}