2012-06-02 2 views
7

У меня возник какой-то странный вопрос. Мне нужно знать, как я могу разбить данный файл на мелкие кусочки, используя Java (любой тип файла). Тогда я могу поместить эти ряды в число компакт-дисков, pendrives и забрать. Я попробовал это, используя this wayКак разбить файл на куски с помощью Java?

Но, как большинство пользователей прокомментировали, то, что я пытаюсь, невозможно достичь таким образом. Итак, я решил задать новый вопрос для получения правильного метода для разбивки файлов.

Когда я разбиваю файл на куски (предположим, 30 штук), должен быть способ собрать их обратно и создать исходный файл. Пожалуйста помоги.

ответ

25

Прочитайте части байтов в байтовый массив и сохраните их в новых файлах, когда буфер заполнен или это конец файла.

Например (код не является совершенным, но это должно помочь пониманию процесса)

class FileSplit { 
    public static void splitFile(File f) throws IOException { 
     int partCounter = 1;//I like to name parts from 001, 002, 003, ... 
          //you can change it to 0 if you want 000, 001, ... 

     int sizeOfFiles = 1024 * 1024;// 1MB 
     byte[] buffer = new byte[sizeOfFiles]; 

     String fileName = f.getName(); 

     //try-with-resources to ensure closing stream 
     try (FileInputStream fis = new FileInputStream(f); 
      BufferedInputStream bis = new BufferedInputStream(fis)) { 

      int bytesAmount = 0; 
      while ((bytesAmount = bis.read(buffer)) > 0) { 
       //write each chunk of data into separate file with different number in name 
       String filePartName = String.format("%s.%03d", fileName, partCounter++); 
       File newFile = new File(f.getParent(), filePartName); 
       try (FileOutputStream out = new FileOutputStream(newFile)) { 
        out.write(buffer, 0, bytesAmount); 
       } 
      } 
     } 
    } 

    public static void main(String[] args) throws IOException { 
     splitFile(new File("D:\\destination\\myFile.mp4")); 
    } 
} 

размер myFile.mp4 = 12,7 MB

После раскола у меня было 13 файлов

  • myFile.mp4.001 - myFile.mp4.012 с размером 1 MB
  • myFile.mp4.013 с размером 806 KB

Если вы хотите, чтобы объединить эти файлы, которые вы можете использовать

public static void mergeFiles(List<File> files, File into) 
     throws IOException { 
    try (FileOutputStream fos = new FileOutputStream(into); 
     BufferedOutputStream mergingStream = new BufferedOutputStream(fos)) { 
     for (File f : files) { 
      Files.copy(f.toPath(), mergingStream); 
     } 
    } 
} 

Вы также можете создать некоторые дополнительные методы, чтобы сделать вашу жизнь проще. Например, метод, который будет создавать список файлов, содержащих отдельные части, на основе имени (и местоположения) одного из этих файлов.

public static List<File> listOfFilesToMerge(File oneOfFiles) { 
    String tmpName = oneOfFiles.getName();//{name}.{number} 
    String destFileName = tmpName.substring(0, tmpName.lastIndexOf('.'));//remove .{number} 
    File[] files = oneOfFiles.getParentFile().listFiles(
      (File dir, String name) -> name.matches(destFileName + "[.]\\d+")); 
    Arrays.sort(files);//ensuring order 001, 002, ..., 010, ... 
    return Arrays.asList(files); 
} 

С этим методом мы можем перегружать mergeFiles метод использовать только один из файлов File oneOfFiles вместо всего списка List<File> (мы будем генерировать этот список, основанный на одном из файлов)

public static void mergeFiles(File oneOfFiles, File into) 
     throws IOException { 
    mergeFiles(listOfFilesToMerge(oneOfFiles), into); 
} 

Вы можете также перегрузить эти методы использовать String вместо File (мы будем обернуть каждую строку в файл, когда это необходимо)

public static List<File> listOfFilesToMerge(String oneOfFiles) { 
    return listOfFilesToMerge(new File(oneOfFiles)); 
} 

public static void mergeFiles(String oneOfFiles, String into) throws IOException{ 
    mergeFiles(new File(oneOfFiles), new File(into)); 
} 
+0

Отлично. Спасибо alot :) –

+0

А как насчет слияния? –

+0

@ldce Я обновил свой ответ. Надеюсь, вам это понравится. – Pshemo

3

Прочитано & пишет потоки как сырьевые byte[]. Избегайте текстовых потоков и считывателей.

В вашем последнем вопросе вы, по-видимому, разбивали файлы в соответствии с «строкой». Чтобы воспроизвести это поведение, просто используйте фиксированный размер byte[] для чтения. Обратите внимание на предупреждения в комментариях к вашему последнему вопросу, чтобы проверить, сколько байтов считывается. A byte[2^16] не обязательно заполняется одним чтением.

+0

Дорог Эндрю, я почти устал от этого. Если вы зададите мне вопросы, вы можете задать другой вопрос, который я задал о чем-то подобном этому месяцу назад. Итак, не могли бы вы быть добрыми, чтобы дать мне пример кода? Это будет очень полезно :) –

Смежные вопросы