I am wondering how to pass a file as an argument on linux command line.
public class Main {
public static void main(String[] args){
System.out.println(args[0]);
}
}
For the above code if I do:
java -jar myJava.jar blah.txt
It prints blah.txt to the screen.
But I have a sample line of code that looks like this:
java -jar myJava.jar < blah.txt
How am I able to get the value of blah.txt from the above command?
Use one of the techniques for reading from System.in where the file is being redirected such as Scanner
Scanner scanner = new Scanner(System.in);
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
...
}
try the following
java -jar myJava.jar 'blah.txt'
The quotes indicate that the argument is literal.
double quotes will also work, but will not prevent things like variable expansion, so single quotes is better when trying to pass a literal string.
Related
I have a Scanner that could be reading from either keyboard or from a file (via pipes), and apparently there's no way to tell which.
I have te following code:
Scanner scan = new Scanner(System.in);
while (scan.hasNextLine()) {
String line = scan.nextLine();
doStuff();
}
That works wonderfully when redirecting input to a file. But if I try to run the program by itself and read from keyboard, it enters an infinite loop. Is there a way to differentiate between reading from keyboard and from a file? Thanks in advance!
Edit 1:
As requested by #Abra, this is what my code looks like with your suggestion:
Scanner scan = new Scanner(System.in);
do {
String linea = scan.nextLine();
doStuff();
} while (System.in.available() != 0 && scan.hasNextLine());
And here's the command I'm running:
java -jar Class.jar < File.txt
Edit 2:
Solved it, turns out I should only evaluate System.in.available() != 0 once:
Scanner scan = new Scanner(System.in);
boolean file = System.in.available() != 0;
do {
String linea = scan.nextLine();
doStuff();
} while (file && scan.hasNextLine());
The classic practice used commonly in Linux and Unix is to read input from standard input, as you are already doing. In Java, standard input is called System.in.
The program reads from standard input and processes what it reads in a loop until it detects end-of-file, which you are already doing.
So your program is not stuck - it is merely waiting for more input or for the end-of-file signal to come from the outside.
If you want to use this program with input from a file, you run it like this:
myprogram < input_file.txt
And if you want your program to get its input from terminal (where you type it), you run it just like
myprogram
In this case, and after typing your input, you are also responsible to send a special signal from your terminal that will act as a "end-of-file" and will be picked by the program, causing the while-loop to exit. Typically, you do this by pressing Control-D.
Keep in mind that reading from standard input is not strictly the same as reading from keyboard. Standard input only knows about text and end-of-file; it has no concept of line editing, testing for when shift key is pressed/released etc.
The class of System.in is java.io.InputStream. That class has method available(). If you redirect System.in to a file, as in
myprogram < input_file.txt
Then method available() returns a number greater than zero (assuming that input_file.txt has non-zero size) but when System.in refers to the standard input stream, i.e. when you run your program without redirecting standard input, as in
myprogram
Then method available() returns zero.
based on the answer of #Abra you can break the loop if System.in is keyboard so:
import java.util.Scanner;
import java.io.IOException;
public class Main {
public static void main(String[] argv) throws IOException {
Scanner scan = new Scanner(System.in);
boolean isKeyboard = System.in.available() == 0;
while (scan.hasNextLine()) {
String line = scan.nextLine();
doStuff();
if (isKeyboard) {
break;
}
}
}
}
I'm using the Scanner class as stdin for read input from keybord.
I would read token by token the string insert until the end of the line.
token are separated by white spaces.
this is my code:
Scanner in = new Scanner(System.in);
int count=0;
while(in.hasNextLine()){
while(in.hasNext()){
String s=in.next();
System.out.println(s);
if(s.equals("\n"))
break;
count++;
}
break;
}
System.out.println(count);
The problem is that when i press enter, it seems considering it like a white space and it never exit from while block, so it continues to expect another input.
the only way to exit from the while and end the program in Linux is to press ctrl+D (=enter) but i'm searching another way...
I tried to insert an if statement which check if the token is a "\n" but it doesn't work.
Can you help me find a solution to the problem?
The in.hasNextLine() and in.hasNext() methods are blocking ones when used with streams: if there is no new line or new token, they will wait until you write something and press enter again.
If you only want one line you can use something like:
package test;
import java.util.Scanner;
public class Test {
public static void main(String[] args) {
int count=0;
Scanner in =new Scanner(System.console().readLine()); //scanning just one line
while(in.hasNext()){
String s=in.next();
System.out.println(s);
count++;
}
System.out.println(count);
in.close();
}
}
Note:
If you execute this code from an IDE, there is no console, so System.console() return null. In order to run it from the command line you need to type something like:
$ pwd
/home/user/development/workspace/test/bin
$ ls
test
$ ls test
Test.class
$ java -classpath /home/user/development/workspace/test/bin/ test.Test
Consider the code :
import java.util.*;
public class TestClass
{
public static void main(String[] args)
{
Scanner input= new Scanner ("34\n567");
while(input.hasNext())
{
System.out.println(input.nextLine());
}
input.close();
}
}
the output I get:
34
567
When I try to read the string by nextLine(), it should not read it like this as it has to terminate only at line separator and \n is not line separator in Java.
So how does this happen?
Try this one
String s = "a\r\nb";
for (String str : s.split(System.getProperty("line.separator"))) {
System.out.println(str);
}
System.out.println("Length:"+s.split(System.getProperty("line.separator")).length);
\r\n represents new line.
output
a
b
Length:2
nextLine() is base in the regulare expression "\r\n|[\n\r\u2028\u2029\u0085]". This accepts any line break of the supported plattforms of java and is not limited to plattform this instance of the jvm is actually running on. In fact most methods in java for detecting a line break work this way. Thus it's not really correct that there's a definition how the line break should look like.
This question already has answers here:
How to get around the command line length limit?
(9 answers)
Closed 9 years ago.
I am writing a code that accepts a list of files as an input. I am doing stress testing and an error occurs if there are a lot of files as an input.
My main function accepts an array of Strings as an input.
public static void main(String[] args)
I have around 200 files as an input. My args accepts input in this format:
-f <file path>
At one point on the list of files, Java will throw a File Not Found exception because it gets an incorrect path. There is always only one character missing. And the preceding file entries are read correctly.
I tried to get the length of the string when one character got missing, and it is always on 8090th character.
Example:
If I have a list of files in a nested directory. My input will be something like this.
-f test\test1\test1_test2\test1_test2_test3\test3_test4.txt
Repeated inputs of this kind would result to:
-f test\test1\test1_test2\test1_test2_test3\test3_test4.txt
...
-f test\test1\test1_**tst2**\test1_test2_test3\test3_test4.txt
...
-f test\test1\test1_test2\test1_test2_test3\test3_test4.txt
There is a missing "e" which should be the 8090th character. But the next file entries are being read correctly. What am I missing?
Quoting MS Support
In Command Prompt, the total length of the following command line that you use at the command prompt cannot contain more than either 2047 or 8191 characters (as appropriate to your operating system)
So this means you cannot pass arguments to your program longer than 8191 characters. But workaround could be storing your arguments into the file and pass that file through command line to your program.
Make a second main class, where the main reads a file with the arguments.
public class MainWithArgsFile {
public static void main(String[] fileArgs) {
List<String> args = new ArrayList<>();
// Fill args:
for (String fileArg: fileArgs) { // One or more files.
try (BufferedReader in = new BufferedRead(new InputStreamReader(
new FileInputStream(new File(fileArg)), "UTF-8"))) {
for (;;) {
String line = in.readLine();
if (line == null) {
break;
}
//args.add(line); // One arg per line (for instance).
Collections.addAll(args, line.split(" +"));
}
}
}
OriginalMain.main(args.toArray(new String[args.size()]);
}
}
How do I pick the methods in my program to run using command line arguments? For example, if I want my program to process an image called Moon.jpg, how do I make it work so that -S Moon.jpg in the command line would invoke the Scale method? Or -HI Moon.jpg would flip the image Horizontally and Invert it? I have some methods written and they work when I run the program normally.
You can parse arguments with a function like this:
private void parseArguments(String[] args)
{
int i = 0;
String curArg;
while (i < args.length && args[i].startsWith("-"))
{
curArg = args[i++];
if ("-S".compareTo(curArg) == 0)
{
if (i < args.length)
{
String image = args[i++];
processImage()
}
else
{
// ERROR
}
}
}
}
Your main method should always have String[] args which contains arguments split on the space character. There are also plenty of libraries you can use to parse command line arguments. This method is quite similar to what the Apaches CLI library uses (Of course there's a lot more that comes with that library but the parser uses this logic).
http://commons.apache.org/cli/
This should help. and here's how to use it:
http://commons.apache.org/cli/usage.html
You may need to write different methods for each purpose and have if/else conditions based on command input.
why not read the arguments passed and read subsequent value to do the required stuff
ie,
java yourprogram -a1 something -a2 somethingelse
and in your program
public static void main(String[] args){
for(int i=0;i<args.length;i++){
switch(args[i]){//you can use if-else to deal with string...
case "-a1":read args[i+1] to get value to do somethng
case "-a2": read args[i+1] to get value to do something else
}
}