Why does File method rename() delete files? - java

I wanted to remove the spaces that Windows puts in filenames.
I ran the following code to rename all the files in a test directory thus. The result: all the files disappeared.
I am puzzled as to why.
import java.io.*;
public class FileRenamer {
public static void main(String[] args) {
for (File file: (new File("O:\\test0")).listFiles())
file.renameTo(new File(file.getName().replaceAll("\\s","")));
System.exit(0);
}
}

TL;DR: You are moving the file.
You list the files in a directory "O:\\test0.
For each such file you then create a String:
file.getName().replaceAll("\\s","")
You end up with:
new File("someFileName")
So you have called:
file.renameTo(new File("someFileName"))
Now, someFileName is not an absolute path; but a relative path. So you have moved from O:\\test0\\some File Name to someFileName, where someFileName is in the directory of the program.
P.S. there is no need to call System.exit(0).

Yes, I found the files had been moved to my class file directory.
Boris's tip about relative vs. absolute paths showed me the solution: to use the
public File(File parent, String child)
constructor for the new abstract File object. The following code did the job correctly.
import java.io.*;
public class FileRenamer {
public static void main(String[] args) {
File dir = new File("O:\\test0");
for (File file: dir.listFiles())
file.renameTo(new File(dir, file.getName().replaceAll("\\s","")));
}
}

Related

Resource loading using ClassLoader

I have a resource file I need to load at runtime...it is in src/main/resources
I have successfully loaded the file to an inputStream using :
LoadSAC.class.getClassLoader().getResourceAsStream("someFile.txt");
LoadSAC is the class name ...
However, PMD complains about this suggests I use
Thread.currentThread().getContextClassLoader().getResource(...)
I have tried numerous combinations and can never get the file to be located... Any thoughts... I have trolled a number of searches with plenty of suggestions but none seem to work...
Any thoughts ?
If someFile.txt is in the same folder than LoadSAC.java, you can do:
InputStream is = LoadSAC.class.getResourceAsStream("someFile.txt");
If someFile.txt is in a subfolder subdir, you can do:
InputStream is = LoadSAC.class.getResourceAsStream("subdir/someFile.txt");
If your method in LoadSAC.java is non-static, you can replace LoadSAC.class.getResourceAsStream... by getClass().getResourceAsStream...
Be careful when compiling with ant or maven, by default, only .java file are copied as .class files in the build directory.
You have to write some rules to include someFile.txt in the final jar.
In your resource directory, you can add a little helper class like this:
import java.io.InputStream;
import java.net.URL;
import javax.activation.DataSource;
import javax.activation.URLDataSource;
public abstract class ResourceHelper {
public static URL getURL(String name) {
return ResourceHelper.class.getResource(name);
}
public static InputStream getInputStream(String name) {
return ResourceHelper.class.getResourceAsStream(name);
}
public static DataSource getDataSource(String name) {
return new URLDataSource(getURL(name));
}
}
In LoadSAC.java just call:
InputStream is = ResourceHelper.getInputStream("someFile.txt");

Creating File & Directories not working properly

I am currently working on a method that will create files and directories. Bellow is the use case & problem explained.
1) When a user specifies a path e.g "/parent/sub folder/file.txt", the system should be able to create the directory along with the file.txt. (This one works)
2) When a user specifies a path e.g "/parent/sub-folder/" or "/parent/sub-folder", the system should be able to create all directories. (Does not work), Instead of it creating the "/sub-folder/" or /sub-folder" as a folder, it will create a file named "sub-folder".
Here is the code I have
Path path = Paths.get(rootDir+"test/hello/");
try {
Files.createDirectories(path.getParent());
if (!Files.isDirectory(path)) {
Files.createFile(path);
} else {
Files.createDirectory(path);
}
} catch (IOException e) {
System.out.println(e.getMessage());
}
You need to use createDirectories(Path) instead of createDirectory(path). As explained in the tutorial:
To create a directory several levels deep when one or more of the
parent directories might not yet exist, you can use the convenience
method, createDirectories(Path, FileAttribute). As with the
createDirectory(Path, FileAttribute) method, you can specify an
optional set of initial file attributes. The following code snippet
uses default attributes:
Files.createDirectories(Paths.get("foo/bar/test"));
The directories
are created, as needed, from the top down. In the foo/bar/test
example, if the foo directory does not exist, it is created. Next, the
bar directory is created, if needed, and, finally, the test directory
is created.
It is possible for this method to fail after creating some, but not
all, of the parent directories.
Not sure of which File API you are using. But find below the simplest code to create file along with folders using java.io package.
import java.io.File;
import java.io.IOException;
public class FileTest {
public static void main(String[] args) {
FileTest fileTest = new FileTest();
fileTest.createFile("C:"+File.separator+"folder"+File.separator+"file.txt");
}
public void createFile(String rootDir) {
String filePath = rootDir;
try {
if(rootDir.contains(File.separator)){
filePath = rootDir.substring(0, rootDir.lastIndexOf(File.separator));
}
File file = new File(filePath);
if(!file.exists()) {
System.out.println(file.mkdirs());
file = new File(rootDir);
System.out.println(file.createNewFile());
}
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
}

Eclipse not finding file?

I am using eclipse and I have my text file in the correct directory (src folder). I just want to read the file and count all the words in it. For some reason I am getting a file not found exception being thrown.
here is my code.
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class Tester {
public static int getSizeOfDictionary(File dictionary)
throws FileNotFoundException {
int count = 0;
Scanner reader = new Scanner(dictionary);
while (reader.hasNextLine()) {
reader.nextLine();
count++;
}
reader.close();
return count;
}
public static void main(String[] args) throws FileNotFoundException {
File test = new File("words.txt");
System.out.println(getSizeOfDictionary(test));
}
}
You could use this.getClass().getResource("words.txt") which will find that file on the current classpath.
From the main method you could use: Tester.class.getResource("words.txt")
when eclipse launches jvm it sets current directory to project base directory generally (unless you modify the default current directory)
${workspace_loc}/project_name
so you need to change your File initialization to
File test = new File("src/words.txt");
Note:
It will just be limited to this project structure, if you export it to jar it will not work any more, I assume you just need it as part of exercise
You have to use property class to access your file within class-path and source folder
you can try like:
this.getClass().getResourceAsFile("words.txt")

Xtend how to get full path of current working directory

I have written a grammar that allows the user to input a relative path. (e.g. "../../temp/out/path"
May aim is to get the absolute path based on the input from the user, and the absolute path of the current working directory so that I can also check if the input path is valid or not.
Is there libraries or built in functions that I can use to get the absolute path?
Something similar to C's _getcwd() function.
Yes, Java has a File class. You can create one by calling this constructor which takes a String. Then you can call getAbsolutePath() on it. You can call it like this:
package com.sandbox;
import java.io.File;
public class Sandbox {
public static void main(String[] args) {
File file = new File("relative path");
String absolutePathString = file.getAbsolutePath();
}
}
This will print a complete absolute path from where your application has initialized.
public class JavaApplication1 {
public static void main(String[] args) {
System.out.println("Working Directory = " +System.getProperty("user.dir"));
}
}

How to get files from a directory on specific condition one file must come after another

Hi I am trying to load data into table using data files. I am using JDBC batch upload. After I load data from test.data into table, I want to validate it using expected-table.data. So in the following method first when test.data comes I want to do batch upload and then it should validate data using expected file but the following code does not work as expeted-data files comes in first iteration and test.data in second iteration. Please help I am new to file programming. Thanks in advance.
public static void loadFromFilesNValidateTable(Schema schema, final File folder)
{
for (final File fileEntry : folder.listFiles())
{
if (fileEntry.isDirectory())
{
loadFromFilesNValidateTable(schema,fileEntry);
}
else
{
if(fileEntry.getName().equals("test.data"))
{
BatchUpload.batchUpload(schema,fileEntry.getAbsolutePath());
}
if(fileEntry.getName().equals("expected-table.data"))
{
validateData(schema,fileEntry.getAbsolutePath());
}
}
}
}
Use a FileFilter
public static void loadFromFilesNValidateTable(TableDef schema, final File folder) {
// Process folders recursively
for(final File subFolder : folder.listFiles(new DirectoryFilter())){
loadFromFilesNValidateTable(schema, subFolder);
}
// Process data files
for (final File dataFileEntry : folder.listFiles(new FileNameFilter("test.data"))) {
BatchUpload.batchUpload(schema,dataFileEntry.getAbsolutePath());
}
// Process expected files
for (final File expectedFileEntry : folder.listFiles(new FileNameFilter("expected-table.data"))) {
validateData(schema,expectedFileEntry.getAbsolutePath());
}
}
public class FileNameFilter implements FileFilter {
private String name;
public FileNameFilter(String name){
this.name = name;
}
public boolean accept(File pathname){
return pathname.getName().equals(name)
}
}
public class DirectoryFilter implements FileFilter {
public boolean accept(File pathname){
return pathname.isDirectory();
}
}
Note: Apache commons-io provides a lot of FileFilters ready to use http://commons.apache.org/proper/commons-io/javadocs/api-2.4/org/apache/commons/io/filefilter/package-summary.html
I have 2 things to suggest you:
1. Change equals method with matches method. Matches method is the best method to compare
Strings.
2. Try to separate the moment in which you do batchUpload from that in which you do
validateData. Maybe you jump some files. For example the algorithm finds first the
"expected-table.data" file and then the "test.data" file. In this case it doesn't validate
the file. I hope my answer is usefull and I hope I have understood your problem : )
You should change the algorithm to something like this:
for (each directory in current directory) {
loadFromFilesNValidateTable(schema, directory);
}
if (current directory contains file "test.data") {
batchUpload();
if (current directory contains file "expected-table.data") {
validateData();
}
}

Categories