C#PathTooLongException

C#PathTooLongException,c#,C#,我正在为我的一个C班做作业。我需要使用visual studio 2012制作一个程序,该程序打开并读取文本文件,报告垃圾邮件单词的数量以及邮件为垃圾邮件的概率。我想我记下了代码,但打开文件时出现异常: mscorlib.dll中发生类型为“System.IO.PathTooLongException”的未处理异常 其他信息:指定的路径、文件名或两者都太长。完全限定文件名必须少于260个字符,目录名必须少于248个字符 此外,文件名(包含文件本身的内容)除了文本本身之外,还包含路径名C:\Spa

我正在为我的一个C班做作业。我需要使用visual studio 2012制作一个程序,该程序打开并读取文本文件,报告垃圾邮件单词的数量以及邮件为垃圾邮件的概率。我想我记下了代码,但打开文件时出现异常:

mscorlib.dll中发生类型为“System.IO.PathTooLongException”的未处理异常

其他信息:指定的路径、文件名或两者都太长。完全限定文件名必须少于260个字符,目录名必须少于248个字符

此外,文件名(包含文件本身的内容)除了文本本身之外,还包含路径名C:\Spam message.txt,而文本本身不应该包含。我想弄明白这一点,基本上是碰了一鼻子灰

这是第一节课的主要方法

public void ScanMessage(string filename)
    {
        spamCount = 0;
        spamProbability = 0.0;

        StreamReader fileReader;
        FileStream input = new FileStream(filename, FileMode.Open, FileAccess.Read); //This is where the exception is pointing to.
        fileReader = new StreamReader(input);
        messageRead = fileReader.ReadLine();

        while (messageRead != null)
        {
            messageRead = fileReader.ReadLine();
        }
        //Converts message to lowercase
        filename.ToLower();

        //For each word in spam phrases, look through the message. If a spam phrase is found,
        //increment spamCount and add it to the sorteddictionary, or adds an entry to the
        //sortedDictionary if it already exists
        foreach (var word in spamPhrases)
        {
            if (filename.IndexOf(word) != -1)
            {
                spamCount++;
                messageSpamPhrases.Add(word, 1);
            }

           /* else
            {
                ++messageSpamPhrases[word];
            }*/
        }

        spamProbability = spamCount / 30.0 * 100.0;

        //This is for the list of spam phrases found
        phrasesFound = new String[messageSpamPhrases.Count() + 1];
        phrasesFound[0] = string.Format("{0,-22}{1,-12}\n", "Phrase", "Count");
        int x = 1;

        foreach (String key in messageSpamPhrases.Keys)
        {
            phrasesFound[x++] = String.Format("{0,-25} {1,-25}", key, messageSpamPhrases[key]);
        }

        //The message of probability of spam
        spamResult = String.Format("This message has a {0}% chance of being a spam message", spamProbability);

        input.Close();
以及通过表单中的按钮对其进行分析的方法

private void analyzeBtn(object sender, EventArgs e)
    {
        OpenFileDialog fileChooser = new OpenFileDialog();

        fileChooser.InitialDirectory = "c:\\";

        fileChooser.Filter = "txt files (*.txt)|*.txt";
        fileChooser.FilterIndex = 2;
        fileChooser.RestoreDirectory = true;
        //fileChooser.Multiselect = false;

        DialogResult result = fileChooser.ShowDialog();

        if (result == DialogResult.OK)
        {

            string filename = fileChooser.FileName;

            //result = fileChooser.ShowDialog();
            StreamReader fileReader = new StreamReader(filename);

            while (filename != null)
            {
                textBox1.Text += filename;
                filename = fileReader.ReadLine();
            }
        }
        //textBox1.Text = filename;
        spam.ScanMessage(textBox1.Text);
        textBox1.Show();
        listBox1.BeginUpdate();
        foreach (var element in spam.PhrasesFound)
        {
            listBox1.Items.Add(element);
        }
        listBox1.EndUpdate();

        label2.Text = spam.spamResult;

        listBox1.Show();              
    }
我真正需要的唯一帮助是弄清楚为什么会发生这种错误。有什么建议吗

当路径或文件名超过系统定义的最大长度时引发的异常

-

在Windows API中(以下段落讨论了一些例外情况),路径的最大长度是MAX_path,定义为260个字符。本地路径按以下顺序构造:驱动器号、冒号、反斜杠、由反斜杠分隔的组件和终止的空字符

-

如果代码没有权限,则此异常的错误消息可能只包含文件或目录名,而不包含完整路径

-

完整路径不得超过260个字符,以保持与Windows操作系统的兼容性。有关此限制的更多信息,请参阅BCL团队博客中的条目

罪魁祸首在这里:

您正在将正在读取的文本添加到文件名,因此。文件名将变大(除此之外,它可能包含无效字符)

在这篇文章中:

        while (filename != null)
        {
            textBox1.Text += filename;
            filename = fileReader.ReadLine();
        }
    }
    //textBox1.Text = filename;
    spam.ScanMessage(textBox1.Text);
由于
+=
,文件中的所有内容都会填充
textBox1.Text的值。可以是数百/数千个字符

然后,执行一个
spam.ScanMessage(textBox1.Text)
(可能包含数千个字符)。
在ScanMessage方法中,您尝试在第4条语句中打开具有该路径的文件。这溢出了


帮自己一个忙:学习如何调试。不要太苛刻,也不要太尖刻,但这确实会让你的生活更轻松。

好的,根据你最近的评论,我给了你一个机会:

DialogResult result = fileChooser.ShowDialog();

if (result == DialogResult.OK)
{
    string filename = fileChooser.FileName;
    spam.ScanMessage(filename);
    //...
}
以及:


这可能还没有完全启动它,因为您的部分代码丢失了。不过这会让你走得更远。

为什么会这样?它在告诉你。你的路太长了。您可能没有打开您认为要打开的文件。断点并检查您的逻辑是否打开了正确的文件。是的,异常非常清楚。您是否验证了包括目录在内的完整路径少于260个字符?请在
新文件流上设置断点(filename,…
行,并在监视窗口中显示调试器的
filename
截图。检查您的“filename”。它可能包含260多个字符。好的,这修复了该异常,但现在出现另一个错误,称路径中的字符非法。@MichaelShonsey您想扫描文件本身还是文件包含要扫描的文件的路径?如果是第一个,那么为什么不调用
ScanMessage(..,fileChooser.FileName)
-您还不清楚自己想要实现什么目标。我正在尝试扫描文件本身。只扫描包含消息的1.txt文件。如果我听起来像个白痴,我也很抱歉。很遗憾,这是我第一次使用打开文件和其他编码方式。我"我只是不确定我是否一直在把事情搞砸。@MichaelShonsey继续,一开始有点困难,我们都经历过。你的代码不错,但肯定需要一些改进,这就是为什么你会有一些未定义的行为。试着从令人愉快的网站上看看:创造奇迹般的东西在你的电脑上做事情!祝你的班级好运,不要因为你的得票率下降而退缩提问。SO社区有时会在标准上有点高:)。很快你就会成为回答问题的人!这似乎就做到了。只需再添加一些内容(主要是让一些标签可见).另外,谢谢你能容忍我。如果答案很明显而我没有看到,我道歉。
        while (filename != null)
        {
            textBox1.Text += filename;
            filename = fileReader.ReadLine();
        }
    }
    //textBox1.Text = filename;
    spam.ScanMessage(textBox1.Text);
DialogResult result = fileChooser.ShowDialog();

if (result == DialogResult.OK)
{
    string filename = fileChooser.FileName;
    spam.ScanMessage(filename);
    //...
}
public void ScanMessage(string filename)
{
    spamCount = 0;
    spamProbability = 0.0;

    var messageRead="";
    using(var input = new StreamReader(filename))
    {
        messageRead = input.ReadToEnd();
    }
    //Converts message to lowercase
    messageRead = messageRead.ToLower();

    //For each word in spam phrases, look through the message. If a spam phrase is found,
    //increment spamCount and add it to the sorteddictionary, or adds an entry to the
    //sortedDictionary if it already exists
    foreach (var word in spamPhrases)
    {
        if (messageRead.Contains(word))
        {
            spamCount++;
            messageSpamPhrases.Add(word, 1);
        }
    }

    spamProbability = spamCount / 30.0 * 100.0;

    //This is for the list of spam phrases found
    phrasesFound = new String[messageSpamPhrases.Count() + 1];
    phrasesFound[0] = string.Format("{0,-22}{1,-12}\n", "Phrase", "Count");
    int x = 1;

    foreach (String key in messageSpamPhrases.Keys)
    {
        phrasesFound[x++] = String.Format("{0,-25} {1,-25}", key, messageSpamPhrases[key]);
    }

    //The message of probability of spam
    spamResult = String.Format("This message has a {0}% chance of being a spam message", spamProbability);
}