【问题标题】:How to read a text file for a specific word in lines and write the entire lines to another text file?如何逐行读取特定单词的文本文件并将整行写入另一个文本文件?
【发布时间】:2014-03-03 06:46:18
【问题描述】:

我有一个包含以下行的文本文件(比如 text1.txt):

4410 Rel testRel1
4411 Dbg testDbg1
4412 Dbg testDbg2
4412 Rel testRel2
4413 Rel testRel3
4413 Dbg testDbg3
4414 Rel testRel4
4415 Rel testRel5

现在,我想将所有带有单词“Rel”的行写入一个文本文件(比如 text2.txt)。所以我的 text2.txt 应该是这样的:

4410 Rel testRel1
4412 Rel testRel2
4413 Rel testRel3
4414 Rel testRel4
4415 Rel testRel5

最后,我的代码应该读取 text2.txt 返回 text2.txt(即 4415)最后一行的前四个字符,以 text1.txt 的路径作为输入。 下面是我的代码。可能我已经写了一半,但对 c# 毫无概念。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Activities;
using Microsoft.Build.Utilities;
using Microsoft.Build.Framework;
using System.IO;
using Microsoft.TeamFoundation.Build.Client;

namespace Build_Tasks.Activities
{
    [BuildActivity(HostEnvironmentOption.All)]
    public sealed class GetBuildNumber : CodeActivity
    {
        // Define an activity input argument of type string
        public InArgument<string> TextFileName { get; set; }
        public OutArgument<string> setBuildNumber { get; set; }
        private string temp_FilePath = "c:\\temp.txt";

        // If your activity returns a value, derive from CodeActivity<TResult>
        // and return the value from the Execute method.
        protected override void Execute(CodeActivityContext context)
        {
            // Obtain the runtime value of the Text input argument
            string TextFileName = context.GetValue(this.TextFileName);
            string TextFilePath = TextFileName;
            string[] Lines = File.ReadAllLines(TextFilePath);
            //string wordrel = "Rel";
            System.IO.StreamReader file = new System.IO.StreamReader(TextFilePath);
            List<string> Spec = new List<string>();
            string line;
            System.IO.StreamWriter file2 = new System.IO.StreamWriter(temp_FilePath);
            while ((line = file.ReadLine()) != null)
            {
                if(line.Contains("Rel"))
                     {
                        file2.WriteLine(line);
                      }
            }
            var lastline = File.ReadLines(temp_FilePath).Last();
            string number = lastline.Substring(0, 4);
            context.SetValue<string>(this.setBuildNumber, number);
            }
    }
    }

【问题讨论】:

  • 如果有任何其他方法,比如将行读取到数组而不是 text2.txt,即使这样也有帮助。我的 text2.txt 是用于实现上述指定的临时文件。
  • 您不必创建 file2.txt 也不必将行存储在数组中,只是为了获得我在回答中指出的内部版本号。

标签: c# c#-4.0


【解决方案1】:

试试这个……

    static void Main(string[] args)
    {
        int counter = 0;
        string line;

        // Read the file(your SXA file) and display it line by line.
        System.IO.StreamReader file = new System.IO.StreamReader("c:\\SXA63.txt");
        while((line = file.ReadLine()) != null)
         {         //File to write lines which contain Rel. 
                   using(StreamWriter writer = new StreamWriter("c:\\Relfile.txt",true))
                    {
                       if(line.Contains("Rel"))
                      writer.WriteLine(line);
                    }
            counter++;

        }
        String last = File.ReadLines(@"C:\Relfile.txt").Last();
        string buildNo = last.Substring(0, 4);
        file.Close();
        Console.ReadKey();

    }
}

【讨论】:

    【解决方案2】:

    如果您只需要 file2 获取内部版本号,则根本不必创建它:

    protected override void Execute(CodeActivityContext context)
    {
        // Obtain the runtime value of the Text input argument
        string TextFileName = context.GetValue(this.TextFileName);
        string TextFilePath = TextFileName;
    
        string number = null;
        var splitChars = new[]{ ' ' };
    
        foreach (var line in File.ReadLines(TextFilePath))
        {
            var values = line.Split(splitChars, StringSplitOptions.RemoveEmptyEntries).ToArray();
            if (values.Length < 3)
                continue;
    
            buildNumber = (values[1] == "Rel" ? values[0] : buildNumber);
        }
    
        context.SetValue<string>(this.setBuildNumber, number);        
    }
    

    并且由于您只对 last 内部版本号感兴趣,因此可以通过不从头读取文件而是寻找流到末尾并跳回直到找到该行来进一步优化Rel

    【讨论】:

    • 你是说优化部分?
    • 我得到这个错误:索引超出了数组的范围
    • 是的,优化部分也需要帮助
    • 我修改了代码以处理格式错误/不感兴趣的行。
    • 我得到了这段代码的帮助。非常感谢。尝试优化部分。如果我没有找到,我会提出一个问题。
    【解决方案3】:

    这将遍历原始文件的行并将相关行复制到新文件:

    string tempFile = "text2.txt";
    List<string> linesWithREL = new List<string>();
    using (var sr = new StreamReader("file.txt"))
    using (var sw = new StreamWriter(tempFile))
    {
        string line;
    
        while ((line = sr.ReadLine()) != null)
        {
            //check if the current line should be copied
            if (line.Contains("whatever"))
            {
                   linesWithREL.Add(line.Substring(0,4));
                   sw.WriteLine(line);
            }
        }
    }
    

    【讨论】:

      【解决方案4】:

      试试这个:

      string path1 = @"C:\data1.txt";
      string path2 = @"C:\data2.txt";
      string searchKey = "Rel";
      List<string> newlines = new List<string>();
      foreach (var line in File.ReadLines(path1))
      {
      if (line.Split(new char[]{' '},
               StringSplitOptions.RemoveEmptyEntries)[1].Contains(searchKey))
      {
      newlines.Add(line);
      }
      }
      File.WriteAllLines(path2,newlines.ToArray());
      

      【讨论】:

      • 我可以将这些行写入另一个文件。但我的第二个问题是我面临的问题。(阅读最后一行的前四个字符)
      • @Bala 您必须先关闭阅读器才能使用不同的方法访问相同的文件。
      【解决方案5】:

      好的,所以当我阅读一些 cmets 时,您的问题不在于读/写,而在于这一行:

      var lastline = File.ReadLines(temp_FilePath).Last();
      

      在对同一文件使用File.ReadLine 之前,您必须先关闭您的编写器。

      file2.Flush();
      file2.Close();
      var lastline = File.ReadLines(temp_FilePath).Last();
      

      如果你想优化你的代码,已经添加了几个答案,无需重复。

      【讨论】:

        猜你喜欢
        • 2016-08-14
        • 1970-01-01
        • 2012-10-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-12-29
        相关资源
        最近更新 更多