为什么我的StreamWriter没有写入文件?

时间:2014-09-15 14:30:46

标签: c# logging streamwriter

我正在使用StreamWriter为我的程序创建日志以写入文件。我有一些看似有效的代码,但它只做它应该做的部分。

我创建了一个名为Log的简单类(下面的代码)。

public class Log
{
string path;
StreamWriter fs;
public Log(string fullPathToLogFile)
{
    path = fullPathToLogFile;
    fs = new StreamWriter(path);
    writeLog("Starting log");
}
public void writeLog(string s)
{
    fs.WriteLine(DateTime.Now.ToString("dd-MM-yyyy  H:mm:ss         ") + s);
}
public void closeLog()
{
    writeLog("Closing log");
    fs.WriteLine(); //add a blank line at the end
    fs.Close();

}
}

我制作了一个完美的测试程序。它执行以下三行:

Log l = new Log(@"C:\Users\SADunkerton\Desktop\l.txt");
l.writeLog("testing log");
l.closeLog();

但是在我更大的程序中,我实际上想要使用Log类,我得到的只是一个空文件 - 里面没有文本。它的代码如下:

Log log = new Log(folderPDFs + @"\Log.txt"); //folderPDFs is a parameter of this method--it is a string that is a complete path to a destination folder.
log.writeLog("Beginning conversions");
//do some stuff, including write to the log
log.writeLog("Finished converting.  Success = " + success);

有谁能告诉我为什么这段代码的程序版本不起作用?

2 个答案:

答案 0 :(得分:3)

我会重写你的Log类以避免关闭部分 完成写入部分后,只需打开,写入和关闭

class MySimpleLog
{
    private string _filename;
    public MySimpleLog(string filename)
    {
        _filename = filename;
    }

    public void AppendText(string msg)
    {
        // Create an instance of StreamWriter to write text to a file.
        // The using statement also closes the StreamWriter.
        using (StreamWriter sw = new StreamWriter(_filename, true))
        {
            // Add some text to the file.
            sw.WriteLine(msg);
        }
    }
}

通过这种方式,using语句将关闭流,您不必担心关闭它。实际上,如果代码中出现意外情况,关闭流可能非常麻烦。 (就像更改代码流的异常一样)。

这只是测试和验证代码的起点,但您可以按照给定的模式添加一些更复杂的逻辑。例如,你可以添加一个带有标志的构造函数来为每一行添加一个时间戳(或者添加一个分隔线的标志,或者如果存在则重新创建文件的标志......)

class MySimpleLog
{
    private string _filename;
    private bool _addtime;
    public MySimpleLog(string filename)
    {
        _filename = filename;
    }
    public MySimpleLog(string filename, bool addtime)
    {
        _filename = filename;
        _addtime = addtime;
    }

    public void AppendText(string msg)
    {
        // Create an instance of StreamWriter to write text to a file.
        // The using statement also closes the StreamWriter.
        using (StreamWriter sw = new StreamWriter(_filename, true))
        {
            // Add some text to the file.
            msg = (_addtime ? DateTime.Now.ToString() + ": " + msg : msg);
            sw.WriteLine(msg);
        }
    }
}

最后:请记住,专门的日志库存在经过良好测试且可以免费使用。也许你可以投入一些时间来学习它们

<强> Log4Net
NLog

答案 1 :(得分:1)

1。你没有在第二个例子中关闭流 - 以及垃圾收集会发生什么我不确定。最后调用l.closeLog();至少得到一些输出。但这不是一个好主意。如果某个方法在l.write();l.closeLog;之间抛出,会发生什么。不太好的事情 - 文件将在GC处理之前保持打开状态。

2。您在每次通话时都会覆盖该文件。您可能需要的是附加数据 - http://msdn.microsoft.com/en-us/library/3zc0w663(v=vs.110).aspx甚至更好地更改您的代码以使用File.AppendText方法:

 public void writeLog(string s)
 {
    using (StreamWriter sw = File.AppendText(path)) 
    {
        sw.WriteLine(DateTime.Now.ToString("dd-MM-yyyy  H:mm:ss         ") + s);
    }   
}

并删除closeLog方法,因为这是不必要的。

修改

最好的想法是使用无状态标准方法(如@leppie所指出的),不会泄漏任何资源:

如果为每个日志实例创建一个日志文件,则为File.WriteAllText

 public void writeLog(string s)
 {
     File.WriteAllText(path,
         DateTime.Now.ToString("dd-MM-yyyy  H:mm:ss         ") + s);        
 }

File.AppendAllText如果您需要继续现有日志:

 public void writeLog(string s)
 {
     File.AppendAllText(path,
         DateTime.Now.ToString("dd-MM-yyyy  H:mm:ss         ") + s);        
 }