【问题标题】:StreamWriter doesn't write to a file that doesn't existStreamWriter 不会写入不存在的文件
【发布时间】:2012-01-07 22:56:11
【问题描述】:

我正在为我的游戏制作关卡编辑器,其中大部分都在工作,除了... 当我尝试保存我的文件 (XML) 时,该文件没有被创建,并且在输出框中我得到:

A first chance exception of type 'System.NullReferenceException'

有趣的是,它仅在文件不存在时才会发生,但如果我覆盖另一个文件,它就会正常工作。

这是我正在使用的代码:

using (StreamWriter stream = new StreamWriter(filePath))
{
    stream.Write(data);
    stream.Close();
}

数据是一个字符串(这不是问题,因为它在我覆盖文件时起作用)

【问题讨论】:

  • 哪一行给出NullReferenceException
  • 没说,我觉得StreamWriter一定要捕获异常并Debug.WriteLine消息
  • 我唯一能想到的是该程序没有目录的创建权限。尝试删除using(仅用于调试目的),看看是否得到更有意义的异常。
  • @ChrisF 不,异常仍然没有出现,它只是被写入输出框
  • @luisperezphd 是的,如果文件存在,它们就可以工作

标签: c# file-io xna filestream xna-4.0


【解决方案1】:

你是 missing a constructor,它接受一个可以帮助创建文件的布尔值:

using (StreamWriter stream = new StreamWriter(filePath, false)) {
    stream.Write(data);
    stream.Close();
}

不过,逻辑实际上比这复杂一点:

public StreamWriter( string path, bool append )

确定是否将数据附加到文件中。如果文件 存在且追加为假,文件被覆盖。如果文件 存在且 append 为 true,则数据将附加到文件中。 否则,将创建一个新文件。

【讨论】:

  • 嗯,这使得流追加到文件,我想替换文件
  • 如果文件存在我想覆盖它,而不是附加到它
  • 我认为这不是正确的过载。问题不在于文件被覆盖,而在于它一开始就没有被创建。
  • @ChrisF 我看了一下,appendfalse,如果文件不存在,这个构造函数将始终创建文件。根据this使用默认编码和缓冲区大小为指定路径上的指定文件初始化 StreamWriter 类的新实例。如果文件存在,它可以被覆盖或附加到。如果文件不存在,则此构造函数创建一个新文件。
  • 使用using关键字时,不需要调用sw.Close(),它会自动处理。 (这是首先使用using 的重点)
【解决方案2】:

您为什么不简单地绕过它,并在写入文件之前检查文件是否存在:

public void Foo(string path, string data)
{
    if (!File.Exists(path))
        File.Create(path);

        using (var sw = new StreamWriter(path, false))
        {
            // Work your magic.
            sw.Write();
        }
}

我真的不会让它比个人更复杂。另外,不要关闭StreamWriterusing 语句会在其达到目的后将其处理掉。

【讨论】:

  • 检查是多余的,所以本质上会使事情变得更复杂。
  • 我个人认为不会。尽管它可能是多余的,但它更易于阅读、理解和调试。
  • 阅读起来并不容易。这段代码对竞争条件有什么看法?如果其他进程在创建文件后立即删除文件怎么办?它容易出现竞争条件错误。 StreamWriter 必须正确创建文件。否则这是 .NET 中的错误。
【解决方案3】:

在我的情况下,我以非管理员身份运行程序,该文件将写入以管理员权限创建的文件夹中(即使在 ProgramFiles 或任何非管理员位置)。该文件永远不会创建,您必须手动启用Managed Debugging Assistants 异常中断才能看到任何错误。

解决方案是删除该文件夹并使用我的非管理员帐户重新创建它。另请注意,StreamWriter does not 创建目录树,只创建文件。

【讨论】:

    【解决方案4】:

    您是否尝试过不使用 File.Create()?像这样:

    using (StreamWriter stream = new StreamWriter(filePath)) {
        stream.Write(data);
        stream.Close();
    }
    

    【讨论】:

    • 是的,这是第一种有效的方法,我复制粘贴了我的备份,抱歉 ;)
    • 当我运行此代码时,如果文件不存在,它会创建一个文件。并且覆盖它确实存在 - 这不是你想要的行为吗?
    • 好的,我明白了,这是它应该表现的方式,但它不适用于您的特定计算机。你能得到堆栈跟踪吗?您是否尝试过查看您是否拥有最新版本的 .NET 框架?也许不知何故你有写但没有创建文件夹的权限?
    • 我确实有最新的 .net 框架,而且我很确定我有创建文件夹的权限。至于堆栈跟踪,对不起,错误后我似乎无法调试,它只是恢复程序
    • 您可以尝试运行免费的 filemon 应用程序,看看它是否为您提供了更多详细信息。 Visual Studio 中还有一个设置可以在抛出任何异常时冻结应用程序,即使是已处理的异常也是如此。最后,您可以添加代码以输出堆栈跟踪。
    猜你喜欢
    • 2014-05-16
    • 2015-10-13
    • 1970-01-01
    • 1970-01-01
    • 2011-01-20
    • 2012-06-14
    • 1970-01-01
    • 2021-12-19
    • 2015-08-05
    相关资源
    最近更新 更多