0

Unzipping multipart file with and without subdirectories since I am not giving any instruction to user to how to zip the file therefore I need to find/search all files from Zip file which might have directories and subdirectories and keeping all files in a seperate different folder.

So basically it is some kind of smart unzipping where it detects the directory using ZipEntry then skip and find file to write in the folder.

I have written a code but I am not even near it since I am getting only one file that too which has no directories in it.

String outputPath="C:\\Users\\Plootus\\exceldocs\\";
    FileSystem fileSystem = FileSystems.getDefault();
    try
    {
        ZipInputStream zis=new ZipInputStream(serverFile.getInputStream());
        BufferedInputStream bis=null;
        InputStream is=null;
        //Get file entries

        ZipEntry entry=null;
        //We will unzip files in this folder

        while ( (entry = zis.getNextEntry()) != null ) {
          System.out.println(entry.getName());
            if(!entry.isDirectory()) {
                System.out.println(entry.getName());
                is = zis;
                bis = new BufferedInputStream(is);
                String uncompressedFileName = outputPath+toolName+entry.getName();
                Path uncompressedFilePath = fileSystem.getPath(uncompressedFileName);
                Files.createFile(uncompressedFilePath);
                FileOutputStream fileOutput = new FileOutputStream(uncompressedFileName);
                while (bis.available() > 0)
                {
                    fileOutput.write(bis.read());
                }
                fileOutput.close();
                System.out.println("Written :" + entry.getName());
               bis.close();
               is.close();

            }
          }
        zis.close();
        return true;
        }

    catch(IOException e)
    {
        return false;
    }
    return false;

Objective: Zip file contains possible entries

1.) abc.zip(Multipart File)

    -folder1-arkan.csv,dan.csv,kud.csv
  1. abc.zip(Mutlipart File)

    -folder1--bio.csv(file)-folder-2(inside folder1)-arkan.csv,dan.csv,kud.csv
    
  2. abc.zip(Mutlipart File)

    -arkan.csv,dan.csv,kud.csv
    
Kramer
  • 389
  • 8
  • 34
  • I'm not completely sure I understand. Your users upload a single zip file that contains multiple files? (Did you mean something specific by 'multipart'?) And you want to ignore the user's provided directory structure in the .zip and create your own? And you want to put each extracted file in a separate folder? (in case of name clashes?) You said separate directories but I don't see that in your code. – Rup Aug 13 '18 at 09:51
  • I can't see you creating any directories at all - does ZipEntry.getName() return a full path or just the final name component? If it's the full path I'd be surprised if Files.createFile() will make missing directories in the path for you automatically. – Rup Aug 13 '18 at 09:51
  • @Rup No, I want all the File means any File not Folder to get unzipped and kept in the seperate folder with no hierarchies within them. I will update the question again to show possible structure. Also Files.createFile() will create file in the directory because I passed path inside it which has outpath+entry.getname(); and yes entry.getname() gets you file name only I guess – Kramer Aug 13 '18 at 10:01
  • 2
    Do you mean that you want to unzip ALL files into a single folder no matter if the ZIP file contains folder structure? – Jokkeri Aug 13 '18 at 10:12
  • @Jokkeri Exactly but with Multipart File not local file – Kramer Aug 13 '18 at 10:15
  • @Plootus check this answer: https://stackoverflow.com/a/1399432/2996452. I think there is quite good example for PRESERVING the folders. With some changes I think you are able to modify it to not preserve folders – Jokkeri Aug 13 '18 at 10:30
  • @Rup I thought the same when I saw your comment but it still extracting one file from it and updated the above code also – Kramer Aug 13 '18 at 10:45
  • 1
    @Plootus not sure if that is anyway meaningful as you get inputstream from it and handle the entries as ZipEntry... – Jokkeri Aug 13 '18 at 11:27

1 Answers1

1

Instead of extracting from MultipartFile and handling entries as ZipEntry(as told by @Jokkeri) is not possible therefore I found other way to do it.

I will save that file and when the operation is done then delete it.

After receiving multipart file I saved the file using File object(saveZip)

        try(ZipFile file = new ZipFile(saveZip.getCanonicalPath()))
        {

            FileSystem fileSystem = FileSystems.getDefault();
            //Get file entries
            Path inputpath=fileSystem.getPath(file.getName());
            Enumeration<? extends ZipEntry> entries = file.entries();

          //We will unzip files in this folder
                File directory=new File(zipFilePath.concat(username+"-"+toolName));

                if(!directory.exists()) {
                    directory.mkdir();
                }

            //Iterate over entries
            while (entries.hasMoreElements())
            {
                ZipEntry entry = entries.nextElement();
                String abc[]=entry.getName().split("/");

                //Else create the file
                if(!entry.isDirectory())
                {
                    InputStream is = file.getInputStream(entry);
                    BufferedInputStream bis = new BufferedInputStream(is);
                    String uncompressedFileName = zipFilePath +username+"-"+toolName+"/"+ abc[abc.length-1];
                    Path uncompressedFilePath = fileSystem.getPath(uncompressedFileName);
                    if(Files.notExists(uncompressedFilePath)) 
                    Files.createFile(uncompressedFilePath);
                    FileOutputStream fileOutput = new FileOutputStream(uncompressedFileName);
                    while (bis.available() > 0)
                    {
                        fileOutput.write(bis.read());
                    }
                    fileOutput.close();
                    System.out.println("Written :" + entry.getName());
                    is.close();
                    bis.close();
                }
            }
            file.close();
            Files.deleteIfExists(inputpath);
        return true;
        }catch(IOException e)
        {
            e.printStackTrace();
            return false;
        }
Kramer
  • 389
  • 8
  • 34