вторник, 27 сентября 2011 г.

Операции с файлами в Java

На днях делал небольшой файловый менеджер и пришлось погрузиться в манипуляции с файлами. Задача в принципе тривиальная, если не работать с директориями или использовать Apache Commons IO. Но для проекта "весом" в 60 Kb использовать 155 Kb библиотеку для вызова трёх методов... Не наш это путь, верно? Сделаем всё сами.
Начнём с удаления файлов:

  public static void delete(String path_from) {
    File f = new File(path_from);
    if (f.isDirectory()) {
      String[] child = f.list();
      for (int i = 0; i < child.length; i++) {
        delete(path_from + "/" + child[i]);
      }
      f.delete();
    } else {
      f.delete();
    }
  }



Это рекурсивный метод: Он вызывает сам себя для каждого вложенного файла или директории, а затем удаляет и саму директорию. файл он удаляет сразу.
Копирование реализуется ненамного сложнее:

  public static void copy(String from, String to) throws FileNotFoundException, IOException {
    String fname = from.substring(from.lastIndexOf("/") + 1);
    File f = new File(from);
    if (f.isDirectory()) {
      if (new File(to + "/" + fname).exists()) {
        throw new IOException("Directory " + to + "/" + fname + " already exists");
      }
      mkdir(to + "/" + fname);
      String[] child = f.list();
      for (int i = 0; i < child.length; i++) {
        copy(from + "/" + child[i], to + "/" + fname);
      }
    } else {
      if (new File(to + "/" + fname).exists()) {
        throw new IOException("File " + to + "/" + fname + " already exists");
      }
      FileChannel srcChannel = new FileInputStream(f).getChannel();
      FileChannel destChannel = new FileOutputStream(to + "/" + fname).getChannel();
      srcChannel.transferTo(0, srcChannel.size(), destChannel);
    }
  }


Тут добавлены проверки на существование файла и директории перед их созданием. Копирование файла через FileChannel предпочтительнее ибо быстрее.