【问题标题】:reading/writing to txt file in C#在 C# 中读取/写入 txt 文件
【发布时间】:2013-11-13 05:02:06
【问题描述】:

这里是初学者

我很难理解如何在 c# 中编辑 txt 文件的内容。我正在尝试执行以下-伪代码:

foreach word in file.txt
        if ((word.length < 4) || (word.length > 11))
                        delete word from file.txt

我需要做什么?我知道它涉及流读取器/写入器类,但我不明白它们是如何工作的。

【问题讨论】:

标签: c# streamreader streamwriter


【解决方案1】:

乍一看,这似乎很简单,使用 StreamReader 读取文件,在空间上拆分,然后删除不符合长度标准的单词。然后使用 StreamWriter 将结果写回。但是,使用字符串解析(单词解析)时,您会遇到一些可能需要额外处理的“特殊”情况。

语言很难用编程语言来描述。例如,一个单词可能包含作为单词一部分的标点符号,或者它可能以表示句子结尾、换行符等的标点符号开头\结尾。

话虽如此,我们可以说我们有以下规则。

  • 单词包含一个或多个字母数字字符
  • 一个词可能包含以下标点符号。 [-,_']
  • 单词可以用标点符号或空格分隔。

按照这些规则,我们可以轻松阅读所有文本并执行您要求的操作。我会先从文字处理开始。你可以做的是为此创建一个静态类。让我们调用这个类WordProcessor

这是根据我们的规则从字符串中解析单词的注释代码。

/// <summary>
/// characters that denote a new word
/// </summary>
const string wordSplitPuncuation = ",.!&()[] \"";

/// <summary>
/// Parse a string
/// </summary>
/// <param name="inputString">the string to parse</param>
/// <param name="preservePuncuation">preserve punctuation in the string</param>
/// <returns></returns>
public static IList<string> ParseString(string inputString, bool preservePuncuation)
{
    //create a list to hold our words
    List<string> rebuildWords = new List<string>();

    //the current word
    string currentWord = "";

    //iterate through all characters in a word
    foreach(var character in inputString)
    {
        //is the character is part of the split characters 
        if(wordSplitPuncuation.IndexOf(character) > -1)
        {
            if (currentWord != "")
                rebuildWords.Add(currentWord);
            if (preservePuncuation)
                rebuildWords.Add("" + character);
            currentWord = "";
        }
        //else add the word to the current word
        else
            currentWord += character;
    }
    return rebuildWords;
}

现在上面是非常基本的,如果你将保留标点设置为 true,你会得到相同的字符串。

该类的下一部分实际上将用于删除小于特定长度或大于特定长度的单词。这使用上面的方法将单词拆分为多个片段,并根据变量单独评估每个片段。

/// <summary>
/// Removes words from a string that are greater or less than the supplied lengths
/// </summary>
/// <param name="inputString">the input string to parse</param>
/// <param name="preservePuncuation">flag to preserve the puncation for rebuilding the string</param>
/// <param name="minWordLength">the minimum word length</param>
/// <param name="maxWordLength">the maximum word length</param>
/// <returns></returns>
public static string RemoveWords(string inputString, bool preservePuncuation, int minWordLength, int maxWordLength)
{
    //parse our string into pieces for iteration
    var words = WordProcessor.ParseString(inputString, preservePuncuation);

    //initialize our complete string container
    List<string> completeString = new List<string>();

    //enumerate each word
    foreach (var word in words)
    {
        //does the word index of zero matches our word split (as puncuation is one character)
        if (wordSplitPuncuation.IndexOf(word[0]) > -1)
        {
            //are we preserviing puncuation
            if (preservePuncuation)
                //add the puncuation
                completeString.Add(word);
        }
        //check that the word length is greater or equal to the min length and less than or equal to the max word length
        else if (word.Length >= minWordLength && word.Length <= maxWordLength)
            //add to the complete string list
            completeString.Add(word);
    }
    //return the completed string by joining the completed string contain together, removing all double spaces and triming the leading and ending white spaces
    return string.Join("", completeString).Replace("  ", " ").Trim();
}

好的,上面的方法简单的运行并提取符合特定条件的单词并保留标点符号。难题的最后一块是读\写文件到磁盘。为此,我们可以使用StreamReaderStreamWriter。 (请注意,如果您有文件访问问题,您可能需要查看 FileStream 类)。

现在下面的相同代码简单地读取文件,调用上面的方法,然后将文件写回原始位置。

/// <summary>
/// Removes words from a file
/// </summary>
/// <param name="filePath">the file path to parse</param>
/// <param name="preservePuncuation">flag to preserve the puncation for rebuilding the string</param>
/// <param name="minWordLength">the minimum word length</param>
/// <param name="maxWordLength">the maximum word length</param>
public static void RemoveWordsFromAFile(string filePath, bool preservePuncuation, int minWordLength, int maxWordLength)
{


    //our parsed string
    string parseString = "";

    //read the file
    using (var reader = new StreamReader(filePath))
    {
        parseString = reader.ReadToEnd();
    }

    //open a new writer
    using (var writer = new StreamWriter(filePath))
    {
        //parse our string to remove words
        parseString = WordProcessor.RemoveWords(parseString, preservePuncuation, minWordLength, maxWordLength);

        //write our string
        writer.Write(parseString);
        writer.Flush();
    }
}

现在上面的代码同样简单地打开文件,根据你的参数解析文件,然后重新写入文件。

然后可以通过简单地直接调用方法来重用它。

WordProcessor.RemoveWordsFromAFile(@"D:\test.txt", true, 4, 10);

最后一点。这绝不是处理您的请求的最有效方式,也绝不是为性能而设计的。这只是一个关于如何从文件中解析单词的演示。

干杯

【讨论】:

  • 阅读更多问题而不是屏幕上写的内容的分数。
  • 没问题.. 我希望这能回答你的问题。如果您需要其他任何东西,请不要犹豫。..
【解决方案2】:

这个概念将更接近于:

While(there is input to read from the input file)
{
read the input
if(input fits your criteria of shorter than 4 or longer than 11)
   ignore it
else
   write it to output file (which is a new file, NOT the file you read it from)
}

您可以使用streamreader.readline()

【讨论】:

  • 感谢您的回复。根本不可能覆盖原始文件吗?另外,创建流是怎么回事 - 为什么我不能只运行该方法?
  • @dreadbeat 您可以覆盖原始文件,但将其写入新文件要简单得多。请记住,这是存储在磁性介质上的信息。如果您只是“擦除”文本文件的一部分,则必须从该点读取文件的整个其余部分,然后从您擦除的位置开始重新写入。可以做到,但效果不好。创建一个新的输出文件更好更容易,当你完成后,如果你需要删除原始文件并重命名输出,你可以。此外,您必须创建要写入的流。这使磁盘准备好存储文件。
【解决方案3】:

我会根据您在问题中描述的要求研究正则表达式以进行模式匹配: 这是一个关于正则表达式的好教程。定位单词并用空格替换它们。

将其与以下有关如何读取/写入文本文件的帖子结合起来。 根据文件的大小,您可能只需阅读整个文件,删除要删除的单词,最后将整个内容写回即可。 How to both read and write a file in C#

如果文件非常大,您可能需要对其进行优化并以块的形式读取文件。

【讨论】:

    【解决方案4】:

    试试这个。

    1. Get the contents of the text file in a string variable.

    2. 用空格作为分隔符分割文本,得到一个数组中的单词。

    3. 然后加入该数组中的单词以满足您的条件写回

      到文本文件。

    【讨论】:

      【解决方案5】:
              var filePath = HttpRuntime.AppDomainAppPath + "your file path";
              if (!File.Exists(filePath))
                  return;
              using (var sr = new StreamReader(filePath))
              {
                  var text = sr.ReadToEnd();
                  if (text.Length < 4 || text.Length > 11)
                  {
                      using (var sw = new StreamWriter(filePath))
                      {
                          sw.Write("");
                      }
                  }
              }
      

      【讨论】:

      • 不确定这里发生了什么,我收到一个错误:“名称 http 运行时在当前上下文中不存在”
      • @dreadbeat 我猜你的应用程序是一个winform项目,然后删除HttpRuntime.AppDomainAppPath,使'filepath'成为绝对路径
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-07-15
      • 1970-01-01
      • 1970-01-01
      • 2021-02-06
      • 2013-03-25
      • 2023-03-22
      • 2020-03-06
      相关资源
      最近更新 更多