Как разбить файл на части с помощью Java?

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

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

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

2 ответов


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

например (код не идеален, но он должен помочь понять процесс)

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 МБ

после разделения у меня было 13 файлов

  • myFile.mp4.001 - myFile.mp4.012 С размером 1 МБ
  • myFile.mp4.013 С размером 806 КБ

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

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));
}

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

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