Rename non empty directory issue using Java NIO - java

According to:
How do I rename (not move) a file in JDK7?
I'm trying to rename folder name of not empty folder with java NIO
My result , is new directory created without files inside and not delete old one.
The code i used but it doesn't work:
try (FileSystem fs = FileSystems.newFileSystem(uri, env)) {
Path oldPath = fs.getPath("/some/directory2");
Files.move(oldPath, oldPath.resolve("/some/directory_replaced2_2"), StandardCopyOption.REPLACE_EXISTING);
} catch (IOException e) {
e.printStackTrace();
}
What I'm missing ? ( I want only rename folder)

You can rename directory using java.nio.file.Files.move method and then copy the files with Files.walkFileTree:
To move a file tree may involve copying rather than moving directories and this can be done using the copy method in conjunction with the Files.walkFileTree utility method.
You can follow java tutorial:
import static java.nio.file.StandardCopyOption.*;
Files.move(source, target, REPLACE_EXISTING);
the method is most often used with the file tree recursion mechanism. For more information, see Walking the File Tree.

Related

FileAlreadyExistsException when using Files.copy

I am trying to copy a file from an InputStream into a local directory. I created a local directory called test, and it is located in my package root.
public void copyFileFromInputStream(InputStream is) {
Path to = Paths.get("test");
Files.copy(is, to);
}
Clearly I am misunderstanding Files.copy(...), because it seems like it is trying to create a new file called "test" instead of placing the file into the directory "test".
How do I write the file into the directory?
First create the new directory, then copy the stream to a new file in that directory:
Path to = Paths.get("mynewdir/test");
Files.copy(is, to);
Also bare in mind that your InputStream does not have a filename, so you will always need to provide a filename when writing the stream to disk. In your example, it will indeed try to create a file 'test', but apparently that is a folder that already exists (hence the Exception). So you need to specify the full filename.
Here is a answer for you question:
Referring to you code snippet: Paths.get("test");
you're asking a file path to the file named "test" in the current directory but not the directory.
If you want to refer the file under test directory which in tern under your current directory. use the following:
Paths.get("test/filename.ext") to which you want to write your stream data.
If you run your app twice, you get "FileAlreadyExistsException" because copy method on Files writes to new file , if exists it'll not override it.
I hope this helps you!
The 'to' parameter of Files.copy(from, to) is the path to the destination file.
Try specifying what file name inside the test directory:
Path to = Paths.get("test/newfilename");
Files.copy(is, to);
You can use the option StandardCopyOption.REPLACE_EXISTING :
public void copyFileFromInputStream(InputStream is) {
Path to = Paths.get("test");
Files.copy(is, to, StandardCopyOption.REPLACE_EXISTING);
}

Is there a way to get the file path of the .java file executed or compiled?

In Python the global variable __file__ is the full path of the current file.
System.getProperty("user.dir"); seems to return the path of the current working directory.
I want to get the path of the current .java, .class or package file.
Then use this to get the path to an image.
My project file structure in Netbeans looks like this:
(source: toile-libre.org)
Update to use code suggested from my chosen best answer:
// read image data from picture in package
try {
InputStream instream = TesseractTest.class
.getResourceAsStream("eurotext.tif");
bufferedImage = ImageIO.read(instream);
}
catch (IOException e) {
System.out.println(e.getMessage());
}
This code is used in the usage example from tess4j.
My full code of the usage example is here.
If you want to load an image file stored right next to your class file, use Class::getResourceAsStream(String name).
In your case, that would be:
try (InputStream instream = TesseractTest.class.getResourceAsStream("eurotext.tif")) {
// read stream here
}
This assumes that your build system copies the .tif file to your build folder, which is commonly done by IDEs, but requires extra setup in build tools like Ant and Gradle.
If you package your program to a .jar file, the code will still work, again assuming your build system package the .tif file next to the .class file.
Is there a way to get the file path of the .java file executed or compiled?
For completeness, the literal answer to your question is "not easily and not always".
There is a round-about way to find the source filename for a class on the callstack via StackFrameElement.getFileName(). However, the filename won't always be available1 and it won't necessarily be correct2.
Indeed, it is quite likely that the source tree won't be present on the system where you are executing the code. So if you needed an image file that was stashed in the source tree, you would be out of luck.
1 - It depends on the Java compiler and compilation options that you use. And potentially on other things.
2 - For example, the source tree can be moved or removed after compilation.
Andreas has described the correct way to solve your problem. Make sure that the image file is in your application's JAR file, and access it using getResource or getResourceAsStream. If your application is using an API that requires a filename / pathname in the file system, you may need to extract the resource from the JAR to a temporary file, or something like that.
public class Main {
public static void main(String[] args) throws Exception {
System.out.println(getPackageParent(Main.class, false));
}
public static String getPackageParent(Class<?> cls, boolean include_last_dot)
throws Exception {
StringBuilder sb = new StringBuilder(cls.getPackage().getName());
if (sb.lastIndexOf(".") > 0)
if (include_last_dot)
return sb.delete(sb.lastIndexOf(".") + 1, sb.length())
.toString();
else
return sb.delete(sb.lastIndexOf("."), sb.length()).toString();
return sb.toString();
}
}

java.nio.file Files.move() is copying instead of moving

I'm trying to use Java NIO Files.move method to move a directory. It does copy the directory contents to the new location, but it leaves the old directory in place. I would consider this a copy operation and not a move operation.
Any ideas why this is happening? Here is my code:
Path source = FileSystems.getDefault().getPath("C:\\test-source");
Path destination = FileSystems.getDefault().getPath("C:\\test-destination");
try {
System.out.println("Moving files ...");
Files.move(source, destination, StandardCopyOption.ATOMIC_MOVE);
System.out.println("Done.");
} catch (IOException e) {
System.out.println("Moving failed: " + e.toString());
}
Again, the destination directory appears with all its contents, but the source folder remains in place.
From
this
ATOMIC_MOVE is a file operation.
public static final StandardCopyOption ATOMIC_MOVE
Move the file as an atomic file system operation.
Try StandardCopyOption.REPLACE_EXISTING
It turns out that the code is correct. But the source folder is not being deleted because another process is still working with that folder. When I eliminate the other process (an AWS S3 directory download to the source folder), the move happens as I would expect.
I was encountering this problem with Apache Lucene when trying to commit an IndexWriter. The problem was an IndexSearcher opened on the directory, resulting in a java.nio.file.atomicmovenotsupportedexception. The IndexReader constructor argument was provided by DirectoryReader.open(Directory directory). Changing to use the overload DirectoryReader.open(IndexWriter writer) fixed the problem.
I had this problem on a zipFileSystem but discovered I needed to call fileSystem.close() before it actually got removed from the zip.

Name of directory from jar file system differs from regular file system

EDIT: I'm rephrasing my original question (I keep it at the bottom)
Take a look at this code:
public static void main(String[] args) {
try {
// file in file system
Path dir = Paths.get("webapp/");
System.out.println(dir.getFileName().toString());
// file in jar
FileSystem fs = FileSystems.newFileSystem(Paths.get("ajar.jar"), null);
Path jarDir = fs.getPath("webapp/");
System.out.println(jarDir.getFileName().toString());
} catch (IOException e) {
e.printStackTrace();
}
}
First I'm getting a Path from a directory in the file system and I print its name. The output is:
webapp
Then I open a FileSystem from a jar file which contains the same folder and do the same as before. This is the corresponding output:
webapp/
Is there a reason for getting the trailing '/' in the jar's folder's name?
How do I get just the name of the folder with no slash, without having to differentiate among the two cases (jar and no jar)?
Thanks!
--- original question ---
I'm experimenting a bit with Java SE 7's nio library.
Take a look at this code:
public static void main(String[] args) {
try {
// List files in file system
Path dir = Paths.get("webapp/");
try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir)) {
for (Path file : stream) {
System.out.println(file.toString());
}
}
// List files in jar
FileSystem fs = FileSystems.newFileSystem(Paths.get("ajar.jar"), null);
Path jarDir = fs.getPath("webapp/");
try (DirectoryStream<Path> stream = Files.newDirectoryStream(jarDir)) {
for (Path file : stream) {
System.out.println(file.toString());
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
Basically first I'm creating a DirectoryStream from a folder in my file system and iterate on the content, the output is something like this:
webapp/afile.txt
webapp/afolder
Then I open a FileSystem from a jar file which contains the same folder and do the same as before. This is the corresponding output:
/webapp/afile.txt
/webapp/afolder/
Now, this is really driving me crazy... why on earth would the output differ?
I can understand the '/' prefix in the jar's output since the files are in the root relatively to the jar file system (even though I don't think I still accept it), but the '/' suffix after a directory is outrageous!
It sucks that I have to write different code to handle the two cases... Of course, here I'm exaggerating on the problem and I know it's easily fixed... but still... why??
Thanks folks!
Summary of a all the comments:
Don't rely on the string version a Paths. Use the paths directly.
To differentiate dirs form files use Files.isDirectory on the path
relative dirs have relative childs
i.e. you should be able to write code to handle both cases. This is whats nio is for.
Answer to the modified question:
The filename of a path p: p.getFileName().
The string representation of the filename of p: p.getFileName().toString().
This string has no slashes.
e.g.
fs.getPath( "abc", "def" ).getFileName().toString() -> "def"

how to access resources(Excel file) in jar file

Hi i have exported my java project as executable jar file. inside my project I am accessing a Excel file containing some data. Now I am not able to access the Excel file when I am trying to access the file.
My project structure is:
Java_Project_Folder
- src_Folder
- resources_Folder(Containing excel file)
I am accessing the excel file like
FileInputStream file=new FileInputStream(new File(System.getProperty("user.dir")
+File.separator+"resources"+File.separator+"Excel.xlsx"));
I have tried accessing this file using getResourceAsStream like:
FileInputStream file=(FileInputStream) this.getClass().getResourceAsStream
("/resources/Excel.xlsx");
But i am getting in is null exception. whats wrong can anyone help?
I bet you have no package called resources in your project.
Trying to use Class.#getResourceAsStream is the way to go. But this method does not return a FileInputStream. It returns an InputStream wich is an interface.
You should be passing the absolute name of the resource
InputStream is = getClass().getResourceAsStream("my/pack/age/Excel.xlsx");
where the excel file is located in the directory
resources/my/pack/age
The first step is to include the excel file itself in your project. You can create a resources folder like you show, but to make sure this gets included in your jar, you add the resources folder in along with your source code files so that it gets built into the jar.
Then
InputStream excelContent = this.getClass().getResourceAsStream("/resources/Excel.xlsx");
should work. From one post at least, the leading forward slash may also mess things up if you use the ClassLoader.
getClass().getResourceAsStream("/a/b/c.xml") ==> a/b/c.xml
getClass().getResourceAsStream("a/b/c.xml") ==> com/example/a/b/c.xml
getClass().getClassLoader().getResourceAsStream("a/b/c.xml") ==> a/b/c.xml
getClass().getClassLoader().getResourceAsStream("/a/b/c.xml") ==> Incorrect
ref: getResourceAsStream fails under new environment?
Also in eclipse you can set the resources folder as a source folder like this:
in the properties of your eclipse project, go to java build path, select sources, and check to see if all needed source fodlers are added (as source folders). If some are missing, just add them manually using add sources... button
ref: Java Resources Folder Error In Eclipse
I tried this and it is working for me.
My Test1 class is in default package, just check where your accessing class is in any package, if it is then go back to exact resource folder from classpath like this "../"
public class Test1 {
public static void main(String[] args) {
new Test1();
}
Test1(){
BufferedInputStream file= (BufferedInputStream) this.getClass().getResourceAsStream("resources/a.txt");
try {
System.out.println((char)file.read());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
FileInputStream file= (FileInputStream)
this.getClass().getResourceAsStream("/resources/Excel.xlsx");
Why do you need FileInputStream? Use
InputStream is = getClass().getResourceAsStream..
Secondly use "resources/Excel.xlsx"
Thirdly when constructing file like this
new
File(System.getProperty("user.dir")+File.separator+"resources"+File.separator+"Excel.xlsx"));
is hard to control slashes. use
new File("parent (userdir property)", "child (resources\Excel.xlsx)")

Categories