Here is a simple piece of code:
import java.io.*;
public class Read {
public static void main(String[] args) {
BufferedReader f = new BufferedReader(new InputStreamReader(System.in));
while(true)
{
String x = null;
try{
x = f.readLine();
}
catch (IOException e) {e.printStackTrace();}
System.out.println(x);
}
}
}
I execute this as : java Read < input.txt
Once the input.txt is completely piped into the program, x keeps getting infinite nulls. Why is that so? Is there a way by which I can make the Standard In(Command Line) active after the file being fed into the code is done?
I've tried closing the stream and reopening, it doesn't work. Reset etc also.
By executing "java Read < input.txt" you've told the operating system that for this process, the piped file is standard in. You can't then switch back to the command line from inside the application.
If you want to do that, then pass input.txt as a file name parameter to the application, open/read/close the file yourself from inside the application, then read from standard input to get stuff from the command line.
Well, this is typical for reading in a BufferedReader. readLine() returns null when end of stream is hit. Perhaps your infinite loop is the problem ;-)
// try / catch ommitted
String x = null;
while( (x = f.readLine()) != null )
{
System.out.println(x);
}
You need to terminate your while loop when the line is null, like this:
BufferedReader in = null;
try {
in = new BufferedReader(new InputStreamReader(System.in));
String line;
while ((line = in.readLine()) != null) {
System.out.println(line);
}
}
catch (IOException e) {
logger.error("IOException reading System.in", e);
throw e;
}
finally {
if (in != null) {
in.close();
}
}
Is there a way by which I can make the Standard In(Command Line)
active after the file being fed into the code is done?
Sorry to bump an old question, but none of the answers so far points out that there is a (shell-only) way to pass back to console input after piping in a file.
If you run the command
{ cat input.txt & cat; } | java Read
then the text from input.txt will be passed to java Read and you will then be dropped back to console input.
Note that if you then press Ctrl+D, you will get the infinite loop of nulls, unless you modify your program to end the loop when it receives null.
Related
i have problem which is probably easy but in can't figure it out. I'm writing simple java program called task1 to read a file and calculate some values. I run this program in cmd like this:
cmd: java task1 calculate
Word "calculate" after "task1" is an argument which start my method to calculate some values. But i would like to calculate some values in a file called values.txt. My problem is that i don't know how to write my code to that read file. This file is passed as argument in cmd like that:
cmd: java task1 calculate < values.txt
hope, you can understand my problem. It Would be awesome if you can just tell me how to print this values in my file
if(args.length == 0)
{
System.out.println("Insert some arguments");
}
else if(args[0].equals("calculate"))
{
//here i would like to read my file (values.txt)
}
I appreciate your help and i am sorry for my bad English.
You should use buffered reader for that.
When you do
cmd: java task1 calculate < values.txt
you pass the contents of values.txt in the program as standard input.
The code would look like this
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
String line = bufferedReader.readLine();
This way you read a line with BufferedReader.
For more please consult http://alvinalexander.com/java/java-bufferedreader-readline-string-examples
PS: It is also possible to directly read a file from disk, no need to pipe it to the program.
You do that like this:
BufferedReader bufferedReader = new BufferedReader(new FileReader(filename));
You can try Files#readAllLines(). This will read a text file and store every line in
a List collection:
//Path valuesPath = Paths.get("VALUES_DIR", "values.txt");
Path valuesPath = Paths.get("./" + args[0]);
try {
List<String> lines = Files.readAllLines(valuesPath, Charset.defaultCharset()));
for (String line : lines) { //print lines (or do whatever you need)
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
Where args[0] is the name of the file to read (on the same directory where the task1.jar is).
Call your java program as:
java -jar task1.jar values.txt
EDIT:
To read piped file as standard in:
BufferedReader in = null;
try {
in = new BufferedReader(new InputStreamReader(System.in));
String line;
while ((line = in.readLine()) != null) { //print lines (or do whatever you need)
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
call your task as:
java task1 calculate < VALUES_PATH\values.txt
Where VALUES_PATH is the complete path where your file is.
Note that when you use < then you can't get back the command line in your own program.
I need to be able to read each line of the file for multiple arguments, hence the for loop. After the first one, it does not seem to be reading them anymore, seems to skip the try statement. Any ideas? I'm sure Its something silly I am missing but have been playing about with it and unfortunately time is not on my side.
for (int j = 0; j < ags.length; j++){
try{
String nameFromFile = null;
BufferedReader InputReader = new BufferedReader(new InputStreamReader(System.in));
while ((nameFromFile = InputReader.readLine()) != null) {
// Do stuff
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
You appear to have two sources you want to compare System.in and args I suggest you read these individually and then compare them.
Set<String> fromInt = new HashSet<>();
try (BufferedReader br = new BufferedReader(new InputStreamReader(System.in))) {
for(String line; (line = br.readLine()) != null;)
fromIn.add(normalise(line));
}
// compare argsList with fromIn.
e.g.
for(String arg: args) {
if (fromIn.contains(normalise(arg))) {
// something
} else {
// something else
}
}
I need to be able to read each line of the file
What file? You're reading from System.in:
BufferedReader InputReader = new BufferedReader(new InputStreamReader(System.in));
Your code will block at this line until you enter something at the console.
You do not read a file, bu the System.in stream.
Every stream has an internal pointer, so the stream nows, which line was read at last.
If the System stream was read once, the pointer is pointing to the end of the stream.
As long as the stream is not reset, the read command will not return anything.
try
InputStream.reset()
or even better, only read the Stream once and cache the result! This is faster and safe, because the Stream input can change during iteration.
Your code will never exit from while loop.
while ((nameFromFile = InputReader.readLine()) != null)
In above loop it will print only one time and at the end of the file it will not be out of the while loop . That's why you are getting only one time output. Since it is not exited from while loop it does not go back into for loop. readLine() return the string and it is terminated by "\n" or "\r\n". Change as below and you will be able to read as ags.length
while ((nameFromFile = InputReader.readLine())=="\n")
I'm writing a Java program with multiple threads. One of the threads is responsible for reading lines from the standard input and parsing them.
Everything works well when running normally, but when the program is run in the background (in Linux) using:
$ java -jar my_jar_file &
my program hangs (at least until brought to foreground).
When running in the background I don't really need the standard input, but I also don't want my program to hang.
I searched for a way to programatically determine if the process is running in the background but could not find it.
Here's the code that reads from standard input:
InputStreamReader inputStreamReader = new InputStreamReader(System.in);
BufferedReader br = new BufferedReader(inputStreamReader);
String line = null;
try {
while ((line = br.readLine()) != null) {
parseInputLine(line, br);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
As far as I can tell, the program hangs when it reaches the br.readLine() command.
I would guess the reader is blocking waiting for input you might be able to pipe in your input from the command line
readLine is a blocking call. So it is obviously waiting for input. If you want it to run in the background, then pass to it input from a file like this
java TakeInput < test.txt &
This where the class is as below and test.txt also shown below:
public class TakeInput
{
public static void main(String[] args)
{
InputStreamReader inputStreamReader = new InputStreamReader(System.in);
BufferedReader br = new BufferedReader(inputStreamReader);
String line = null;
try {
while ((line = br.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
write a text file as test.txt which has say
test1
test2
test3
I don't believe a Java program can determine if it's running in foreground or background.
I tried System.console(), with the following results:
Linux - returns null if stdin is redirected from a file, independent of foreground/background status
Windows - same thing;
Cygwin - seems to always return null
I suspect you will need to invoke the program from the command line as
java -cp ... ClassName < /dev/null
Try using .ready() function.
try {
if (stdError.ready())
{
while((line= stdError.readLine()) != null){
logger.error(line);
}
}
}
Do the same for the stdout.
this is the code that i have found in the internet for reading the lines of a file and also I use eclipse and I passed the name of files as SanShin.txt in its argument field. but it will print :
Error: textfile.txt (The system cannot find the file specified)
Code:
public class Zip {
public static void main(String[] args){
try{
// Open the file that is the first
// command line parameter
FileInputStream fstream = new FileInputStream("textfile.txt");
BufferedReader br = new BufferedReader(new InputStreamReader(fstream));
String strLine;
//Read File Line By Line
while ((strLine = br.readLine()) != null) {
// Print the content on the console
System.out.println (strLine);
}
//Close the input stream
in.close();
}catch (Exception e){//Catch exception if any
System.err.println("Error: " + e.getMessage());
}
}
}
please help me why it prints this error.
thanks
...
// command line parameter
if(argv.length != 1) {
System.err.println("Invalid command line, exactly one argument required");
System.exit(1);
}
try {
FileInputStream fstream = new FileInputStream(argv[0]);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// Get the object of DataInputStream
...
> java -cp ... Zip \path\to\test.file
When you just specify "textfile.txt" the operating system will look in the program's working directory for that file.
You can specify the absolute path to the file with something like new FileInputStream("C:\\full\\path\\to\\file.txt")
Also if you want to know the directory your program is running in, try this:
System.out.println(new File(".").getAbsolutePath())
Your new FileInputStream("textfile.txt") is correct. If it's throwing that exception, there is no textfile.txt in the current directory when you run the program. Are you sure the file's name isn't actually testfile.txt (note the s, not x, in the third position).
Off-topic: But your earlier deleted question asked how to read a file line by line (I didn't think you needed to delete it, FWIW). On the assumption you're still a beginner and getting the hang of things, a pointer: You probably don't want to be using FileInputStream, which is for binary files, but instead use the Reader set of interfaces/classes in java.io (including FileReader). Also, whenever possible, declare your variables using the interface, even when initializing them to a specific class, so for instance, Reader r = new FileReader("textfile.txt") (rather than FileReader r = ...).
First, I saw a few Q's about this issue in the site, but didn't see any answer that solve my problem.
I have a program written in Java and it calls a cmd program written in C++. (this is an assumption since I don't have the actual source) I know the expected I/O of the C++ program, in the cmd it is two lines of output and then it waits for string input.
I know that the first output line of the program is through error stream, and I receive it properly (this is expected), but I don't get the second line in error or input stream.
I tried to write to the program right after the first line ( the error line) and didn't got stuck, but there was no response.
I tried using 3 different threads, for each stream, but again, nothing was received in input/error stream after the first line, and the program didn't respond to writing through output stream.
My initializers are:
Process p = Runtime.getRuntime().exec("c:\\my_prog.exe");
BufferedReader err = new BufferedReader(new InputStreamReader(p.getErrorStream()));
BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream()));
BufferedWriter output = new BufferedWriter(new OutputStreamWriter(p.getOutputStream()));
Is it possible at all or maybe it depends on the C++ program?
Thanks,
Binyamin
If you want to call native applications like C and C++ from Java, you need to use JNI.
I would suggest to put the input in the program when it has started, it will propably use that as input when it wants it.
Here is how I execute any command line in Java. This command line may execute any program:
private String executionCommandLine(final String cmd) {
StringBuilder returnContent = new StringBuilder();
Process pr;
try {
Runtime rt = Runtime.getRuntime();
pr = rt.exec(cmd);
BufferedReader input = new BufferedReader(new InputStreamReader(pr.getInputStream()));
String line = null;
while ((line = input.readLine()) != null) {
returnContent.append(line);
}
input.close();
LOG.debug(returnContent.toString());
// return the exit code
pr.waitFor();
} catch (IOException e) {
LOG.error(e.getMessage());
returnContent = new StringBuilder();
} catch (InterruptedException e) {
LOG.error(e.getMessage());
returnContent = new StringBuilder();
}
return returnContent.toString();
}