Move/Copy File Operations in Java

Move / Copy File Operations in Java

Here's how to do this with java.nio operations:

public static void copyFile(File sourceFile, File destFile) throws IOException {
if(!destFile.exists()) {
destFile.createNewFile();
}

FileChannel source = null;
FileChannel destination = null;
try {
source = new FileInputStream(sourceFile).getChannel();
destination = new FileOutputStream(destFile).getChannel();

// previous code: destination.transferFrom(source, 0, source.size());
// to avoid infinite loops, should be:
long count = 0;
long size = source.size();
while((count += destination.transferFrom(source, count, size-count))<size);
}
finally {
if(source != null) {
source.close();
}
if(destination != null) {
destination.close();
}
}
}

How do I move a file from one location to another in Java?

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

Copy and move files in Java, explanation and comparison of different approaches

We can divide your four approaches into two types:

  1. Use a built-in standard library method (such as File.renameTo() and Files.move()).
  2. Do the work ourselves - by copying bytes from source to target.

First, note that File doesn't have a copy method, so you only have one option for built-in, standard library method when you're talking about copy.

Also note that "do the work ourselves" when renaming is going to be very bad - you're going to copy the entire file, then delete the old file. Not a good or efficient approach. In most cases, renaming/moving within the same filesystem requires just changing file metadata without actually touching the content, so it's really a lot better to use a standard library.

So you have two cases:

Renaming

The options are really using either File.renameTo() or Files.move(). No point in using streams and copying data.

File is an outdated class. It shouldn't really be used anymore. There is an excellent explanation why, which sums up to the fact that File doesn't give you any information when any of its standard methods fail, whereas Files provides you with very accurate exceptions when that happens.

Copying

You have two choices - either use Files.copy() or one of the "do it yourself" approaches.

By far, if what you are copying are actual files, your choice should be Files.copy(). There is no need to re-invent the wheel. It does exactly what you want, is well documented, you're not likely to introduce bugs accidentally. And yes, it's very efficient.

Files.copy() relies on underlying "providers" for its operation. What it means is that there are specialized vendor (or operating system) specific classes that do the operation that is the most efficient for that filesystem. Whether it's a Linux filesystem or a Windows one, the copy will be optimized for it. There are even providers for specialized cases, such as zip files, so you can copy files inside a zip, jar or war file using Files.copy() - which is a lot more complicated if you try the "do it yourself" approach.

Besides, Files.copy() checks lots of things that you might forget when you write "your own" copy. For example, did you remember to check that the file that you are reading from and the file you are writing to are not the same file? It could cause serious trouble. Files.copy() does it. It checks permissions, it checks if the target of the copy is a directory, and so on. So it's very reliable.

So why do you have the option to do "your own"? Because well, Java is a general-purpose language. You have the option to read from a file, the option to write to a file, so you can write your own "copy" method. That doesn't mean you should.

Note that in your "approach #3", the "source" file is not actually a file! It's produced from an Image URI, which means it could be a network source. When your source is not a file, but a stream or channel based on a socket, database BLOB, web server request etc., you can't really use Files.copy(). This is where you'd need to write your own.

Actually, Files also has options for copying from a file to an OutputStream or from an InputStream to a file, so if one side of the copy is a stream and the other a file, you can use that. It will be readable, safe, and throw meaningful exceptions.

So write your own copy:

  • when you need to move data from sources to targets which are not files,
  • when you need to filter or process the data somehow rather than copy as-is from source to target,
  • when you are using old versions of Java, prior to 1.7. In this case, channels would probably be better than streams.

How to copy file from one location to another location?

You can use this (or any variant):

Files.copy(src, dst, StandardCopyOption.REPLACE_EXISTING);

Also, I'd recommend using File.separator or / instead of \\ to make it compliant across multiple OS, question/answer on this available here.

Since you're not sure how to temporarily store files, take a look at ArrayList:

List<File> files = new ArrayList();
files.add(foundFile);

To move a List of files into a single directory:

List<File> files = ...;
String path = "C:/destination/";
for(File file : files) {
Files.copy(file.toPath(),
(new File(path + file.getName())).toPath(),
StandardCopyOption.REPLACE_EXISTING);
}

Java Moving Files

import java.io.*

This should fix your problem. Just remove the 'n' and use a different library.
The class File (Documentation) has some pretty good methods for file operations.

isDirectory() lets you check if your path is correct.

On the other hand you could use this method:

import static java.nio.file.StandardCopyOption.*; 
Files.copy(source, target, REPLACE_EXISTING);

The method copies all files from source to target.

Moving a file in processing

Take a look at this:

import java.nio.file.*;

String source = "C:\\test\\1.jpeg";
String newdir = "C:\\test123\\1.jpeg";

void setup() {
try {
Path temp = Files.move(Paths.get(source), Paths.get(newdir));
} catch (IOException e) {
print(e);
}
}

Couple of points - use \\ instead of a single \ when specifying the paths. Secondly, getFileName() can only be applied to a Path object, not a String, and that caused your error in the question. Same, by the way, with the resolve(String s) method, it can only be applied to a Path, not String.

Using Paths:

import java.nio.file.*;

Path source = Paths.get("...");
Path newdir = Paths.get("...");

void setup() {
try {
Files.move(source, newdir);
} catch (IOException e) {
print(e);
}
}


Related Topics



Leave a reply



Submit