ProcessBuilder delete and rename - java

I am having a ProcessBuilder that should delete File.txt and then rename NewFile.txt.
Problem is that both files are deleted. Any idea why and how to fix?
public class MyProcessBuilder {
public static void main(String[] args){
final ArrayList<String> command = new ArrayList<String>();
// CREATE FILES
File file = new File("File.txt");
File newFile = new File("NewFile.txt");
try{
if(!file.exists())
file.createNewFile();
if(!newFile.exists())
newFile.createNewFile();
} catch(Exception e){}
// force remove File.txt
command.add("rm");
command.add("-f");
command.add("File.txt");
// rename NewFile.txt to File.txt
command.add("mv");
command.add("NewFile.txt");
command.add("File.txt");
final ProcessBuilder builder = new ProcessBuilder(command);
try {
builder.start();
} catch (IOException e) {
e.printStackTrace();
}
}
}

The issue is that you are running a single command, namely
rm -f File.txt mv NewFile.txt File.txt
This unconditionally deletes files named File.txt, mv and NewFile.txt.
You want to split this into two separate commands.
Better still, use File.delete() and File.renameTo(). This will not only give you more control, but will also make your code more portable.

ProcessBuilder.start creates one process. You need to call it twice because you have two commands: first with the first command and then with the second.
Incidentally, why are you not using Java's file API for this? It is a lot easier to do this from Java than to deal with the complexity of launching a separate process, not to mention more efficient.

Related

Java creating a test file from a jar

I want to have a java app, where after starting the jar I get a file for example a test.txt within the same folder as the jar.
For example I click on the jar and in the same folder I get a test.txt file.
The below code works in eclipse and creates the file, but after an export to jar, no file is produced.
Would be very happy if you could help.
public class FileWriterTest {
public static void main(String[] args) {
String fileName = "test.txt";
try(
FileWriter fileWriter = new FileWriter(fileName);
BufferedWriter writer = new BufferedWriter(fileWriter);
) {
writer.write("Hello");
} catch(IOException e) {
e.printStackTrace();
}
}
}
With System.getProperty("user.dir") you can get the current "working directory".
If you want to create a file in that specific directory you could use the following code:
String workingDirectory = System.getProperty("user.dir");
File file = new File(working directory + File.separator + "filename.txt");
file.createNewFile();
If you are running as java -jar yourjar.jar, it will not take the additional classpath.
You need to add your jar and location where file resided in classpath and call java command for Main class
example
Linux
java -classpath .:path_dir_with_jar/*:path_to_file MainClass
Windows
java -classpath .;path_dir_with_jar/*;path_to_file MainClas
Finally can read as
InputStream in = this.getClass().getClassLoader()
.getResourceAsStream("SomeTextFile.txt")
;

Creating temporary file and rename to actual file

I am trying to create a temporary file and then rename it to a usable file. The temp file is getting created in %temp% but not getting renamed:-
static void writeFile() {
try {
File tempFile = File.createTempFile("TEMP_FAILED_MASTER", "");
PrintWriter pw = new PrintWriter(tempFile);
for (String record : new String[] {"a","b"}) {
pw.println(record);
}
pw.flush();
pw.close();
System.out.println(tempFile.getAbsolutePath());
File errFile = new File("C:/bar.txt");
tempFile.renameTo(errFile);
System.out.println(errFile.getAbsolutePath());
System.out.println("Check!");
} catch (Exception e) {
e.printStackTrace();
}
}
There are a few reasons why a rename can fail. The common ones are:
You don't have write permission for the source or destination directory.
The file you are renaming is open (on Windows)
You are attempting to rename across different file systems.
It can be difficult to diagnose these (and other) failure reasons if you are using File.renameTo because all you get is a boolean return value.
I recommend using Files.move instead. It can cope with moving files between file systems, and will throw an exception if the file cannot be renamed.

how to open a file using exec method in java?

C:\Users\Admin\Downloads\VID_20160226_203631957.mp4
when I execute above line in command prompt the corresponding video gets played with default media player.
But when I try to do same using java Runtime class it doesnt work.
I am using following method.
Runtime r= Runtime.getRuntime();
r.exec("C:\Users\Admin\Downloads\VID_20160226_203631957.mp4")
Use Desktop.open(File) which launches the associated application to open the file. Something like,
File f = new File("C:/Users/Admin/Downloads/VID_20160226_203631957.mp4");
try {
Desktop.getDesktop().open(f);
} catch (IOException e) {
e.printStackTrace();
}
You might prefer to build the path relative to the user's home directory; something like
File downloads = new File(System.getProperty("user.home"), "Downloads");
File f = new File(downloads, "VID_20160226_203631957.mp4");
Try this.
Runtime r= Runtime.getRuntime();
r.exec("cmd /c C:\\Users\\Admin\\Downloads\\VID_20160226_203631957.mp4");

java.io.FileNotFoundException when copying existing file via FileUtils

I have a problem. I try to copy a file and I get a FileNotFound exception. Here is my code:
File file = new File("C:\\.DS\\tmp\\client-" + node_id + ".war");
File dir = new File("D:\\Utils\\Apache\\Tomcat\\webapps");
try {
FileUtils.copyFileToDirectory(file, dir);
} catch (Exception e) {
e.printStackTrace();
}
And the exception is:
java.io.FileNotFoundException: Source 'C:\.DS\tmp\client-022.war' does not exist
at org.apache.commons.io.FileUtils.copyFile(FileUtils.java:1074)
at org.apache.commons.io.FileUtils.copyFileToDirectory(FileUtils.java:1013)
...
But the file is in that folder.
This code is called from JSF in Tomcat, so maybe it's a problem of Tomcat direcories. The file is generated in previous function via external command using ProcessBuilder, so maybe Java tries to parallel and the ProcessBuilder is finishing after the copying is done.
Also, in another method of the same class this code works perfectly:
File file = new File("C:\\.DS\\tmp\\client-" + node_id + ".properties");
File dir = new File("C:\\.DS\\ss\\engines");
try {
FileUtils.copyFileToDirectory(file, dir);
...
I've figured out that Java is "smart", so Process Builder runs in separate thread (or even process), and to fix my problem I have to change
ProcessBuilder pb = ...
pb.start()
to
ProcessBuilder pb = ...
Process p = pb.start()
p.waitFor()

Java, reading a file from current directory?

I want a java program that reads a user specified filename from the current directory (the same directory where the .class file is run).
In other words, if the user specifies the file name to be "myFile.txt", and that file is already in the current directory:
reader = new BufferedReader(new FileReader("myFile.txt"));
does not work. Why?
I'm running it in windows.
Try
System.getProperty("user.dir")
It returns the current working directory.
The current directory is not (necessarily) the directory the .class file is in. It's working directory of the process. (ie: the directory you were in when you started the JVM)
You can load files from the same directory* as the .class file with getResourceAsStream(). That'll give you an InputStream which you can convert to a Reader with InputStreamReader.
*Note that this "directory" may actually be a jar file, depending on where the class was loaded from.
None of the above answer works for me. Here is what works for me.
Let's say your class name is Foo.java, to access to the myFile.txt in the same folder as Foo.java, use this code:
URL path = Foo.class.getResource("myFile.txt");
File f = new File(path.getFile());
reader = new BufferedReader(new FileReader(f));
Files in your project are available to you relative to your src folder. if you know which package or folder myfile.txt will be in, say it is in
----src
--------package1
------------myfile.txt
------------Prog.java
you can specify its path as "src/package1/myfile.txt" from Prog.java
If you know your file will live where your classes are, that directory will be on your classpath. In that case, you can be sure that this solution will solve your problem:
URL path = ClassLoader.getSystemResource("myFile.txt");
if(path==null) {
//The file was not found, insert error handling here
}
File f = new File(path.toURI());
reader = new BufferedReader(new FileReader(f));
Thanks #Laurence Gonsalves your answer helped me a lot.
your current directory will working directory of proccess so you have to give full path start from your src directory like mentioned below:
public class Run {
public static void main(String[] args) {
File inputFile = new File("./src/main/java/input.txt");
try {
Scanner reader = new Scanner(inputFile);
while (reader.hasNextLine()) {
String data = reader.nextLine();
System.out.println(data);
}
reader.close();
} catch (FileNotFoundException e) {
System.out.println("scanner error");
e.printStackTrace();
}
}
}
While my input.txt file is in same directory.
Try this:
BufferedReader br = new BufferedReader(new FileReader("java_module_name/src/file_name.txt"));
try using "."
E.g.
File currentDirectory = new File(".");
This worked for me

Categories