【问题标题】:Combining all text files in a folder into a single file将文件夹中的所有文本文件合并到一个文件中
【发布时间】:2013-07-11 15:58:28
【问题描述】:

如何将文件夹中的所有 txt 文件合并为一个文件?一个文件夹通常包含成百上千个 txt 文件。

如果这个程序只在 Windows 机器上运行,我只会使用包含类似内容的批处理文件

copy /b *.txt merged.txt

但事实并非如此,所以我认为用 Java 编写它来补充我们所拥有的一切可能会更容易。

我写过这样的东西

// Retrieves a list of files from the specified folder with the filter applied
File[] files = Utils.filterFiles(downloadFolder + folder, ".*\\.txt");
try
{
  // savePath is the path of the output file
  FileOutputStream outFile = new FileOutputStream(savePath);

  for (File file : files)
  {
      FileInputStream inFile = new FileInputStream(file);
      Integer b = null;
      while ((b = inFile.read()) != -1)
          outFile.write(b);
      inFile.close();
  }
  outFile.close();
}
catch (Exception e)
{
  e.printStackTrace();
}

但是合并数千个文件需要几分钟,所以不可行。

【问题讨论】:

  • 您一次读取一个字节...
  • 哦,read() 没有尽可能多地阅读?这可能解释了为什么它这么慢
  • 不,它读取单个字节(参见here,使用其他接受byte[] 的read() 方法。
  • @fge 一些机器仍在 java 6 上运行,但这应该不是问题。
  • 好吧,即使 Java 6 也有 FileChannel,你应该充分利用它

标签: java file-io


【解决方案1】:

使用 NIO,它比使用输入流/输出流要容易得多。注意:使用Guava的Closer,表示所有资源都安全关闭;更好的是使用 Java 7 和 try-with-resources。

final Closer closer = Closer.create();

final RandomAccessFile outFile;
final FileChannel outChannel;

try {
    outFile = closer.register(new RandomAccessFile(dstFile, "rw"));
    outChannel = closer.register(outFile.getChannel());
    for (final File file: filesToCopy)
        doWrite(outChannel, file);
} finally {
    closer.close();
}

// doWrite method

private static void doWrite(final WriteableByteChannel channel, final File file)
    throws IOException
{
    final Closer closer = Closer.create();

    final RandomAccessFile inFile;
    final FileChannel inChannel;

    try {
        inFile = closer.register(new RandomAccessFile(file, "r"));
        inChannel = closer.register(inFile.getChannel());
        inChannel.transferTo(0, inChannel.size(), channel);
    } finally {
        closer.close();
    }
}

【讨论】:

    【解决方案2】:

    因为这个

      Integer b = null;
      while ((b = inFile.read()) != -1)
          outFile.write(b);
    

    您的操作系统正在进行大量 IO 调用。 read() 只读取一个字节的数据。使用另一个接受byte[]read methods。然后,您可以使用该byte[] 写信给您的OutputStream。同样,write(int) 执行写入单个字节的 IO 调用。也改变一下。

    当然,您可以研究为您执行此操作的工具,例如 Apache Commons IO 甚至 Java 7 NIO 包。

    【讨论】:

    • 在我自己弄清楚如何合并文件之后,我可能会切换到 NIO。感谢您指出问题。
    【解决方案3】:

    尝试使用BufferedReaderBufferedWriter,而不是逐个写入字节。

    【讨论】:

      【解决方案4】:

      您可以使用 IoUtils 来合并文件,IoUtils.copy() 方法将帮助您合并文件。

      此链接可能有用merging file in java

      【讨论】:

        【解决方案5】:

        我会这样做!

        1. 检查操作系统

          System.getProperty("os.name")

        2. 从 Java 运行系统级命令。

          如果窗口

                  copy /b *.txt merged.txt
          

          如果是 Unix

                  cat *.txt > merged.txt
          

          或任何可用的最佳系统级命令。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2013-06-03
          • 2022-06-17
          • 2016-09-05
          • 1970-01-01
          • 1970-01-01
          • 2015-01-20
          • 1970-01-01
          相关资源
          最近更新 更多