2014-09-15 8 views
1

Я делаю журнал для своей программы, используя 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, все это я получаю пустой файл --no текст внутри. Его код выглядит так:

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

ваш последний пример не 'closeLog' .. – Sayse

+2

Вы думали об использовании что-то надежное и широко используется как Log4Net а не изобретать колесо. –

+0

попробуйте включить AutoFlush, как это. fs = новый StreamWriter (путь) {AutoFlush = true}; –

ответ

3

Я бы переписал ваш класс журнала, чтобы избежать близости.
Просто откройте, писать и закрыть после окончания части

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

записи Таким образом, используя оператор закрывает поток, и вам не придется беспокоиться о закрытии. Действительно, закрытие потока может быть очень неприятным, если в вашем коде произойдет что-то неожиданное. (Как исключение, изменяющее поток кода).

Это всего лишь отправная точка для проверки и проверки кода, но вы можете добавить более сложную логику, следуя приведенному шаблону. Например, вы можете добавить конструктор с флагом для добавления метки времени для каждой строки (или флаг для добавления разделительной строки или флаг для воссоздания файла, если он существует).)

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

+3

'File.AppendAllText()' не нужно изобретать колесо. – leppie

+0

@leppie Вы правы, конечно. Причина для StreamWriter не очевидна из этого контекста, иногда мне нужно убить и воссоздать журнал. – Steve

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, потому что это не нужно.

EDIT:

Лучшая идея заключается в том, чтобы просто использовать стандартные методы апатридов (как указано на @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);   
} 
+0

1. Вы (и я) сделали предположение, что последний пример является полным примером и двумя. Операция не переписывает ничего, что казалось бы – Sayse

+0

Закрытие журнала исправило это; благодаря! Я не могу поверить, что сам этого не видел. Я не слишком беспокоюсь о перезаписи файла - указанный путь был предназначен только для тестирования; Я совершенно уверен, что я собираюсь получить другой путь назначения каждый раз, когда вызывается весь метод. – senschen

+0

Вместо того, чтобы просто отрываться от ответов других народов, вы должны попытаться должным образом оценить их. – Sayse

Смежные вопросы