How to compress a folder to make docx file in andr

2019-05-25 01:26发布

问题:

I'm trying to make an Android application that can open a docx file to read, edit and save it.

My idea is to extract all the xml file within the archive to a temp folder. In this folder we can edit the content of the docx in /word/document.xml. The problem is when I compress this temp folder to make a new docx file and replace the old file, inside the new docx archive the path is like /mnt/sdcard/temp/"all files xml go here" while the xml files should be in the first level.

Can anybody help me to go through this? here is the method to compress the temp directory

Note: dir2zip argument's value I use is /mnt/sdcard/temp/***.docx

public void zipDir(String dir2zip, ZipOutputStream zos)
{
    try
   {
        //create a new File object based on the directory we
        //have to zip File   
        File zipDir = new File(dir2zip);

        //get a listing of the directory content
        String[] dirList = zipDir.list();
        byte[] readBuffer = new byte[2156];
        int bytesIn = 0;

        //loop through dirList, and zip the files
        for(int i=0; i<dirList.length; i++)
        {
            File f = new File(zipDir, dirList[i]);
            if(f.isDirectory())
            {
                    //if the File object is a directory, call this
                    //function again to add its content recursively
                String filePath = f.getPath();
                zipDir(filePath, zos);
                    //loop again
                continue;
            }
            //if we reached here, the File object f was not a directory
            //create a FileInputStream on top of f
            FileInputStream fis = new FileInputStream(f);
            //create a new zip entry
            ZipEntry anEntry = new ZipEntry(f.getPath());
            //place the zip entry in the ZipOutputStream object
            zos.putNextEntry(anEntry);
            //now write the content of the file to the ZipOutputStream
            while((bytesIn = fis.read(readBuffer)) != -1)
            {
                zos.write(readBuffer, 0, bytesIn);
            }
           //close the Stream
           fis.close();
        }
    }
    catch(Exception e)
    {
        //handle exception
    }
}

回答1:

I have managed to fix it by myself. The problem is in this line:

    File f = new File(zipDir, dirList[i]);

It should be

    File f = new File(dirList[i]);

If the argument zipDir is included, the absolute path to the directory will be used in the archive!



回答2:

I have now managed to get the original poster's code working on Mac and Windows by making the following two modifications:

1: add a ZipEntry for each directory: do not simply ignore it

2: remove the directory name from the ZipEntry name

Note: zipinfo is useful

This is a program that works for me:

import java.io.*;
import java.util.zip.*;

public class zipdoc
{
    String savedDir = null;

    public void zipDir(String dir2zip, ZipOutputStream zos)
    {
        try
       {
            if (savedDir == null)
                savedDir = dir2zip;
            // create a new File object based on the directory we
            // have to zip File   
            File zipDir = new File(dir2zip);

            //get a listing of the directory content
            String[] dirList = zipDir.list();
            byte[] readBuffer = new byte[2156];
            int bytesIn = 0;

            // loop through dirList, and zip the files
            for (int i=0; i<dirList.length; i++)
            {
                File f = new File(zipDir, dirList[i]);
                if (f.isDirectory())
                {
                    // if the File object is a directory, call this
                    // function again to add its content recursively
                    System.out.println("Adding dir: " + f); 
                    // create a new zip entry
                    ZipEntry anEntry = new ZipEntry(f.getPath().substring(savedDir.length()+1) + "/");
                    // place the zip entry in the ZipOutputStream object
                    zos.putNextEntry(anEntry);


                    String filePath = f.getPath();
                    zipDir(filePath, zos);
                    // loop again
                    continue;
                }
                else if (!f.getName().equals(".DS_Store"))
                {
                    // if we reached here, the File object f was not a directory
                    // and it's not the MacOSX special .DS_Store
                    // create a FileInputStream on top of f
                    System.out.println("Adding file: " + f);
                    FileInputStream fis = new FileInputStream(f);
                    // create a new zip entry
                    ZipEntry anEntry = new ZipEntry(f.getPath().substring(savedDir.length()+1));
                    // place the zip entry in the ZipOutputStream object
                    zos.putNextEntry(anEntry);
                    // now write the content of the file to the ZipOutputStream
                    while((bytesIn = fis.read(readBuffer)) != -1)
                    {
                        zos.write(readBuffer, 0, bytesIn);
                    }
                   // close the Stream
                   fis.close();
                }
            }
        }
        catch(Exception e)
        {
            // handle exception
            System.out.println(e);
        }
    }

    public void zipit(String inDir, String outFile)
    {
        try {
            ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(new File(outFile)));
            zos.setMethod(0);
            zos.setMethod(ZipOutputStream.DEFLATED);
            zos.setLevel(0);

            zipDir(inDir, zos);
            zos.finish();
            zos.close();
        }
        catch (Exception e)
        {
            System.out.println(e);
        }
    }


    public static void main (String args[]) {
        zipdoc z1 = new zipdoc();

        // Check there are sufficient params if desired
        // first param is directory to be 'zipped', second is resulting
        // filename (??.docx)
        // eg java zipdoc dir1 newDoc.docx

        z1.zipit(args[0], args[1]);

        System.out.println("Finished creating " + args[1]);
    }
}