0

I am trying to append one text file to another by using linux commands from my Java program. I am completely new to Linux. I tried sorting and it works just fine, so I have no idea what I am doing wrong with using 'cat'. Could you please review my code and help me figure out what I am doing wrong.

public static void mergeRecords(String fileName, String overflowFileName)
{
    String command = "cat " + overflowFileName + " >> " + fileName;
    try {
        Process r = Runtime.getRuntime().exec(command);
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}
Jezor
  • 3,253
  • 2
  • 19
  • 43
useruser123
  • 89
  • 1
  • 11

2 Answers2

4

Runtime#exec is not a shell.

This is a very common misconception. What you need to do is:

  • create a Process with the command cat file1 file2,
  • take the output of that process,
  • dump that output into a file.

Hint: use a ProcessBuilder, this will make your job much easier.

fge
  • 119,121
  • 33
  • 254
  • 329
  • Or just add [bash -c](http://stackoverflow.com/a/1410778/5922757) (if he's using `bash` of course). – Jezor Sep 11 '16 at 15:46
  • Yep, this was the problem. As I said I'm completely new to Linux and on an assignment deadline so I didn't really do a lot of research. I used ProcessBuilder and now it works :) Thank you – useruser123 Sep 11 '16 at 16:07
1

As others have pointed out, you should not use external commands to do something Java can easily do:

try (OutputStream existingFile = Files.newOutputStream(
    Paths.get(fileName),
    StandardOpenOption.WRITE,
    StandardOpenOption.APPEND)) {

    Files.copy(Paths.get(overflowFileName), existingFile);
}
VGR
  • 40,506
  • 4
  • 48
  • 63
  • Why the use of a `BufferedOutputStream`? To be honest, I have never seen any difference in speed between this and a "classical" `OutputStream`, at least as far as file I/O is concerned... – fge Sep 11 '16 at 18:42
  • FileOutputStream is analogous to C’s write(), while BufferedOutputStream is analogous to C’s fwrite(), so it’s good practice, usually. But you made me curious, so I looked at the source of the Files class… and it is indeed doing its own buffering for both Files.copy(Path, OutputStream, options) and Files.copy(InputStream, Path, options). Which means, for those two methods at least, BufferedOutputStream and BufferedInputStream are not needed. I’ve removed it. – VGR Sep 11 '16 at 21:42