I've made this method that copies files from one absolute path (input directory) to another absolute path (output directory).
It doesn't give me any error, however no files are copied to the output folder.
Why would this be?
public static boolean copyFiles(String input, String output)
{
File source = new File(input);
File dest = new File(output);
try {
Files.copy(Paths.get(input), Paths.get(output), StandardCopyOption.REPLACE_EXISTING);
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
As #zapl said, Files.copy() only copies the directory.
I found the solution, by importing the Apache commons.io library.
org.apache.commons.io.FileUtils.copyDirectory(new File(input), new File(output));
This works.
For my case, the Files are copied, just that it is not shown in the project explorer (in Eclipse) so just refresh it will do.
Related
I am currently making a game which have levels which are pre-made and i currently store them in resources. I want a solution to how i can extract a folder out of a jar in production and development environment.
I have tried copying the folder by using the given method below and pass the src as File defaultWorld = new File(GameData.class.getClassLoader().getResource("worlds/").getFile());
and destination as private static File worldsDir = new File("run/worlds");
public static void copyFolder(File src, File dest) {
try {
if (src.isDirectory()) {
if (!dest.exists()) {
dest.mkdir();
}
String[] files = src.list();
for (String file : files) {
copyFolder(new File(src, file), new File(dest, file));
}
} else {
try (InputStream in = new FileInputStream(src)) {
try (OutputStream out = new FileOutputStream(dest)) {
byte[] buffer = new byte[1024];
int length;
//copy the file content in bytes
while ((length = in.read(buffer)) > 0) {
out.write(buffer, 0, length);
}
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
I expected the above method to work on both dev and production env but it throws FileNotFoundException when opening file output stream.
You cannot list resources in a jar.
Any workarounds you’re thinking of, are unreliable.
Never call the getFile() method of URL. It does not return a valid file name; it just returns the path and query portions of the URL, with any percent-escapes intact. Furthermore, jar entries are not file: URLs, so a resource path can never be a valid file name when it refers to a jar entry.
The only way to list things in a jar file is by iterating through all jar entries, but you aren’t even guaranteed to have access to your jar, because ClassLoaders are not guaranteed to be URLClassLoaders, and in general are not guaranteed to use jar: URLs.
You can’t even rely on MyApplication.class.getProtectionDomain().getCodeSource(), because getCodeSource() can return null.
If you want to copy multiple files from your jar, here are some reliable ways to do it:
Hard code the list of resources you plan to copy. It’s your application, so you know what files you’re putting in the jar.
Keep a single text file in your jar which contains a list of resource paths to copy.
Store your resources in a single zip archive which is embedded in your jar, and extract it yourself with a ZipInputStream which wraps MyApplication.class.getResourceAsStream.
Getting an error when trying to open a FileInputStream to load Map from file with .ser extension.
Constructor where I create new File and invoke method that loads map from file:
protected DriveatorImpl() {
accounts = new ConcurrentHashMap<String, Client>();
db = new File("database.ser"); // oddly this does not create a file if one does not exist
loadDB();
}
#SuppressWarnings("unchecked")
private void loadDB() {
try {
fileIn = new FileInputStream(db);
in = new ObjectInputStream(fileIn);
accounts = (Map<String, Client>) in.readObject();
in.close();
fileIn.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
I've tried to create file manually and put it in same package with class, but it does not help. What's going on?!
Thank You!
You provide a relative path for the file. That means program will look for the file relative to the working directory.
Depending on how you run the program it will be the directory you run it from (if run from Shell/Cmd) or whatever is configured in the project settings (if run from the IDE). For the latter, it depends on the IDE but usually it's the project root directory.
More info on working directory: https://en.wikipedia.org/wiki/Working_directory
More info on relative path: https://en.wikipedia.org/wiki/Path_(computing)#Absolute_and_relative_paths
Regarding creation of the file, it would create non-existing file if you were to write to it. When you read it, it expects it to exist. That means you have to create empty file (if one does not exist) before reading or simply treat exception as empty content.
The path to the file you have given might be wrong for IDE it can take relative path but from the command line, it will take the absolute path.
How do you move a file from one location to another? When I run my program any file created in that location automatically moves to the specified location. How do I know which file is moved?
myFile.renameTo(new File("/the/new/place/newName.file"));
File#renameTo does that (it can not only rename, but also move between directories, at least on the same file system).
Renames the file denoted by this abstract pathname.
Many aspects of the behavior of this method are inherently platform-dependent: The rename operation might not be able to move a file from one filesystem to another, it might not be atomic, and it might not succeed if a file with the destination abstract pathname already exists. The return value should always be checked to make sure that the rename operation was successful.
If you need a more comprehensive solution (such as wanting to move the file between disks), look at Apache Commons FileUtils#moveFile
With Java 7 or newer you can use Files.move(from, to, CopyOption... options).
E.g.
Files.move(Paths.get("/foo.txt"), Paths.get("bar.txt"), StandardCopyOption.REPLACE_EXISTING);
See the Files documentation for more details
Java 6
public boolean moveFile(String sourcePath, String targetPath) {
File fileToMove = new File(sourcePath);
return fileToMove.renameTo(new File(targetPath));
}
Java 7 (Using NIO)
public boolean moveFile(String sourcePath, String targetPath) {
boolean fileMoved = true;
try {
Files.move(Paths.get(sourcePath), Paths.get(targetPath), StandardCopyOption.REPLACE_EXISTING);
} catch (Exception e) {
fileMoved = false;
e.printStackTrace();
}
return fileMoved;
}
File.renameTo from Java IO can be used to move a file in Java. Also see this SO question.
To move a file you could also use Jakarta Commons IOs FileUtils.moveFile
On error it throws an IOException, so when no exception is thrown you know that that the file was moved.
Just add the source and destination folder paths.
It will move all the files and folder from source folder to
destination folder.
File destinationFolder = new File("");
File sourceFolder = new File("");
if (!destinationFolder.exists())
{
destinationFolder.mkdirs();
}
// Check weather source exists and it is folder.
if (sourceFolder.exists() && sourceFolder.isDirectory())
{
// Get list of the files and iterate over them
File[] listOfFiles = sourceFolder.listFiles();
if (listOfFiles != null)
{
for (File child : listOfFiles )
{
// Move files to destination folder
child.renameTo(new File(destinationFolder + "\\" + child.getName()));
}
// Add if you want to delete the source folder
sourceFolder.delete();
}
}
else
{
System.out.println(sourceFolder + " Folder does not exists");
}
Files.move(source, target, REPLACE_EXISTING);
You can use the Files object
Read more about Files
You could execute an external tool for that task (like copy in windows environments) but, to keep the code portable, the general approach is to:
read the source file into memory
write the content to a file at the new location
delete the source file
File#renameTo will work as long as source and target location are on the same volume. Personally I'd avoid using it to move files to different folders.
Try this :-
boolean success = file.renameTo(new File(Destdir, file.getName()));
Wrote this method to do this very thing on my own project only with the replace file if existing logic in it.
// we use the older file i/o operations for this rather than the newer jdk7+ Files.move() operation
private boolean moveFileToDirectory(File sourceFile, String targetPath) {
File tDir = new File(targetPath);
if (tDir.exists()) {
String newFilePath = targetPath+File.separator+sourceFile.getName();
File movedFile = new File(newFilePath);
if (movedFile.exists())
movedFile.delete();
return sourceFile.renameTo(new File(newFilePath));
} else {
LOG.warn("unable to move file "+sourceFile.getName()+" to directory "+targetPath+" -> target directory does not exist");
return false;
}
}
Please try this.
private boolean filemovetoanotherfolder(String sourcefolder, String destinationfolder, String filename) {
boolean ismove = false;
InputStream inStream = null;
OutputStream outStream = null;
try {
File afile = new File(sourcefolder + filename);
File bfile = new File(destinationfolder + filename);
inStream = new FileInputStream(afile);
outStream = new FileOutputStream(bfile);
byte[] buffer = new byte[1024 * 4];
int length;
// copy the file content in bytes
while ((length = inStream.read(buffer)) > 0) {
outStream.write(buffer, 0, length);
}
// delete the original file
afile.delete();
ismove = true;
System.out.println("File is copied successful!");
} catch (IOException e) {
e.printStackTrace();
}finally{
inStream.close();
outStream.close();
}
return ismove;
}
I am trying to add a txt file into a folder which is inside a zip file.
First, I was extracting all the contents of zip file then adding the txt file and then zipping back.
Then I read about the nio method which I can modify the zip without extracting it. Using this method I can add the txt file to the main folder of zip but I can't go deeper.
testing.zip file has res folder in it.
Here is my code:
Path txtFilePath = Paths.get("\\test\\prefs.txt");
Path zipFilePath = Paths.get("\\test\\testing.zip");
FileSystem fs;
try {
fs = FileSystems.newFileSystem(zipFilePath, null);
Path fileInsideZipPath = fs.getPath("res/prefs.txt"); //when I remover "res/" code works.
Files.copy(txtFilePath, fileInsideZipPath);
fs.close();
} catch (IOException e) {
e.printStackTrace();
}
I get the following exception:
java.nio.file.NoSuchFileException: res/
(edit to give the actual answer)
Do:
fs.getPath("res").resolve("prefs.txt")
instead of:
fs.getPath("res/prefs.txt")
The .resolve() method will do the correct thing with regards to file separators etc.
The fs.getPath("res/prefs.txt") should certainly work and you don't need to split it to fs.getPath("res").resolve("prefs.txt") as the approved answer says.
The exception java.nio.file.NoSuchFileException: res/ is slightly confusing because it mentions file but in fact directory is missing.
I had a similar problem and all I had to do was:
if (fileInsideZipPath.getParent() != null)
Files.createDirectories(fileInsideZipPath.getParent());
See full example:
#Test
public void testAddFileToArchive() throws Exception {
Path fileToAdd1 = rootTestFolder.resolve("notes1.txt");
addFileToArchive(archiveFile, "notes1.txt", fileToAdd1);
Path fileToAdd2 = rootTestFolder.resolve("notes2.txt");
addFileToArchive(archiveFile, "foo/bar/notes2.txt", fileToAdd2);
. . .
}
public void addFileToArchive(Path archiveFile, String pathInArchive, Path srcFile) throws Exception {
FileSystem fs = FileSystems.newFileSystem(archiveFile, null);
Path fileInsideZipPath = fs.getPath(pathInArchive);
if (fileInsideZipPath.getParent() != null) Files.createDirectories(fileInsideZipPath.getParent());
Files.copy(srcFile, fileInsideZipPath, StandardCopyOption.REPLACE_EXISTING);
fs.close();
}
If I remove Files.createDirectories() bit, and ensure clear start with clear test directory, I get:
java.nio.file.NoSuchFileException: foo/bar/
at com.sun.nio.zipfs.ZipFileSystem.checkParents(ZipFileSystem.java:863)
at com.sun.nio.zipfs.ZipFileSystem.newOutputStream(ZipFileSystem.java:528)
at com.sun.nio.zipfs.ZipPath.newOutputStream(ZipPath.java:792)
at com.sun.nio.zipfs.ZipFileSystemProvider.newOutputStream(ZipFileSystemProvider.java:285)
at java.nio.file.Files.newOutputStream(Files.java:216)
at java.nio.file.Files.copy(Files.java:3016)
at java.nio.file.CopyMoveHelper.copyToForeignTarget(CopyMoveHelper.java:126)
at java.nio.file.Files.copy(Files.java:1277)
at my.home.test.zipfs.TestBasicOperations.addFileToArchive(TestBasicOperations.java:111)
at my.home.test.zipfs.TestBasicOperations.testAddFileToArchive(TestBasicOperations.java:51)
Using jdk7, I am trying to use the java.nio.file.Files class to move an empty directory, let's say Bar, into another empty directory, let's say Foo
Path source = Paths.get("Bar");
Path target = Paths.get("Foo");
try {
Files.move(
source,
target,
StandardCopyOption.REPLACE_EXISTING);
} catch (IOException e) {
e.printStackTrace();
}
After executing that code snippet, I expected that the Bar directory would be in the Foo directory (...\Foo\Bar). Instead it is not. And here's the kicker, it's been deleted as well. Also, no exceptions were thrown.
Am I doing this wrong?
NOTE
I'm looking for a jdk7-specific solution.I am also looking into the problem, but I figured I'd see if there was anyone else playing around with jdk7.
EDIT
In addition to the accepted answer, here's another solution
Path source = Paths.get("Bar");
Path target = Paths.get("Foo");
try {
Files.move(
source,
target.resolve(source.getFileName()),
StandardCopyOption.REPLACE_EXISTING);
} catch (IOException e) {
e.printStackTrace();
}
I didn't realize jdk7 java.nio.file.Files is a necessity, so here is the edited solution. Please see if it works coz I have never used the new Files class before.
Path source = Paths.get("Bar");
Path target = Paths.get("Foo", "Bar");
try {
Files.move(
source,
target,
StandardCopyOption.REPLACE_EXISTING);
} catch (IOException e) {
e.printStackTrace();
}
In the javadoc for the Files.move method you will find an example where it moves a file into a directory, keeping the same file name. This seems to be what you were looking for.
Here is the solution.
http://docs.oracle.com/javase/7/docs/api/java/nio/file/Files.html
suppose we want to move a file to new directory, keeping the same file name, and replacing any existing file of that name in the directory:
Path source = ...
Path newdir = ...
Files.move(source, newdir.resolve(source.getFileName()), REPLACE_EXISTING);
//Files.move(source, newdir.resolve(source.getFileName()), StandardCopyOption.REPLACE_EXISTING);