Outputting result of "dir" to console in Java - java

I want to output the result of the "dir" command to the java console. I have already looked on Google and here, but none of the examples work for me, thus making me rite this post.
My code is as follows:
try
{
System.out.println("Thread started..");
String line = "";
String cmd = "dir";
Process child = Runtime.getRuntime().exec(cmd);
//Read output
BufferedReader dis = new BufferedReader( new InputStreamReader(child.getInputStream() ));
while ((line = dis.readLine()) != null)
{
System.out.println("Line: " + line);
}
dis.close();
}catch (IOException e){
}
What am I doing wrong?
Any help would be very nice.
Thanks in advance,
Darryl

You cannot run "dir" as a process, you need to change it to String cmd = "cmd dir";.
You don't handle the exception at all. adding the line e.printStackTrace()); in the catch block would tell you what I wrote in (1). Never ignore exceptions!
You don't handle error stream. This might cause your program to hang, handle error stream and read from both streams (error and input) in parallel using different streams.

The best way is to use commons exec http://commons.apache.org/exec/
This has things that catch quirks that can really drive you up the wall, such as the whole process blocking if you didn't clear its output stream, escaping quotes in commands, etc.
Here is a method that will run the del command in windows successfully. Note the use of cmd since del is not a standalone executable:
private void deleteWithCmd(File toDelete) throws IOException {
CommandLine cmdLine = new CommandLine("cmd.exe");
cmdLine.addArgument("/C");
cmdLine.addArgument("del");
cmdLine.addArgument(toDelete.getAbsolutePath());
DefaultExecutor executor = new DefaultExecutor();
int exitValue = executor.execute(cmdLine);
}

a) What is the java console?
b) You should use javas File.listFiles () instead of Runtime.exec, which isn't portable, and makes Name splitting neccessary - a hard thing, for filenames which contain spaces, blanks, newlines and so on.
c) Whats wrong with your code?
d) Why don't you do anything in the case of Exception?

Here is a more thorough example that accounts for OS versions and error conditions ( as stated by MByD above)
http://www.javaworld.com/javaworld/jw-12-2000/jw-1229-traps.html?page=4
Remember that using "exec" means that your application is no longer cross-platform and loses one of the main advantages of Java.
A better approach is to use java.io package.
http://download.oracle.com/javase/tutorial/essential/io/dirs.html

You can also do something like that in java 6 :
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
public class ListFilesFromRegExp {
public static void main(String[] args) throws IOException {
File dir = new File("files/");
File[] files = dir.listFiles(new FilenameFilter() {
public boolean accept(File dir, String name) {
return name.matches("File[0-9].c");
}
});
for (int i = 0; i < files.length; i++) {
System.out.println(files[i].getAbsolutePath());
}
}
}

Related

How to merge one file to another \ Linux

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);
}
}
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.
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);
}

Running a terminal program from java and saves it to a file called output1.txt

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.FileOutputStream;
import java.io.InputStream;
public class RunInput {
public static void main(String[] args) {
try {
Process p = Runtime.getRuntime().exec("java Island < island1.in");
p.waitFor();
InputStream in = p.getInputStream();
int b;
while ((b = in.read()) != -1) {
outputStream.write(b);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
I could not figure out why my program doesn't seem to run the command line and save it to output1.txt. Can someone tell me what is the proper way to do it?
There are I think 2 things missing:
you need to set the classpath for your Java command
you need toseparate the arguments of the command line you want to execute
For instance, assuming the classpath is the current directory:
String[] commands = { "java", "-cp", ".", "Island", "< island1.in" };
Process p = Runtime.getRuntime().exec(commands);
You can do this without invoking a seperate Java VM with code like this:
System.setIn(new FileInputStream("island1.in"));
System.setOut(new FileOutputStream("output1.txt"));
new Island().main(new String[0]);
This replaces the "stdin" and "stdout" with your files and then invokes the main of the Island class.
Runtime.exec does not execute the given command in a shell, so redirection via < and > will not work as you expect. Instead, they will be passed as additional parameters to the executed command. Use the getOutputStream and getInputStream methods of the Process object returned by exec instead.
Don't be confused by the names: getOutputStream returns the standard input stream of the subprocess (which is of type java.io.OutputStream) while getInputStream returns the standard output stream of the subprocess (which is of type java.io.InputStream). In my humble opinion these methods were better named getStandardInput, getStandardOutput and getStandardError.

How to write "enter key pressed" to a stream?

Sorry for this odd-sounding title...
I have the following situation: I want my Java program to interact with an external console. In order to "send" the individual commands to that console, I need to simulate what would be an "enter key pressed" on a normal console. To clarify what I want, imagine mysql had no other API and I would need to interact via console. Although this is not my actual problem, it is close enough.
I have the following code:
String command = "/usr/local/mysql/bin/mysql";
Process child = Runtime.getRuntime().exec(command);
StreamGobbler gobbler = new StreamGobbler(child.getInputStream());
gobbler.start();
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(child.getOutputStream()));
out.write("help");
// here enter key needs to be pressed
out.flush();
// out.close();
If the call to out.close() is executed, everything is fine. But of course, this way I can only send a single command, which is not what I want. But if out.close() is omitted, the other program never executes the command. My guess is that it still waits for the command to "finish", which on a normal console would be done by pressing enter. out.write(System.getProperty("line.separator")); and out.newLine(); (which are the same) do not solve the problem, neither does out.write("\r\n"); and out.write((char) 26); (EOF).
Of course, it might be, that I am doing it completely wrong (i.e., wrong approach). Then I would appreciate a pointer into the right direction...
Any help on this highly appreciated.
The following code works fine on both Windows 7 using Java 1.6.0_23 and on Ubuntu 8.04 using Java 1.6.0_22:
public class Laj {
private static class ReadingThread extends Thread {
private final InputStream inputStream;
private final String name;
public ReadingThread(InputStream inputStream, String name) {
this.inputStream = inputStream;
this.name = name;
}
public void run() {
try {
BufferedReader in = new BufferedReader(
new InputStreamReader(inputStream));
for (String s = in.readLine(); s != null; s = in.readLine()) {
System.console().writer().println(name + ": " + s);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) throws Exception {
String command = "psql -U archadm arch";
final Process child = Runtime.getRuntime().exec(command);
new ReadingThread(child.getInputStream(), "out").start();
new ReadingThread(child.getErrorStream(), "err").start();
BufferedWriter out = new BufferedWriter(
new OutputStreamWriter(child.getOutputStream()));
out.write("\\h");
out.newLine();
out.flush();
out.write("\\q");
out.newLine();
out.flush();
}
}
newLine() is the same as writing the platform line separator. As one would expect, it prints help preceded with "out: ", then exits. If I don't send "\q", it doesn't exit (obviously) but still prints help. Using "\r\n" or "\r" instead of the platform line separator doesn't look like a good idea to me, because such command-line utilities will usually detect that they don't get input from the terminal and assume it is in the native text format (think "psql < script.sql"). Good software should properly detect and accept all reasonable line endings though.
What about out.write((char) 13)? See this Wikipedia article. I don't have enough code to test this for you.
You also might want to try looking at this API
http://download.oracle.com/javase/6/docs/api/java/io/Console.html
From my experience, I've never tried doing anything more than running one process from the Process API. It seems like you want to enter multiple commands I think this API might let you do that.
EDIT: Found a tutorial on it to help you further.
http://download.oracle.com/javase/tutorial/essential/io/cl.html
Hope this helps,

Run shell command from jar?

The usual way to call a shell command from java is something like that:
Process process = Runtime.getRuntime().exec(command);
and works usually fine.
But now I've exported my project to an executable jar file and callig shell commands doesn't work any more. Are there any explanations, solutions or workarounds for this problem?
phineas
--
edit:
even keyboard interrupts (ctrl+c; ctrl+d) aren't recognized.
terminal input won't work after killing java
--
Smallest programm:
import java.io.BufferedWriter;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.IOException;
public class Test {
public static String fileName = "";
/** test if you can open a 7z archive file with a given password */
public static boolean test(String password)
throws IOException, InterruptedException {
String command = "7z l "+fileName;
Process process = Runtime.getRuntime().exec(command);
OutputStream out = process.getOutputStream();
OutputStreamWriter w = new OutputStreamWriter(out);
BufferedWriter writer = new BufferedWriter(w);
writer.write(password+"\n");
writer.close();
w.close();
out.close();
if(process.waitFor() == 0) {
return true;
}
else {
return false;
}
}
public static void main(String[] args) throws IOException, InterruptedException {
fileName = args[0];
test(args[1]);
}
}
If you run your test program and use ps or the task manager you will notice that 7z is running. Your issue is that you are not consuming the output of the Process. So 7z is quickly blocked trying to output your archive's contents.
If you add just before the process.waitFor() the following lines you'll get a working program:
InputStream in = process.getInputStream();
byte[] buf = new byte[256];
while (true) {
int c = in.read(buf);
if (c == -1)
break;
System.out.println(new String(buf));
}
However this will only consume the process stdout you need to do the same with process.getErrorStream(). You may find it easier to use ProcessBuilder to launch your process as it allows you to merge the stderr and stdout streams.
You should read this excellent JavaWorld article on the pitfalls of running external processes from Java.
I would guess that your issue is with the base path from which the command is executed. There is a way to set it explicitly when invoking exec.

How to clear the console?

Can any body please tell me what code is used for clear screen in Java?
For example, in C++:
system("CLS");
What code is used in Java to clear the screen?
Since there are several answers here showing non-working code for Windows, here is a clarification:
Runtime.getRuntime().exec("cls");
This command does not work, for two reasons:
There is no executable named cls.exe or cls.com in a standard Windows installation that could be invoked via Runtime.exec, as the well-known command cls is builtin to Windows’ command line interpreter.
When launching a new process via Runtime.exec, the standard output gets redirected to a pipe which the initiating Java process can read. But when the output of the cls command gets redirected, it doesn’t clear the console.
To solve this problem, we have to invoke the command line interpreter (cmd) and tell it to execute a command (/c cls) which allows invoking builtin commands. Further we have to directly connect its output channel to the Java process’ output channel, which works starting with Java 7, using inheritIO():
import java.io.IOException;
public class CLS {
public static void main(String... arg) throws IOException, InterruptedException {
new ProcessBuilder("cmd", "/c", "cls").inheritIO().start().waitFor();
}
}
Now when the Java process is connected to a console, i.e. has been started from a command line without output redirection, it will clear the console.
You can use following code to clear command line console:
public static void clearScreen() {
System.out.print("\033[H\033[2J");
System.out.flush();
}
Caveats:
This will work on terminals that support ANSI escape codes
It will not work on Windows' CMD
It will not work in the IDE's terminal
For further reading visit this
This is how I would handle it. This method will work for the Windows OS case and the Linux/Unix OS case (which means it also works for Mac OS X).
public final static void clearConsole()
{
try
{
final String os = System.getProperty("os.name");
if (os.contains("Windows"))
{
Runtime.getRuntime().exec("cls");
}
else
{
Runtime.getRuntime().exec("clear");
}
}
catch (final Exception e)
{
// Handle any exceptions.
}
}
⚠️ Note that this method generally will not clear the console if you are running inside an IDE.
A way to get this can be print multiple end of lines ("\n") and simulate the clear screen. At the end clear, at most in the unix shell, not removes the previous content, only moves it up and if you make scroll down can see the previous content.
Here is a sample code:
for (int i = 0; i < 50; ++i) System.out.println();
Try the following :
System.out.print("\033\143");
This will work fine in Linux environment
Create a method in your class like this: [as #Holger said here.]
public static void clrscr(){
//Clears Screen in java
try {
if (System.getProperty("os.name").contains("Windows"))
new ProcessBuilder("cmd", "/c", "cls").inheritIO().start().waitFor();
else
Runtime.getRuntime().exec("clear");
} catch (IOException | InterruptedException ex) {}
}
This works for windows at least, I have not checked for Linux so far. If anyone checks it for Linux please let me know if it works (or not).
As an alternate method is to write this code in clrscr():
for(int i = 0; i < 80*300; i++) // Default Height of cmd is 300 and Default width is 80
System.out.print("\b"); // Prints a backspace
I will not recommend you to use this method.
If you want a more system independent way of doing this, you can use the JLine library and ConsoleReader.clearScreen(). Prudent checking of whether JLine and ANSI is supported in the current environment is probably worth doing too.
Something like the following code worked for me:
import jline.console.ConsoleReader;
public class JLineTest
{
public static void main(String... args)
throws Exception
{
ConsoleReader r = new ConsoleReader();
while (true)
{
r.println("Good morning");
r.flush();
String input = r.readLine("prompt>");
if ("clear".equals(input))
r.clearScreen();
else if ("exit".equals(input))
return;
else
System.out.println("You typed '" + input + "'.");
}
}
}
When running this, if you type 'clear' at the prompt it will clear the screen. Make sure you run it from a proper terminal/console and not in Eclipse.
Runtime.getRuntime().exec(cls) did NOT work on my XP laptop. This did -
for(int clear = 0; clear < 1000; clear++)
{
System.out.println("\b") ;
}
Hope this is useful
By combining all the given answers, this method should work on all environments:
public static void clearConsole() {
try {
if (System.getProperty("os.name").contains("Windows")) {
new ProcessBuilder("cmd", "/c", "cls").inheritIO().start().waitFor();
}
else {
System.out.print("\033\143");
}
} catch (IOException | InterruptedException ex) {}
}
Try this: only works on console, not in NetBeans integrated console.
public static void cls(){
try {
if (System.getProperty("os.name").contains("Windows"))
new ProcessBuilder("cmd", "/c",
"cls").inheritIO().start().waitFor();
else
Runtime.getRuntime().exec("clear");
} catch (IOException | InterruptedException ex) {}
}
This will work if you are doing this in Bluej or any other similar software.
System.out.print('\u000C');
You can use an emulation of cls with
for (int i = 0; i < 50; ++i) System.out.println();
You need to use control characters as backslash (\b) and carriage return (\r). It come disabled by default, but the Console view can interpret these controls.
Windows>Preferences and Run/Debug > Console and select Interpret ASCII control characteres to enabled it
After these configurations, you can manage your console with control characters like:
\t - tab.
\b - backspace (a step backward in the text or deletion of a single character).
\n - new line.
\r - carriage return. ()
\f - form feed.
More information at: https://www.eclipse.org/eclipse/news/4.14/platform.php
You need to use JNI.
First of all use create a .dll using visual studio, that call system("cls").
After that use JNI to use this DDL.
I found this article that is nice:
http://www.planet-source-code.com/vb/scripts/ShowCode.asp?txtCodeId=5170&lngWId=2

Categories

Resources