【问题标题】:Why am I not getting the text from my file with this code?为什么我没有使用此代码从我的文件中获取文本?
【发布时间】:2014-11-24 23:14:56
【问题描述】:

我正在尝试将我所有的“错误日志文件”加载到一个(希望不是巨大的)字符串中,然后将该字符串分配给多行文本框:

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

在 .exe 目录正下方的 \ErrorLog 目录中有一个文件(名为“ExceptionLog_2.11.2009.txt”),其中包含一些文本数据(文件是在发生异常时以编程方式创建的)。

那么为什么我在 MessageBox.Show() 中看到一个空字符串,而 textBoxErrLogsContents 中没有任何内容?

更新

几乎相同的代码在 VS 2013“沙盒”应用程序中工作,只是目录名称、文件类型和文本框名称不同:

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

更新 2

ctacke 重击了 noggin 上的尖峰:我没有提供完整的路径。这有效:

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

【问题讨论】:

  • 为什么投反对票?我犯了明显的错误吗?如果是这样,是什么?无声的投票没有帮助,而且还有些懦弱。
  • 目标文件中是否有换行符?一种情况是ReadLine 不返回任何内容,因为目标文件中没有新行。我也不喜欢 while 逻辑,因为它不是超级可读的。将其分成两条明显的行,其中 line = sr.Readline()while 条件。聪明你一无所获,清晰则一无所获。
  • 另外,文本格式是什么(ASCII 或 Unicode)?这也可能对行为产生影响。
  • 您可以将整个 StreamReaderwhile 循环替换为:sb.AppendLine(File.ReadAllText(fi.FullName))
  • 在另一条评论中,您说该文件位于“Computer\WindowsCE\Program Files\HHS\ErrorLog”。在将是\Program Files\HHS\ErrorLog 只是\ErrorLog 的设备上。这大概就是问题的根源吧。请记住,设备上没有相对路径。

标签: c# windows-ce streamreader fileinfo directoryinfo


【解决方案1】:

这没有任何意义:

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

所以您正在创建一个新目录,然后尝试从中读取文件。在这种情况下,您在根目录创建目录(即“C:\ErrorLog”,如果当前工作目录的驱动器是 C:)。

如果您要求创建的目录已经存在,CreateDirectory 只会返回 DirectoryInfo 对象。但是如果你创建一个新目录然后尝试从中获取文件,很可能根本没有文件,因为你只是创建了一个空目录。

您可能希望这样

const string errorLogDir = "ErrorLog";

这将导致该目录被创建为当前工作目录的子目录。

顺便说一句,没有读过:

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

CreateDirectory 返回一个DirectoryInfo 对象。所以你可以写:

DirectoryInfo di = new DirectoryInfo(errLogDir);

现在,EXE 目录很可能与当前工作目录不同。如果要从 EXE 的子目录中获取信息,则必须明确说明:

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

最后,您可以替换所有这些代码:

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

单行:

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

【讨论】:

  • 糟糕,我将 cmets 添加到另一个答案而不是此处。但至于摆脱“CreateDirectory”调用,在它出现之前(我忘了以这种方式以编程方式创建它),我得到:“System.IO.DirectoryNotFoundException: DirectoryNotFoundException”事实上,这是两者之一我试图从应用程序中打开的文件中的异常消息。
  • GetEntryAssembly 在 CE 中显然不可用。 ReadAllText() 也是如此
  • 如果您收到“找不到目录”,那么肯定有问题。你应该做一个if !Directory.Exists(..),如果它不存在则创建它并退出。
【解决方案2】:

首先,在所有情况下都调用CreateDirectory 是个坏主意。这很令人困惑。相反,检查目录是否存在,如果不存在则创建它并退出函数(因为如果你创建了它,你就知道没有数据)。这样可以更快地发现您的错误,并且还可以防止@Jim Mischel(以及其他所有人)的困惑。

您的代码问题实际上源于您的一个 cmets。您说从您的带有 WMDC 的 PC 上看到的文件位于 Computer\WindowsCE\Program Files\HHS\ErrorLog。在设备本身上相当于\Program Files\HHS\ErrorLog只是\ErrorLog。请记住,Windows CE 设备上没有相对路径。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-10-01
    • 1970-01-01
    • 2011-01-17
    • 1970-01-01
    • 2019-11-09
    • 2022-01-10
    • 1970-01-01
    • 2020-10-07
    相关资源
    最近更新 更多