Bernice
Bernice

Reputation: 2592

Compressing a folder into a ZipFile

I have this Java method to upload a file. I am trying to cater for users trying to upload a folder by compressing that folder into a zip file and upload it instead. For some reason in my case file.isDirectory() and file.isFile() are not working correctly.. even though the filename does not contain any extension, file.isFile() is returning true and isDirectory() returns false. Also directory.list() is also acting weird by returning null.

What can be the problem? Am I doing something wrong?

public File uploadFile(FileItem item, String filename, int ticket_id) throws IOException
{
    FileOutputStream out = null;
    InputStream fileContent = null;
    File file = null;

    try
    {
        //fullpath returns C://MyDocuments//zerafbe//Documents//apache-tomcat-7.0.29//webapps//attachments//t50\test

        StringBuffer fullPath = new StringBuffer();
        fullPath.append(Attachment.attachments_path); 
        fullPath.append("t"); 
        fullPath.append(Integer.toString(ticket_id)); 
        fullPath.append(File.separator);
        fullPath.append(filename);

        System.out.println("filename " + filename);

        file = new File(fullPath.toString());

        if (!file.exists())
        {
            // if directory does not exist, create it
            file.getParentFile().mkdirs();
        }

        if (file.isFile())
        {
            // if file is not a folder                  
            out = new FileOutputStream(file);
            fileContent = item.getInputStream();

            int read = 0;
            final byte[] bytes = new byte[1024];

            // read all the file and write it to created file
            while ((read = fileContent.read(bytes)) != -1) 
            {
                out.write(bytes, 0, read);
            }
        }
        else if (file.isDirectory())
        {
            ZipFile appZip = new ZipFile(fullPath.toString());
            appZip.generateFileList(file);
            appZip.zipIt(filename + ".zip");
        }
    }
    catch (FileNotFoundException e)
    {
        LogFile.logError("[FileUpload.uploadFile()] " + e.getMessage());
    }
    catch (IOException e1)
    {
        LogFile.logError("[FileUpload.uploadFile()] " + e1.getMessage());
    }
    finally
    {
        if (out != null)
        {
            out.close();
        }

        if (fileContent != null)
        {
            fileContent.close();
        }
    }

    return file;
}

This is the ZipFile class I am using

public class ZipFile 
{
    List<String> fileList = null;
    String source_folder = "";

    public ZipFile(String source_folder)
    {
        fileList = new ArrayList<String>();
        this.source_folder = source_folder;
    }

    public void zipIt(String zipFile)
    {
        byte[] buffer = new byte[1024];
        String source = "";

        try
        {
            try
            {                     
                source = source_folder.substring(source_folder.lastIndexOf("\\") + 1, source_folder.length());
            }
            catch(Exception e)
            {
                source = source_folder;
            }

            FileOutputStream fos = new FileOutputStream(zipFile);
            ZipOutputStream zos = new ZipOutputStream(fos);

            for (String file : this.fileList)
            {
                ZipEntry ze = new ZipEntry(source + File.separator + file);
                zos.putNextEntry(ze);

                FileInputStream in = new FileInputStream(source_folder + File.separator + file);

                int len;
                while ((len = in.read(buffer)) > 0)
                {
                    zos.write(buffer, 0, len);
                }

                in.close();
            }

            zos.closeEntry();
            //remember close it
            zos.close();
        } 
        catch(IOException ex)
        {
           ex.printStackTrace();   
        }
    }

    public void generateFileList(File node)
    {
        // add file only
        if(node.isFile())
        {           
            fileList.add(generateZipEntry(node.toString()));
        }

        if(node.isDirectory())
        {           
            String[] subNode = node.list();

            if (subNode != null) {

                for(String filename : subNode)
                {
                    generateFileList(new File (node, filename));
                }
            }
        }
    }

    private String generateZipEntry(String path)
    {
        return path.substring(source_folder.length() + 1, path.length());
    }
}

file.list() is being done in the generateFileList method in ZipFile class. I know this is returning null since I tried detecting whether the file is a folder or a file by using filename.indexOf(".") instead of isDirectory() and isFile() since they were not working. But I wish I had an explanation for this.

Thanks for your help!

Upvotes: 2

Views: 216

Answers (4)

Er Swati Mittal
Er Swati Mittal

Reputation: 1

    public String compressData(String srcDir) {

         String zipFile = srcDir+".zip"; 
                try {

                    // create byte buffer
                    byte[] buffer = new byte[1024];

                    FileOutputStream fos = new FileOutputStream(zipFile);

                    ZipOutputStream zos = new ZipOutputStream(fos);

                    File dir = new File(srcDir);

                    File[] files = dir.listFiles();

                    for (int i = 0; i < files.length; i++) {

                        System.out.println("Adding file: " + files[i].getName());

                        FileInputStream fis = new FileInputStream(files[i]);

                        // begin writing a new ZIP entry, positions the stream to the start of the entry data
                        zos.putNextEntry(new ZipEntry(files[i].getName()));

                        int length;

                        while ((length = fis.read(buffer)) > 0) {
                            zos.write(buffer, 0, length);
                        }

                    zos.closeEntry();

                        // close the InputStream
                        fis.close();
                    }


    // close the ZipOutputStream
                    zos.close();

                }
                catch (IOException ioe) {
                    System.out.println("Error creating zip file" + ioe);
                }
                return zipFile;

            }

Upvotes: 0

Leos Literak
Leos Literak

Reputation: 9406

if (!file.exists()) {
    // if directory does not exist, create it
    file.mkdirs();
}

will create directory and test file.isDirectory() will return true

Upvotes: 1

blackSmith
blackSmith

Reputation: 3154

I tested your code block

ZipFile appZip = new ZipFile(file.toString());
appZip.generateFileList(file);
appZip.zipIt(filename + ".zip");

with a local folder and it's working perfectly. I think you are passing a invalid path. This may be the cause isFile or isDirectory methods are acting strangely. Try to add a validation statement at the starting of generateFileList method using File API:

if(!node.exists) {
     // return some flag to signify error OR throw a suitable Exception   
}

This should work.

Upvotes: 0

Dusan Plavak
Dusan Plavak

Reputation: 4579

It could be a problem with the path?

C://MyDocuments//zerafbe//Documents//apache-tomcat-7.0.29//webapps//attachments//t50\test

You are mixing backslash with slash...

Upvotes: 0

Related Questions