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.
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.
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