简体   繁体   English

为什么我的StreamWriter无法写入文件?

[英]Why does my StreamWriter not write to file?

I'm making a log for my program using a StreamWriter to write to a file. 我正在使用StreamWriter为我的程序创建日志以写入文件。 I have some code that looks like it works, but its only doing part of what it should. 我有一些看起来像它可以工作的代码,但是它只是在做应做的事情。

I made a simple class called Log (code below). 我做了一个叫做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();

}
}

I made a simple test program that works perfectly. 我做了一个简单的测试程序,可以很好地工作。 It executes these three lines: 它执行以下三行:

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

But in my much larger program, where I actually want to use the Log class, all I get is an empty file --no text inside. 但是在我实际上要使用Log类的更大的程序中,我得到的只是一个空文件-里面没有文本。 Its code looks like this: 其代码如下所示:

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);

Can anyone tell me why the program version of this code isn't working? 谁能告诉我为什么此代码的程序版本不起作用?

I would rewrite your Log class to avoid the close part. 我将重写您的Log类,以避免接近部分。
Just open, write and close after finishing the write part 完成写入部分后,只需打开,写入和关闭

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);
        }
    }
}

In this way the using statement will close the stream and you don't have to worry about closing it. 这样,using语句将关闭流,而您不必担心关闭流。 Indeed closing the stream could be very troublesome if something unexpected happens in your code. 实际上,如果代码中发生意外,关闭流可能会非常麻烦。 (Like an exception that change your code flow). (就像改变代码流的异常一样)。

This is just a starting point to have the code tested and verified, but you could add some more complex logic following the pattern given. 这只是测试和验证代码的起点,但是您可以按照给定的模式添加一些更复杂的逻辑。 For example you could add a constructor with a flag to add a timestamp for everyline (or a flag to add a separator line, or a flag to recreate the file if exists...) 例如,您可以添加一个带有标志的构造函数,以为每行添加一个时间戳(或一个标志,以添加分隔线,或者如果存在的话,可以使用一个标志来重新创建文件...)

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);
        }
    }
}

FINALLY: Keep in mind that specialized log libraries exists well tested and free to use. 最后一点:请记住,专门的日志库已经过测试,可以免费使用。 Perhaps you could invest some of your time in learning them 也许您可以投入一些时间来学习它们

Log4Net Log4Net
NLog 日志

1. You do not close the stream in the second example - and what will happen on garbage collection I am not sure. 1.在第二个示例中,您不会关闭流-而且我不确定在垃圾回收时会发生什么。 Call the l.closeLog(); 调用l.closeLog(); in the end to at least get some output. 最终至少得到一些输出。 But it is not a good idea. 但这不是一个好主意。 What will happen if some method throws between l.write(); 如果在l.write();之间抛出某种方法会发生什么? and l.closeLog; l.closeLog; . Something not good - file will left opened till GC deals with it. 不好的地方-文件将一直打开,直到GC处理为止。

2. You overwrite the file with each call. 2.您每次调用都覆盖文件。 Probably what you need is to append the data - http://msdn.microsoft.com/en-us/library/3zc0w663(v=vs.110).aspx or even better change your code to use File.AppendText method: 可能您需要添加数据-http : //msdn.microsoft.com/zh-cn/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);
    }   
}

And remove the closeLog method, because it is unnecessary. 并删除closeLog方法,因为它是不必要的。

EDIT: 编辑:

The best idea is to just use stateless standard methods(as pointed by @leppie), that won't leak any resources: 最好的想法是只使用无状态的标准方法(如@leppie所指出的),该方法不会泄漏任何资源:

It is File.WriteAllText if you create one logfile for each log instance: 如果为每个日志实例创建一个日志文件,则为File.WriteAllText

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

or File.AppendAllText if you need to continue already existing logs: File.AppendAllText,如果您需要继续已有的日志:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM