0

I have a written a small java program that takes arguments from the commandline and should then be interactive.

When I want to test with large input I want to pipe the contents of a file to the JVM to use as the input arguments to the program but I don't want to replace stdin with the file contents.

So I tried

less file | xargs -0 java -cp ... mypackage.ClassName

but this replaces stdin with the file contents I think so the interactive portion of the program that uses BufferedReader.readLine() takes its content from the file instead.

Is there any way I can first pipe the contents of the file to the JVM then switch back to StdIn?

Im running Ubunthu

Code example:

BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String cmd;
while(true) {
    try {
    System.out.print(">");
    cmd = br.readLine(); //becomes null if I start the program as above

Ps. It would be better for the java program to work with files but I want to know if this is possible Ds.

3
  • This doesn't make sense to me. Do you want java -cp … --other-argument <contents-of-a-file> --another-argument mypackage.ClassName? So you can parse the command line for that argument? Maybe you should give us a minimal code example from your Java program? What do you really need to achieve – i.e. what is in this file and why can't you just give your program the file path and let that open the file?
    – slhck
    Jan 22, 2013 at 19:23
  • @slhck Instead of e.g. java -cp ... myclass "Argument0 Arugment1" I want to do: java myclass <contents of file>. After this I want the program to run and stdin in java take input from stdin Jan 22, 2013 at 19:54
  • You can get the contents of a file evaluated in the command line like so: java myclass "$(<some-file.txt)" — but this is a really bad hack and you should modify your Java program to take a file name as an argument.
    – slhck
    Jan 22, 2013 at 20:11

1 Answer 1

0

First, the scolding: One of the lesser-known rules of shell script programming (and even interactive shell use) is do not use

cat some_file | some_command

unless you have a very good reason to.  Oh, sure, it works, but it’s inefficient and bad style.  And, sure,

cat some_file

is the simplest way to display a file on the terminal; that’s fine.  And

cat options file | some_command

and

cat file1 file2 | some_command

are OK.  But

cat some_file | some_command

(with only one filename on the cat command line) can almost always be converted to

some_command < some_file

And I hope it goes without saying that, if

cat some_file | some_command

is bad,

less some_file | some_command

is probably worse.  Why don’t you say

xargs -0 java -cp ... mypackage.ClassName < file

?  But that wouldn’t solve your problem.


I believe that

the answer you’re looking for is:

xargs –a file  -0 java -cp ... mypackage.ClassName

This (or, equivalently,--arg-file=file) tells xargs to open file, not as standard input, and read from it and process it the way it would normally handle stdin, but leave the original standard input alone, and make it available to the exec’ed program.  Warning: not all versions of xargs support this.

By the way, are you expecting file to be so big that its contents cannot fit on a command line, so your program will need to be exec’ed multiple times, with subsets of file as arguments?

2
  • I want to use it to supply large files as input. Basically I made a bad implementation but then got a bit curious about how one can use (or abuse) these types of operations. Jan 25, 2013 at 15:19
  • I was wondering because, if your file is large, then @slhck’s suggestion of "$(<some-file.txt)" probably wouldn’t have worked. Jan 25, 2013 at 16:33

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .