Zip compression with Java in Windows environment without garbled characters

When Zip-compressing a file with Java, if Japanese characters are used in the file name to be compressed In some Windows environments, garbled characters occurred when decompressing, so we have organized a workaround.

In the first place

The same problem may occur when opening a file compressed on Mac / Linux on Windows. Specifically, it occurs when the patch is not applied on Windows 7 or Windows Server 2008 R2. [^ 1]

~~ I'm asking you to apply various patches and use the latest one ~~ Depending on the environment, it may not be possible to update easily. In that case, let's handle it on the program side.

Implementation

This is a sample that compresses the file (or directory) specified by the argument into a Zip file called packed.zip.

From Java7 you can pass Charset to the constructor of ZipOutputStream If you pass Charset.forName ("Shift-JIS "), you can create a Zip file that does not garble even in a Windows environment.

If you look for a similar problem, you'll find some articles saying that you need to include the ʻorg.apache.tools.zip` package. From Java7, it can be realized only with the standard library.

ZipFile.java


package com.uskey512;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

public class ZipFile implements AutoCloseable {

    private byte[] buffer;
    private List<File> targetFiles;
    private ZipOutputStream zipOutputStream;

    private static final int DEFAULT_BUFFER_SIZE = 1024;

    public ZipFile(String fileName, String path) throws IOException {
        this(fileName, path, Charset.defaultCharset(), DEFAULT_BUFFER_SIZE);
    }

    public ZipFile(String fileName, String path, int bufferSize) throws IOException {
        this(fileName, path, Charset.defaultCharset(), bufferSize);
    }

    public ZipFile(String fileName, String path, Charset charset) throws IOException {
        this(fileName, path, charset, DEFAULT_BUFFER_SIZE);
    }

    public ZipFile(String fileName, String path, Charset charset, int bufferSize) throws IOException {
        File zipFile = new File(path + File.separator + fileName);
        buffer = new byte[bufferSize];
        targetFiles = new ArrayList<File>();
        zipOutputStream = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(zipFile)), charset);
    }

    public void addFile(String filePath) {
        targetFiles.add(new File(filePath));
    }

    public void build() {
        writeFiles(targetFiles.toArray(new File[0]));
    }

    private void writeFiles(File[] files) {
        for (File file : files) {
            if (file.isDirectory()) {
                writeFiles(file.listFiles());
            } else {
                try {
                    ZipEntry entry = new ZipEntry(file.getPath().replace('\\', '/'));
                    zipOutputStream.putNextEntry(entry);
                    try (InputStream is = new BufferedInputStream(new FileInputStream(file))) {
                        int readLength = 0;
                        while (0 < (readLength = is.read(buffer))) {
                            zipOutputStream.write(buffer, 0, readLength);
                        }
                    }
                } catch (IOException ioe) {
                    throw new RuntimeException("", ioe);
                }
            }
        }
    }

    @Override
    public void close() throws IOException {
        zipOutputStream.close();
    }
}

Main.java


package com.uskey512;

import java.io.IOException;
import java.nio.charset.Charset;

public class Main {

    public static void main(String[] args) {
        // try (ZipFile zipFile = new ZipFile("packed.zip", ".") { //Transform
        try (ZipFile zipFile = new ZipFile("packed.zip", ".", Charset.forName("Shift-JIS"))) { //Not garbled
            zipFile.addFile(args[0]);
            zipFile.build();
        } catch (IOException ioe) {
        }
    }
}

Recommended Posts

Zip compression with Java in Windows environment without garbled characters
Umlaut garbled characters
Japanese characters described in MessageResources.properties are garbled
Measures against garbled characters in Multipart Request with Quarkus
Zip compression with Java in Windows environment without garbled characters
Install Java with zip on Windows
Self-hosting with Docker of AuteMuteUs in Windows environment
[Windows] [IntelliJ] [Java] [Tomcat] Create a Tomcat9 environment with IntelliJ
Measures against garbled characters in Multipart Request with Quarkus
Resolve CreateProcess error = 206 when running Java in a Windows environment
Use Java Web Start in an OpenJDK environment on Windows
Change java encoding in windows
[Windows] Java code is garbled
Look through Java and MySQL PATH with environment variables [Windows version]
Morphological analysis in Java with Kuromoji
Create RUNTEQ's environment with Windows DockerDesktop
Unzip the zip file in Java
Java environment variable settings (Windows, AdoptOpenJDK11)
Play with Markdown in Java flexmark-java
Reduce Java / Maven build time with Nexus 3 in OpenShift (okd 3.11) DevOps environment
Alert slack with alert manager in Docker environment
Java container performance degradation in Menicoa environment
Prepare Java development environment with VS Code
CSV parsing with newline characters in fields
Call the Windows Notification API in Java
Using JupyterLab + Java with WSL on Windows 10
Concurrency Method in Java with basic example
Map without using an array in java
Edit Mysql with commands in Docker environment
Java String Byte string truncation Supports garbled characters
Play Framework 2.6 (Java) environment construction in Eclipse
With dbunit 2.6.0, poi comes in without permission
Read xlsx file in Java with Selenium
Split a string with ". (Dot)" in Java
Working with huge JSON in Java Lambda
Modern Java environment for Windows using Chocolatey
Run static analysis Infer in Windows environment
Java application development environment created in VM environment
Japanese characters described in MessageResources.properties are garbled
Avoid garbled characters and share file system with Docker environment Rstudio (also Docoker-compose)
Check with Java / Kotlin that files cannot be written in UAC on Windows