【问题标题】:How can i combine two text files to one text file? [closed]如何将两个文本文件合并为一个文本文件? [关闭]
【发布时间】:2017-07-02 03:43:43
【问题描述】:

第一个文本文件如下所示:

eu
alps
nl
de
sp
fr
gr
it
pl
scan

第二个文本文件如下所示:

Europe
Alps
Benelux
Germany
Spain & Portugal
France
Greece
Italy
Poland
Scandinavia

我想读取两个文本文件并以这种格式创建一个新的文本文件:

Code = eu
Country = Europe
Code = alps
Country = Alps
Code = nl
Country = Benelux

以此类推。

到目前为止,我所做的是从每个文件中读取行:但不确定如何继续。

IEnumerable f1 = File.ReadLines(@"c:\temp\txt1");
IEnumerable f2 = File.ReadLines(@"c:\temp\txt2");

【问题讨论】:

  • 你确定输入,它总是以相同的顺序吗?
  • 为什么这个问题被否决了?它似乎很切题,写得很清楚,并且显示了作者的一些努力。
  • @TannerSwett :我也想知道同样的事情,我看到一些垃圾问题,得到 6 分,还有一些好的问题被否决了。简而言之,如果您在 SE 上有朋友,那么无论您写了多少垃圾,您都会获得支持,如果没有,则您好,反对。我实际上喜欢这个问题,所以我也投了赞成票,但有时赞成或反对投票与质量无关,我在 Math SE 上也看到了同样的问题。我已经放弃尝试问你问的问题了,只是做我的一点点帮助。
  • @un-lucky : 如果可以编写一些不假设输入顺序的东西,那将比依赖它更好。
  • 所有答案都缺少编程中最重要的部分,即为手头的上下文创建有意义的结构,仅读取和操作字符串和文件流不是编程,而是黑客攻击。一个好的答案应该将值放入一个有意义的结构中。

标签: c# .net


【解决方案1】:

压缩两个文件的对应行,选择代码和国家字符串并在写入文件之前将字符串数组展平:

File.WriteAllLines(@"c:\temp\txt3",
   f1.Zip(f2, (l1,l2) => new[] { $"Code = {l1}", $"Country = {l2}" }).SelectMany(a => a));

不要忘记为f1f2 使用IEnumerable<string> 类型。您也可以生成单个字符串:

File.WriteAllLines(@"c:\temp\txt3",
   f1.Zip(f2, (l1,l2) => $"Code = {l1}{Environment.NewLine}Country = {l2}" ));

输出:

Code = eu
Country = Europe
Code = alps
Country = Alps
Code = nl
Country = Benelux
Code = de
Country = Germany
Code = sp
Country = Spain & Portugal
Code = fr
Country = France
Code = gr
Country = Greece
Code = it
Country = Italy
Code = pl
Country = Poland
Code = scan
Country = Scandinavia

= Try Me =

【讨论】:

  • Zip 相当优雅,但在这种情况下,我也认为它可能有点矫枉过正。我认为 un-lucky 的答案更简单,更中肯。
  • 我相信在这里使用Zip 是一个很好的解决方案,因为它还考虑了IEnumerable 项目在计数中不匹配的情况。见stackoverflow.com/a/5122767/3956100
  • @Abion47 性能提升永远不会过大 - zip 枚举两个迭代器,而不是将所有文件内容转储到数组或列表中。您可以消除创建字符串数组,但不能消除 zip
  • 除非您还在Zip 之后使用SelectMany,这涉及另一轮迭代。我也看不出任何 LINQ 解决方案比 unlucky 提供的单个 for 循环解决方案性能更高。
  • @Abion47 我在这里看不到任何 SelectMany f1.Zip(f2, (l1,l2) => $"Code = {l1}{Environment.NewLine}Country = {l2}" )。您是否对这些解决方案进行了一些性能测试?我打赌 LINQ 会赢
【解决方案2】:

方法一(3个数组)

创建两个数组,然后创建第三个数组来存储连接的字符串:

var codes = File.ReadAllLines( "Codes.txt" );
var countries = File.ReadAllLines( "Countries.txt" );

var lines = new List<string>( codes.Length );
for( int i = 0; i < codes.Length; i++ ) {
   lines.Add( $"Code = {codes[ i ]}" + Environment.NewLine + $"Country = {countries[ i ]}" );
}

File.WriteAllLines( "Result.txt",  lines);

方法2(2个数组所以内存少)

如果由于内存消耗而不想使用第三个数组,则可以使用已有的数组之一并将连接的字符串存储在其中:

var codes = File.ReadAllLines( "Codes.txt" );
var countries = File.ReadAllLines( "Countries.txt" );

for( int i = 0; i < codes.Length; i++ ) {
   codes[i] = $"Code = {codes[ i ]}" + Environment.NewLine + $"Country = {countries[ i ]}";
}

File.WriteAllLines( "Result.txt", codes );

这是最好的选择,因为它是两全其美:更少的内存和只有 3 次 IO 操作(2 次读取,1 次写入)。


方法3(1个数组所以内存少)

此技术会将所有国家/地区读入内存,然后将代码文件中的一行读入内存,将其写入目标文件,然后从代码文件中读取另一行。因此,在任何给定时间,内存中只有一个代码。这是使用File.ReadLines 实现的。

var countries = File.ReadAllLines( "Countries.txt" );
int i = 0;
File.WriteAllLines( "Result2.txt", File.ReadLines( "Codes.txt" )
   .Select( x => $"Code = {x}" + Environment.NewLine + $"Country = {countries[ i++ ]}" ) );

【讨论】:

    【解决方案3】:

    试试这个:

            string CodePath = Environment.CurrentDirectory + @"\Code.txt";
            List<string> Codes = File.ReadLines(CodePath).ToList();
    
            string CountryPath = Environment.CurrentDirectory + @"\Country.txt";
            List<string> Countries = File.ReadLines(CountryPath).ToList();
    
            string result = string.Empty;
            int length = Math.Min(Codes.Count, Countries.Count);
            for (int i = 0; i < length; i++)
            {
                result += "Code = " + Codes[i] + Environment.NewLine + "Country = " + Countries[i] + Environment.NewLine;
            }
    
            string OutPath = Environment.CurrentDirectory + @"\out.txt";
            File.WriteAllText(OutPath, result);
    

    【讨论】:

      【解决方案4】:

      我会这样做:

      string[] f1 = File.ReadAllLines(@"c:\temp\txt1");
      string[] f2 = File.ReadAllLines(@"c:\temp\txt2");
      string[] f3 = new string[Math.Min(f1.Length, f2.Length)];
      
      for (int i = 0; i < f3.Length; i++)
           f3[i] = "Code = " + f1[i] + "\nCountry = " + f2[i] +"\n";
      File.WriteAllLines(@"c:\temp\txt3", f3);
      

      【讨论】:

        【解决方案5】:

        试试这个:

        List<string> codeList = File.ReadLines(@"c:\temp\txt1").ToList();
        List<string> nameList = File.ReadLines(@"c:\temp\txt2").ToList();
        
        StringBuilder codeNameBuilder = new StringBuilder();
        
        for (int i = 0; i < codeList.Count; i++)
        {
            codeNameBuilder.AppendFormat("Code = {0} \n Country = {1}", codeList[i], nameList[i]);
        }
        
        System.IO.File.WriteAllText(@"c:\temp\txtOutput.txt", codeNameBuilder.ToString());
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-11-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-04-15
          相关资源
          最近更新 更多