java-使用压缩生成的docx损坏

首先,我要说我在这里创建了一个帐户,因为我一直在想办法解决这个问题,所以我就在这里打了个头.

另外,我已经看到了here.这个问题,这些答案都没有帮助,我都尝试过.

我需要创建一个Word文档,其中包含一个简单的表和数据.我决定创建一个示例文档,在其中获取创建文档所需的xml.我已将所有文件夹从解压缩的docx文件移至资产文件夹.一旦意识到无法写入资产文件夹,便编写了一种方法,可将所有文件和文件夹复制到设备的外部存储位置,然后将创建的文档写入相同的位置.我试图从那里将文件压缩回一个.docx文件.这是无法工作的地方.

实际的docx文件已创建,我可以通过DDMS将其移到我的计算机上,但是当我查看该文件时,Word说它已损坏.如果我将其解压缩然后在不进行任何更改的情况下将其重新压缩到我的计算机上,那么这真是很奇怪.我使用了一个名为DiffMerge的程序(对于Mac),将示例解压缩的docx文件与我创建的解压缩的docx进行了比较,并说它们完全相同.因此,我认为这与Android中的压缩过程有关.

我还尝试过在计算机上解压缩示例docx文件,将所有文件和文件夹都移到资产文件夹中,包括document.xml文件,只是尝试将其压缩而不添加我自己的document.xml文件,而是使用示例一那也不起作用.我尝试的另一件事是将实际的docx文件放在我的资产文件夹中,将其解压缩到我的外部存储中,然后不执行任何操作就将其重新压缩.这也失败了.

我基本上不知所措.请有人帮我解决这个问题.

这是我的一些代码:

>首先调用moveDocxFoldersFromAssetsToExternalStorage().
>之后,所有文件都被移走了.
>然后,我创建document.xml文件并将其放置在它所属的word目录中
>一切都应该存在,现在我尝试创建zip文件.

.

private boolean moveDocxFoldersFromAssetsToExternalStorage(){
    File rootDir = new File(this.externalPath);
    rootDir.mkdir();

    copy("");

    // This is to get around a glitch in Android which doesnt list files or folders
    // with an underscore at the beginning of the name in the assets folder.
    // This renames them once they are saved to the device.
    // We need it to show up in the list in order to move them.

    File relsDir = new File(this.externalPath + "/word/rels");
    File renameDir = new File(this.externalPath + "/word/_rels");
    relsDir.renameTo(renameDir);

    relsDir = new File(this.externalPath + "/rels");
    renameDir = new File(this.externalPath + "/_rels");
    relsDir.renameTo(renameDir);

    // This is to get around a glitch in Android which doesnt list hidden files.
    // We need it to show up in the list in order to move it.

    relsDir = new File(this.externalPath + "/_rels/rels.rename");
    renameDir = new File(this.externalPath + "/_rels/.rels");
    relsDir.renameTo(renameDir);

    return true;
}

private void copy(String outFileRelativePath){
    String files[] = null;
    try {
        files = this.mAssetManager.list(ASSETS_RELATIVE_PATH + outFileRelativePath);
    } catch (IOException e) {
        e.printStackTrace();
    }

    String assetFilePath = null;
    for(String fileName : files){
        if(!fileName.contains(".")){
            String outFile = outFileRelativePath + java.io.File.separator + fileName;
            copy(outFile);
        } else {
            File createFile = new File(this.externalPath + java.io.File.separator + outFileRelativePath);
            createFile.mkdir();
            File file = new File(createFile, fileName);

            assetFilePath = 
                ASSETS_RELATIVE_PATH + outFileRelativePath + java.io.File.separator + fileName;

            InputStream in = null;
            OutputStream out = null;
            try {
                in = this.mAssetManager.open(assetFilePath);
                out = new FileOutputStream(file);
                copyFile(in, out);
                in.close();
                out.flush();
                out.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

private void copyFile(InputStream in, OutputStream out) throws IOException {
    byte[] buffer = new byte[1024];
    int read;
    while((read = in.read(buffer)) != -1){
        out.write(buffer, 0, read);
    }
}

private void zipFolder(String srcFolder, String destZipFile) throws Exception{
    FileOutputStream fileWriter = new FileOutputStream(destZipFile);
    ZipOutputStream zip = new ZipOutputStream(fileWriter);
    zip.setMethod(Deflater.DEFLATED);
    zip.setLevel(ZipOutputStream.STORED);

    addFolderToZip(this.externalPath, "", zip);

    zip.finish();
    zip.close();
}


private void addFolderToZip(String externalPath, String folder, ZipOutputStream zip){
    File file = new File(externalPath);
    String files[] = file.list();

    for(String fileName : files){
        try {
            File currentFile = new File(externalPath, fileName);
            if(currentFile.isDirectory()){
                String outFile = externalPath + java.io.File.separator + fileName;          
                addFolderToZip(outFile, folder + java.io.File.separator + fileName, zip);
            } else {
                byte[] buffer = new byte[8000];
                int len;
                FileInputStream in = new FileInputStream(currentFile);
                zip.putNextEntry(new ZipEntry(folder + java.io.File.separator + fileName));
                while((len = in.read(buffer)) > 0){
                    zip.write(buffer, 0, len);
                }
                zip.closeEntry();
                in.close();
            }
        } catch (IOException e) {
                e.printStackTrace();
        }
    }
}

编辑

这是我编写的代码,以便根据下面的@ edi9999说正确的代码.我创建了一个单独的类,Im将对其进行扩展和添加,并可能会进行一些清理,但这是有效的代码.它将目录中的所有文件添加到zip文件中,然后递归调用自身以添加所有子文件和文件夹.

private class Zip {
    private ZipOutputStream mZipOutputStream;
    private String pathToZipDestination;
    private String pathToFilesToZip;

    public Zip(String pathToZipDestination, String pathToFilesToZip) {
        this.pathToZipDestination = pathToZipDestination;
        this.pathToFilesToZip = pathToFilesToZip;
    }

    public void zipFiles() throws Exception{
        FileOutputStream fileWriter = new FileOutputStream(pathToZipDestination);
        this.mZipOutputStream = new ZipOutputStream(fileWriter);
        this.mZipOutputStream.setMethod(Deflater.DEFLATED);
        this.mZipOutputStream.setLevel(8);

        AddFilesToZip("");

        this.mZipOutputStream.finish();
        this.mZipOutputStream.close();
    }

    private void AddFilesToZip(String folder){
        File mFile = new File(pathToFilesToZip + java.io.File.separator + folder);
        String mFiles[] = mFile.list();

        for(String fileName : mFiles){
            File currentFile;
            if(folder != "")
                currentFile = new File(pathToFilesToZip, folder + java.io.File.separator + fileName);
            else
                currentFile = new File(pathToFilesToZip, fileName);
            if(currentFile.isDirectory()){
                if(folder != "")
                    AddFilesToZip(folder + java.io.File.separator + currentFile.getName());
                else
                    AddFilesToZip(currentFile.getName());
            } else {
                try{
                    byte[] buffer = new byte[8000];
                    int len;
                    FileInputStream in = new FileInputStream(currentFile);
                    if(folder != ""){
                        mZipOutputStream.putNextEntry(new ZipEntry(folder + java.io.File.separator + fileName));
                    } else {
                        mZipOutputStream.putNextEntry(new ZipEntry(fileName));
                    }
                    while((len = in.read(buffer)) > 0){
                        mZipOutputStream.write(buffer, 0, len);
                    }
                    mZipOutputStream.closeEntry();
                    in.close();
                } catch (IOException e){
                    e.printStackTrace();
                }
            }
        }
    }
}

解决方法:

我想我出了什么问题.

当我打开您的corrupted File并在winrar上打开它时,我在文件夹的开头看到了反斜线,这很不寻常:

当我在解压缩文件后重新压缩文件时,反斜杠不再存在,并且文件在Word中打开,因此我认为应该是问题所在.

我认为代码在这里是错误的:

String outFile = externalPath + java.io.File.separator + fileName;  

应该

if (externalPath=="")
    String outFile = externalPath + fileName;  
else 
    String outFile = externalPath + java.io.File.separator + fileName;  
上一篇:从Python中的Word文档(.docx)中提取突出显示的单词


下一篇:2018-10-04 [日常]用Python读取word文档中的表格并比较