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);
}
Related
How can I copy a file from one folder to another using java? I have tried to use
org.apache.commons.io.FileUtils.copyFileToDirectory(pasteItem, destinationPath);
This works if the destination folder does not contain a file with same name. It throws an IOException if I try to paste the file into the folder. However, is there any way to handle this? May be I want to just paste the file with name renamed automatically to pasteItem(1) or something like that. Please suggest.
In fact, I'm getting a new name for the file if the file with same name already exists. I'm not able to figure how to copy the file and then rename. If I rename first and then copy, I'll lose the original file. If I try to copy the file first, then it is giving an exception saying File with same name already exists!
You can use the Java.io.File class.
It has a method that checks if a fill exists.
Example:
//create files
File original =new File("C:\\test\\testfile.txt");
File destination =new File("D:\\test\\file.txt");
//check if file exists.
for(int x=0;destination.exists()==true;x++){
//if file exists then add 1 to file name and check if exists again.
destination=new File("D\\test\\file"+x+".txt");
}
//copy file.
Files.copy(origional, destination, StandardCopyOption.REPLACE_EXISTING);
There is an overloaded version of this method using a boolean flag which will overwrite the destination file if true.
public static void copyFileToDirectory(File srcFile,
File destDir,
boolean preserveFileDate)
throws IOException
http://commons.apache.org/proper/commons-io/apidocs/org/apache/commons/io/FileUtils.html#copyFileToDirectory(java.io.File, java.io.File, boolean)
Please refer this site to copy a file from one folder to another.
http://www.mkyong.com/java/how-to-move-file-to-another-directory-in-java/
I am not sure about rename the file automatically
I have a file dateTesting.java . the path's directory is as follows: D:\workspace\Project1\src\dateTesting.java . I want the full path of this file as "D:\workspace\Project1\src" itself but when I use any of the following code, i get only "D:\workspace\Project1" . the src part is not coming.
System.out.println(System.getProperty("user.dir"));
File dir2 = new File(".");
System.out.println(dir2.getCanonicalPath().toString());
System.out.println(dir2.getAbsolutePath());
How can I get the full path as "D:\workspace\Project1\src" ? I'm using eclipse ide 3.5
Thank you
dateTesting.java is a Java source file which is not available after compilation to bytecode. The source directory it was in is not available, too.
dir2 is the File of the directory you execute the .class file in. It seams that this happens to be D:\workspace\Project1 but you can't rely on this.
Your dir2 points to working directory (new File(".")). You can't get the location of your sources this way. Your file could sit inside the package (e.g. your.company.date.dateTesting). You should just manually concat the "src" to current working directory and then replace file package dots (.) with File.pathSeparator. In that way you will build the full path to your file.
String fullFilePath = "H:\\Shared\\Testing\\abcd.bmp";
File file = new File(fullFilePath);
String filePath = file.getAbsolutePath().substring(0,fullFilePath.lastIndexOf(File.separator));
System.out.println(filePath);
Output:
H:\Shared\Testing
If you are doing this to try to read a file from the classpath, then check out this answer:
How to really read text file from classpath in Java
Essentially you can do this
InputStream in = this.getClass().getClassLoader()
.getResourceAsStream("SomeTextFile.txt");
Otherwise, if you have some other requirement, one option is to pass through the src directory as a JVM arg when the application begins and then just read it back.
/** The actual file running */
public static final File JAR_FILE = new File(MyClass.class.getProtectionDomain().getCodeSource().getLocation().getPath();
/** The path to the main folder where the file .jar is run */
public static final String BASE_DIRECTORY = (JAR_FILE != null ? JAR_FILE.getAbsolutePath().replace(JAR_FILE.getName(), "") : "notFound");
This will work for you both in normal java execution and jar execution. This is the solution I am using in my project.
I have this issue of accessing a file in one of the parent directories.
To explain, consider the following dir structure:-
C:/Workspace/Appl/src/org/abc/bm/TestFile.xml
C:/Workspace/Appl/src/org/abc/bm/tests/CheckTest.java
In the CheckTest.java I want to create a File instance for the TestFile.xml
public class Check {
public void checkMethod() {
File f = new File({filePath value I want to determine}, "TestFile.xml");
}
}
I tried a few things with getAbsolutePath() and the getParent() etc but was getting a bit complicated and frankly I think I messed it up.
The reason I don't want to use "C:/Workspace/Appl/src/org/abc/bm" while creating the File instance is because the C:/Workspace/Appl is not fixed and in all circumstances will be different at runtime and basically I don't want to hard-code.
What could be the easiest and cleaner way to achieve this ?
Thank you.
You should load it from Classpath in this case.
In your CheckTest.java, try
FileInputStream fileIs = new FileInputStream(CheckTest.class.getClassLoader().getResourceAsStream("org/abc/bm/TestFile.xml");
Use System.getProperty to get the base dir or you set the base.dir during application launch
java -Dbase.dir=c:\User\pkg
System.getProperty("base.dir");
and use
System.getProperty("file.separator");
What could be the easiest and cleaner way to achieve this ?
For accessing static resources use:
URL urlToResource = this.getClasS().getResource("path/to/the.resource");
If the resource is expected to change, write it to a sub-directory of user.home, where it is easy to locate later.
First of all, you can't get a reference to the source file path on runtime.
But, you can access the resrources included at your classpath (where you complied .class files will be).
Normally, your compiler will copy the xml file included at your srouce directory into the build directory, so at last, you could end up having something like this:
C:/Workspace/Appl/classes/org/abc/bm/TestFile.xml
C:/Workspace/Appl/classes/org/abc/bm/tests/CheckTest.class
Then, with your classpath pointing to the compiled classes root dir, you get the resources from this directory, using the ClassLoader.getResource method (or the equivalent Class.getResource() method).
public class Check {
public void checkMethod() {
java.net.URL fileURL=this.getClass().getResource("/org/abc/bm/tests/TestFile.xml");
File f=new File( fileURL.toURI());
}
}
One could do this:
String pathOfTheCurrentClass = this.getClass().getResource(".").getPath();
File file = new File(pathOfTheCurrentClass + "/..", "Testfile.xml");
or
String pathOfTheCurrentClass = this.getClass().getResource(".").getPath();
File filePath = new File(pathOfTheCurrentClass);
File file = new File(filePath.getParent(), "Testfile.xml");
But as Tomas Naros points out this gives you the file located in the build path.
Did you try
URL some=Test.class.getClass().getClassLoader().getResource("org/abc/bm/TestFile.xml");
File file = new File(some.getFile());
The code basically allows the user to input the name of the file that they would like to delete which is held in the variable 'catName' and then the following code is executed to try and find the path of the file and delete it. However, it doesn't seem to work, as it won't delete the file this way. Is does however delete the file if I input the whole path.
File file = new File(catName + ".txt");
String path = file.getCanonicalPath();
File filePath = new File(path);
filePath.delete();
If you're deleting files in the same directory that the program is executing in, you don't need specify a path, but if it's not in the same directory that your program is running in and you're expecting the program to know what directory your file is in, that's not going to happen.
Regarding your code above: the following examples all do the same thing. Let's assume your path is /home/kim/files and that's where you executed the program.
// deletes /home/kim/files/somefile.txt
boolean result = new File("somefile.txt").delete();
// deletes /home/kim/files/somefile.txt
File f = new File("somefile.txt");
boolean result = new File(f.getCanonicalPath()).delete();
// deletes /home/kim/files/somefile.txt
String execPath = System.getProperty("user.dir");
File f = new File(execPath+"/somefile.txt");
f.delete();
In other words, you'll need to specify the path where the deletable files are located. If they are located in different and changing locations, then you'll have to implement a search of your filesystem for the file, which could take a long time if it's a big filesystem. Here's an article on how to implement that.
Depending on what file you want to delete, and where it is stored, chances are that you are expecting Java to magically find the file.
String catName = 'test'
File file = new File(catName + '.txt');
If the program is running in say C:\TestProg\, then the File object is pointing to a file in the location C:\TestProg\test.txt. Since the file object is more of just a helper, it has no issues with pointing to a non-existent file (File can be used to create new files).
If you are trying to delete a file that is in a specific location, then you need to prepend the folder name to the file path, either canonically, or relative to the execution location.
String catName = 'test'
File file = new File('myfiles\\'+ catName +'.txt');
Now file is looking in C:\TestProg\myfiles\test.txt.
If you want to find that file anywhere, then you need a recursive search algorithm, that will traverse the filesystem.
The piece of code that you provided could be compacted to this:
boolean success = new File(catName + ".txt").delete();
The success variable will be true if the deletion was successful. If you do not provide the full absolute path (e.g. C:\Temp\test for the C:\Temp\test.txt file), your program will assume that the path is relative to its current working directory - typically the directory from where it was launched.
You should either provide an absolute path, or a path relative to the current directory. Your program will not try to find the file to delete anywhere else.
I'm using Spring's Resource abstraction to work with resources (files) in the filesystem. One of the resources is a file inside a JAR file. According to the following code, it appears the reference is valid
ResourcePatternResolver resourceResolver = new PathMatchingResourcePatternResolver();
// The path to the resource from the root of the JAR file
Resource fileInJar = resourcePatternResolver.getResources("/META-INF/foo/file.txt");
templateResource.exists(); // returns true
templateResource.isReadable(); // returns true
At this point, all is well, but then when I try to convert the Resource to a File
templateResource.getFile();
I get the exception
java.io.FileNotFoundException: class path resource [META-INF/foo/file.txt] cannot be resolved to absolute file path because it does not reside in the file system: jar:file:/D:/m2repo/uic-3.2.6-0.jar!/META-INF/foo/file.txt
at org.springframework.util.ResourceUtils.getFile(ResourceUtils.java:198)
at org.springframework.core.io.ClassPathResource.getFile(ClassPathResource.java:174)
What is the correct way to get a File reference to a Resource that exists inside a JAR file?
What is the correct way to get a File
reference to a Resource that exists
inside a JAR file?
The correct way is not doing that at all because it's impossible. A File represents an actual file on a file system, which a JAR entry is not, unless you have a special file system for that.
If you just need the data, use getInputStream(). If you have to satisfy an API that demands a File object, then I'm afraid the only thing you can do is to create a temp file and copy the data from the input stream to it.
If you want to read it, just call resource.getInputStream()
The exception message is pretty clear - the file does not reside on the file-system, so you can't have a File instance. Besides - what will do do with that File, apart from reading its content?
A quick look at the link you provided for Resource documentation, says the following:
Throws: IOException if the resource cannot be resolved as absolute file path,
i.e. if the resource is not available in a file system
Maybe the text file is inside a jar? In that case you will have to use getInputStream() to read its contents.
Just adding an example to the answers here. If you need a File (and not just the contents of it) from within your JAR, you need to create a temporary file from the resource first. (The below is written in Groovy):
InputStream inputStream = resourceLoader.getResource('/META-INF/foo/file.txt').inputStream
File tempFile = new File('file.txt')
OutputStream outputStream = new FileOutputStream(tempFile)
try {
IOUtils.copy(inputStream, outputStream)
} catch (IOException e) {
// Handle exception
} finally {
outputStream.close()
}