写入AppData中的文本文件不起作用 - C#

时间:2017-03-19 00:02:43

标签: c# file text appdata

我使用以下代码行将用户凭据写入文本文件。它应该在AppData中创建目录(它确实如此),但是它不会将凭证写入文本文件,它会留空![/ p>

public void RegisterUserCreds()
{
    string[] creds = { Username.Text, Password.Text };
    string roaming = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
    if (!Directory.Exists(roaming + "/Launcher")) 
        Directory.CreateDirectory(roaming + "/Launcher");
    string specificFolder = roaming + "/Launcher/user_info.txt";
    var fs = File.Open(specificFolder, FileMode.OpenOrCreate, FileAccess.ReadWrite);
    var sw = new StreamWriter(fs);
    sw.WriteLine(Username.Text);
    fs.Close();
}

问题是什么?谢谢!

2 个答案:

答案 0 :(得分:1)

在溪流上操作时只需使用using statement

public static void RegisterUserCreds()
{
    string[] creds = { Username.Text, Password.Text };
    string roaming = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
    if (!Directory.Exists(roaming + "/Launcher")) Directory.CreateDirectory(roaming + "/Launcher");
    string specificFolder = roaming + "/Launcher/user_info.txt";
    using (var fs = File.Open(specificFolder, FileMode.OpenOrCreate, FileAccess.ReadWrite))
    {
        using (var sw = new StreamWriter(fs))
        {
            sw.WriteLine(Username.Text);
        }
    }
}

在您的代码中,您正在关闭文件流,然后流编写器才能刷新您要写入的更改,以便将文件创建为空。

答案 1 :(得分:0)

您正在关闭错误的信息流。当您创建新的流对象并将现有流传递给构造函数时,该新流现在已经拥有了#34;旧流。当您处理较新的流时,它将自动处理较旧的流。

在您的情况下,您正在关闭" fs"流,但" sw"流可能还没有实际写入它(它有它自己的内部缓冲区)。如果你要关闭" sw"相反,它会刷新它的缓冲区(进入" fs"流),然后它会为你调用fs.Dispose()以确保它做同样的事情。

有更好的方法,可以帮助您避免像这样无序地执行操作,并确保即使异常被抛出也会调用Dispose()(流实施IDisposable,因此当您完成这些方法时,您应该始终调用他们的Dispose()方法,这样他们就可以在内部"清理")。 using语句非常适用于此,因为即使抛出异常它也会调用Dispose()(它是使用try / finally块包装代码的快捷方式):

using (var fs = File.Open(specificFolder, FileMode.OpenOrCreate, FileAccess.ReadWrite))
{
    using (var sw = new StreamWriter(fs))
    {
        sw.WriteLine(Username.Text);
    }
}

这与此相同:

try
{
    var fs = File.Open(specificFolder, FileMode.OpenOrCreate, FileAccess.ReadWrite);
    try
    {
        var sw = new StreamWriter(fs);
        sw.WriteLine(Username.Text);
    }
    finally
    {
        sw.Dispose();
    }
}
finally
{
    fs.Dispose();
}

即使sw.Dispose()会为您拨打fs.Dispose(),再次致电fs.Dispose()也没有什么害处。为什么调用Dispose()很重要?我们假设在sw.WriteLine()期间抛出异常(例如磁盘空间不足,I / O错误等)......文件将保持打开状态,直到您的应用程序终止。 using(或try / catch版本)将确保文件无论如何都被关闭。

(旁注:对于溪流,Dispose()Close()做同样的事情,你不需要同时打电话。Close()只需拨打Dispose() - - MS包含一个名为Close()的方法,因为这是人们习惯使用文件API,但.NET IDisposable接口使用名为Dispose()的方法

(另一方面说明:从.NET 4.5开始,许多流类都有一个额外的构造函数,它有一个新的" leaveOpen"参数...传递true会告诉该流到不自动处理原始流