Compress files into independent parts ( no need to be tight to unzip)

Asked

Viewed 305 times

0

In my application I can compress a folder and its contents, this content is the result of manipulation of pdf, jpg and xls. But I needed to split it into parts ( the compressed file cannot be larger than for example 10 MB), but so that one part can be extracted without the need of the other. I can also with another class compress in parts but with the need for all parts to be together in order to extract. This class is the one I use to create a single file.

import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

public class ZipCompress {
    public static void compress(String dirPath, String zipName,String path) {
        Path sourceDir = Paths.get(dirPath);
        String zipFileName = path+zipName.concat(".zip");
        try {
            ZipOutputStream outputStream = new ZipOutputStream(new FileOutputStream(zipFileName));
            Files.walkFileTree(sourceDir, new SimpleFileVisitor<Path>() {
                @Override
                public FileVisitResult visitFile(Path file, BasicFileAttributes attributes) {
                    try {
                        Path targetFile = sourceDir.relativize(file);
                        outputStream.putNextEntry(new ZipEntry(targetFile.toString()));
                        byte[] bytes = Files.readAllBytes(file);
                        outputStream.write(bytes, 0, bytes.length);
                        outputStream.closeEntry();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    return FileVisitResult.CONTINUE;
                }
            });
            outputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Update:

I added the method I am working on to first separate the files with each "x Mb" and then compress the folders individually. I still could not put in a loop where each "x Mb" is created a new folder and the files are then copied to this new folder.

Another detail is that I realized that it reaches 10 MB my method to copy the files even if it is being used if (fileSizeInMB > 5), should the way it is, copy them all. (Solved by changing from :if (fileSizeInMB > 5) for if (fileSizeInMB >= 5), updated method in question.

Update:

Solved to list the files from the folder ( folder that matches the files that I want to compress), after this create a new folder and move the files until the accumulated size is "x MB", each time the accumulated size of the files is greater than "x Mb" create a new folder and move the files to this new folder. The code can certainly be improved, I accept critical suggestions.

public void listNovo() throws IOException {
File directory = new File("D:\\Faturas\\Gerados\\");
String pasta = "\\Pasta";
long length = 0;
long fileSizeInBytes = 0;
long fileSizeInMB = 0;
long fileSizeInKB = 0;
int count = 0;

File[] files = directory.listFiles();
for (File file : directory.listFiles()) {
    String fileName1 = file.getName();
    if (file.isFile()) {
        length += file.length();
        System.out.println("file:" + file.getName());
        fileSizeInBytes = length;
        fileSizeInKB = fileSizeInBytes / 1024;
        fileSizeInMB = fileSizeInKB / 1024;
        System.out.println("fileSizeInMB:" + fileSizeInMB);
        if (fileSizeInMB < 5) {
            File diretorio = new File(jTCaminho.getText() + pasta + count);
            if (!diretorio.exists()) {
                new File(jTCaminho.getText() + pasta + count).mkdir();
                Files.move(file.toPath(), Paths.get(diretorio.toString(), fileName1), REPLACE_EXISTING);
                length += fileSizeInMB;
            }
            else if (diretorio.exists()) {
                Files.move(file.toPath(), Paths.get(diretorio.toString(), fileName1), REPLACE_EXISTING);
                length += fileSizeInMB;
            }
        }

        if (fileSizeInMB >= 5) {
            fileSizeInMB = 0;
            length=0;
               count++;
            if (fileSizeInMB < 5) {
                File diretorio = new File(jTCaminho.getText() + pasta + count);
                if (!diretorio.exists()) {
                    new File(jTCaminho.getText() + pasta + count).mkdir();
                    Files.move(file.toPath(), Paths.get(diretorio.toString(), fileName1), REPLACE_EXISTING);
                    length += fileSizeInMB;
                }
               else if (diretorio.exists()) {
                    Files.move(file.toPath(), Paths.get(diretorio.toString(), fileName1), REPLACE_EXISTING);
                    length += fileSizeInMB;
                }
            }
        }
    }//fim isFile
}//fim directoryListfile

}

  • 1

    I’m pretty sure I can’t. To get what you want, create different zip files. Because jpg and pdf files already use compression (I’m not sure about xls) the compression will be very small and it is not difficult to estimate the size of the compressed file. You select a 9 MB file and compact. Or try using the tar utility, it may be that it meets your need.

  • @Piovezan actually the question is about compacting in independent parts, without the need to have all the parts together afterwards to be able to unpack. I already left for an approach where I check the accumulated size of the files and, when it reaches 10 MB I create another folder,and start adding the remaining files in this other folder. Thank you for your help, I’ll soon put the new partial code I’m working on.

  • 1

    That’s what I was talking about.

  • @Piovezan added the code I’m working on at the moment.

No answers

Browser other questions tagged

You are not signed in. Login or sign up in order to post.