Задачка копирование файлов в свое время была хорошим тестом для программистов.
1. Streams.
До появления пакета NIO (New I/O, версия Java 1.4) многие использовали обычные потоки.
public static void copy(File source, File dest) throws IOException {
FileInputStream is = new FileInputStream(source);
try {
FileOutputStream os = new FileOutputStream(dest);
try {
byte[] buffer = new byte[4096];
int length;
while ((length = is.read(buffer)) > 0) {
os.write(buffer, 0, length);
}
} finally {
os.close();
}
} finally {
is.close();
}
}
2. New I/O
В 2000-ном году появился пакет java.nio. Акроним NIO означает New I/O (новый ввод/ввывод). Отчасти я согласен с мнением, что название было выбрано не очень удачным, т.к. не сложно было предположить, что пройдет время и будет нелепо называть новым пакет 12-летней давности.
С помощью NIO копирование файлов смотрелось более изящно, решение эволюционировало следующим образом:
public static void copy(File source, File dest) throws IOException {
FileChannel sourceChannel = new FileInputStream(source).getChannel();
try {
FileChannel destChannel = new FileOutputStream(dest).getChannel();
try {
destChannel.transferFrom(sourceChannel, 0, sourceChannel.size());
} finally {
destChannel.close();
}
} finally {
sourceChannel.close();
}
}
Легко видеть, что здесь мы избавились от цикла, используем “новое” API и сократилось количество кода.
3. Apache Commons IO.
Тем не менее, многих ленивых программистов такое развитие не особо впечатлило и те кто знал, продолжил использовать Apache Commons IO.
public static void copy(File source, File dest) throws IOException {
FileUtils.copyFile(source, dest);
}
Единственным неудобством была необходимость в дополнительной сторонней библиотеке. Тем не менее, поскольку библиотека предоставляла программистам еще много другого удобного API для работы с I/O, по моим наблюдениям файл commons-io-*.jar стал присутствовать во многих крупных проектов того времени.
4. Java 7.
Революция произошла с выходом Java 7, релиз который был сделан уже Oracle, а не Sun Microsystems.
Появился класс Files, с помощью которого копирование файлов стало не намного сложнее чем commons-io:
public static void copy(File source, File dest) throws IOException {
Files.copy(source.toPath(), dest.toPath());
}
При этом не нужно прописывать в мавене дополнительную зависимость.
Понятно, что это доступно только для Java 7 и предыдущие ее версии во всю используются многими компаниями. Тем не менее, в связи с недавней новостью о том, что Oracle выпустил недавно свое последнее публичное обновление для Java 6, возможно многие все-таки будут постепенно переползать на семерку.