21

I have a number of .txt files. I would like to concatenate those and generate a text file.
How would I do it in Java?


Following is the case

file1.txt file2.txt 

Concatenation results into

file3.txt

Such that the contents of file1.txt is followed by file2.txt.

informatik01
  • 16,038
  • 10
  • 74
  • 104
thetna
  • 6,903
  • 26
  • 79
  • 113
  • yes i used to do it with cat in unix command. but i would like to do it in my program. – thetna May 20 '12 at 17:14
  • 8
    @casperOne This is a very real question, several have understood it, and provided useful information, like the pointer to the FileUtils class. – Eric Wilson May 02 '13 at 18:26
  • Yeah, definitely a real question. Asked exactly what I wanted to know, and the answers below were helpful. – csjacobs24 Sep 15 '15 at 15:29
  • 1
    +1. It is quite legitimate question, given that the shortest pure-Java answer is 11 lines of code. Compare with #cat file1 file2 > file3 in UNIX shell. – badbishop Oct 07 '17 at 06:36

5 Answers5

39

Using Apache Commons IO

You could use the Apache Commons IO library. This has the FileUtils class.

// Files to read
File file1 = new File("file1.txt");
File file2 = new File("file2.txt");

// File to write
File file3 = new File("file3.txt");

// Read the file as string
String file1Str = FileUtils.readFileToString(file1);
String file2Str = FileUtils.readFileToString(file2);

// Write the file
FileUtils.write(file3, file1Str);
FileUtils.write(file3, file2Str, true); // true for append

There are also other methods in this class that could help accomplish the task in a more optimal way (eg using streams or lists).

Using Java 7+

If you are using Java 7+

public static void main(String[] args) throws Exception {
    // Input files
    List<Path> inputs = Arrays.asList(
            Paths.get("file1.txt"),
            Paths.get("file2.txt")
    );

    // Output file
    Path output = Paths.get("file3.txt");

    // Charset for read and write
    Charset charset = StandardCharsets.UTF_8;

    // Join files (lines)
    for (Path path : inputs) {
        List<String> lines = Files.readAllLines(path, charset);
        Files.write(output, lines, charset, StandardOpenOption.CREATE,
                StandardOpenOption.APPEND);
    }
}
Community
  • 1
  • 1
Paul Vargas
  • 41,222
  • 15
  • 102
  • 148
  • 4
    [This question](http://stackoverflow.com/questions/1605332/java-nio-filechannel-versus-fileoutputstream-performance-usefulness) describes significantly better performance using Channels instead of reading everything into memory. You can also use Guava's ByteSource.concat to get an InputStream of everything concatenated, then pass it into FileChannel.transferTo – Meredith Feb 04 '16 at 00:42
17

Read file-by-file and write them to target file. Something like the following:

    OutputStream out = new FileOutputStream(outFile);
    byte[] buf = new byte[n];
    for (String file : files) {
        InputStream in = new FileInputStream(file);
        int b = 0;
        while ( (b = in.read(buf)) >= 0)
            out.write(buf, 0, b);
        in.close();
    }
    out.close();
CryptoFool
  • 21,719
  • 5
  • 26
  • 44
AlexR
  • 114,158
  • 16
  • 130
  • 208
  • I like this one more as it extensible for more than two files and doesn't have to hold as much in memory. – Brian Risk Mar 24 '17 at 17:59
  • @alexr can you extend it a little bit more and explain it step by step? – JoelBonetR Mar 09 '18 at 09:44
  • The outer loop iterates over files. Inner loop reads the file's content using n-bytes long buffer. Just take a look on any tutorial on java streams for details. – AlexR Mar 10 '18 at 11:34
4

this works fine for me.

// open file input stream to the first file file2.txt
InputStream in = new FileInputStream("file1.txt");
byte[] buffer = new byte[1 << 20];  // loads 1 MB of the file
// open file output stream to which files will be concatenated. 
OutputStream os = new FileOutputStream(new File("file3.txt"), true);
int count;
// read entire file1.txt and write it to file3.txt
while ((count = in.read(buffer)) != -1) {
    os.write(buffer, 0, count);
    os.flush();
}
in.close();
// open file input stream to the second file, file2.txt
in = new FileInputStream("file2.txt");
// read entire file2.txt and write it to file3.txt
while ((count = in.read(buffer)) != -1) {
    os.write(buffer, 0, count);
    os.flush();
}
in.close();
os.close();
Samer Makary
  • 1,815
  • 2
  • 22
  • 25
1

You mean you need one file with the content of other text files? Then, read each and every file(you can do it in a loop), save their content in a StringBuffer/ArrayList, and generate the final .txt file by flushing those saved texts in StringBuffer/ArrayList to the final .txt file.

Don't worry, this is an easy task. Just get used to the given system, then you are OK :)

PeakGen
  • 21,894
  • 86
  • 261
  • 463
0

Sounds like homework...

  1. Open File 1
  2. Open File 2
  3. Create/Open File 3
  4. Read from File 1 and Write into File 3
  5. Close File 1
  6. Read From File 2 and Write into File 3
  7. Close File 2
  8. Close File 3

If you need to know how to create/open/read/write/close files in Java, search for documentation. That information should be widely available.

Sion Sheevok
  • 4,057
  • 2
  • 21
  • 37