Why am I not getting the text from my file with this code?

104 views Asked by At

I am trying to load all my "error log files" into one (hopefully not gigantic) string, and then assign that string to a Multiline textBox:

private void PopulateTextBox()
{
    const string errLogDir = "\\ErrorLog";
    Directory.CreateDirectory(errLogDir);
    StringBuilder sb = new StringBuilder();
    DirectoryInfo di = new DirectoryInfo(errLogDir);
    FileInfo[] files = di.GetFiles("*.txt");
    foreach (FileInfo fi in files)
    {
        sb.AppendLine(String.Format("*** {0} ***", fi.FullName));
        using (StreamReader sr = new StreamReader(fi.FullName))
        {
            String line;
            while ((line = sr.ReadLine()) != null)
            {
                sb.AppendLine(line);
            }
        }
        sb.AppendLine(String.Empty);
    }

    string errLogContents = sb.ToString();
    MessageBox.Show(String.Format("errLogContents is {0}", errLogContents));
    textBoxErrLogsContents.Text = sb.ToString();
}

There is one file (named "ExceptionLog_2.11.2009.txt"), with some text data, in the \ErrorLog directory directly below the .exe directory (files are created programatically when exceptions occur).

So why am I seeing an empty string in the MessageBox.Show() and nothing is in textBoxErrLogsContents?

UPDATE

Virtually the same code works in a VS 2013 "Sandbox" app, with just a different directory name, file type, and textBox name:

const string errLogDir = @"C:\MiscInWindows7";
Directory.CreateDirectory(errLogDir);
StringBuilder sb = new StringBuilder();
DirectoryInfo di = new DirectoryInfo(errLogDir);
FileInfo[] files = di.GetFiles("*.xml");
foreach (FileInfo fi in files)
{
    sb.AppendLine(String.Format("*** {0} ***", fi.FullName));
    using (StreamReader sr = new StreamReader(fi.FullName))
    {
        String line;
        while ((line = sr.ReadLine()) != null)
        {
            sb.AppendLine(line);
        }
    }
    sb.AppendLine(String.Empty);
}

string errLogContents = sb.ToString();
MessageBox.Show(String.Format("errLogContents is {0}", errLogContents));
textBox7.Text = sb.ToString();

UPDATE 2

ctacke whammed the spike on the noggin re: my not providing the full path. This works:

private void PopulateTextBox()
{
    String logDirPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().GetName().CodeBase);
    String fullPath = logDirPath + "\\ErrorLog";
    StringBuilder sb = new StringBuilder();
    DirectoryInfo di;

    if (!Directory.Exists(fullPath))
    {
        di = Directory.CreateDirectory(fullPath);
    }
    else
    {
        di = new DirectoryInfo(fullPath);
    }

    FileInfo[] files = di.GetFiles("*.err");
    foreach (FileInfo fi in files)
    {
        sb.AppendLine(String.Format("*** {0} ***", fi.FullName));
        using (StreamReader sr = new StreamReader(fi.FullName))
        {
            String line;
            while ((line = sr.ReadLine()) != null)
            {
                sb.AppendLine(line);
            }
        }
        sb.AppendLine(String.Empty);
    }
    textBoxErrLogsContents.Text = sb.ToString();
}
2

There are 2 answers

0
ctacke On BEST ANSWER

First, calling CreateDirectory in all cases is a bad idea. It's confusing. Instead, check to see if the directory exists, and if it doesn't then create it and exit the function (because if you created it, you know there's no data). This would have found your error much faster and also prevented @Jim Mischel's (and everyone else's) confusion.

The problem with your code is actually rooted in one of your comments. You say the file, as seen from your PC with WMDC, is at Computer\WindowsCE\Program Files\HHS\ErrorLog. On the device itself that equates to \Program Files\HHS\ErrorLog not just \ErrorLog. Remember, there are no relative paths on Windows CE devices.

3
Jim Mischel On

This doesn't make any sense:

const string errLogDir = "\\ErrorLog";
Directory.CreateDirectory(errLogDir);
StringBuilder sb = new StringBuilder();
DirectoryInfo di = new DirectoryInfo(errLogDir);
FileInfo[] files = di.GetFiles("*.txt");

So you're creating a new directory, and then trying to read files from it. In this case, you're creating the directory at the root (i.e. "C:\ErrorLog", if the drive of the current working directory is C:).

If the directory you asked to create already exists, CreateDirectory just returns the DirectoryInfo object. But if you create a new directory and then try to get files from it, it's pretty likely that there will be no files at all because you just created an empty directory.

It's likely that you wanted that to be

const string errorLogDir = "ErrorLog";

That will cause the directory to be created as a subdirectory of the current working directory.

By the way, there's no readon to have:

Directory.CreateDirectory(errLogDir);
DirectoryInfo di = new DirectoryInfo(errLogDir);

CreateDirectory returns a DirectoryInfo object. So you can write:

DirectoryInfo di = new DirectoryInfo(errLogDir);

Now, it's quite possible that the EXE directory is not the same as the current working directory. If you want to get the information from the EXE's subdirectory, then you have to explicitly say so:

string fullName = Assembly.GetEntryAssembly().Location;
string exeDirectory = Path.GetDirectoryName(fullName);
string fullErrLogDir = Path.Combine(exeDirectory, errLogDir);
DirectoryInfo di = Directory.CreateDirectory(fullErrLogDir);

Finally, you can replace all of this code:

using (StreamReader sr = new StreamReader(fi.FullName))
{
    String line;
    while ((line = sr.ReadLine()) != null)
    {
        sb.AppendLine(line);
    }
}

With a single line:

sb.AppendLine(File.ReadAllText(fi.FullName));