5
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Zip展開したかった話

Last updated at Posted at 2019-09-21

きっかけ

仕事でZIPファイルのやり取りを行った際に、ZIP作成者はMac使いでこちらはWindowsでした。
この時点でわかる人はわかると思いますが、Macではエントリー名がUTF-8でZIP化され、
Windows標準のZIP展開では日本語環境ではWindows-31j(Shift-JIS)で展開するためにエントリー名が文字化けします。
いまだに文字コードで苦労するとか意味わからん。

UTF-8に対応しているフリーソフト入れたら終わりなのですが、
客先常駐で仕事しているで勝手にダウンロードするのもあれですし、せっかくなので自分で解決してみようと思いました。

とりあえずJavaで展開

参考:http://www.ne.jp/asahi/hishidama/home/tech/java/zip.html
安定のひしだまさんのページでほぼ解決してしまった。。

ZipDecoder.java
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UncheckedIOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.zip.ZipFile;

public class ZipDecoder {

	private static final String ZIP_FILE = "C:\\temp\\ふぉるだ.zip";

	public static void main(String[] args) {
		decode(ZIP_FILE);
	}

	public static void decode(String strPath) {
		if (strPath == null || !strPath.toLowerCase().endsWith(".zip")) {
			System.out.println("Argument is not zip file.");
			return;
		}
		Path zipFilePath = Paths.get(strPath);
		String outDir = zipFilePath.toString().replace(".zip", "");
		if (Files.notExists(zipFilePath)) {
			System.out.println("Argument is not file path.");
			return;
		}
		try (ZipFile zipFile = new ZipFile(zipFilePath.toFile(), Charset.forName("UTF-8"))) {
			zipFile.stream().filter(entry -> !entry.isDirectory()).forEach(entry -> {
				Path outName = Paths.get(outDir, entry.getName());
				try {
					Files.createDirectories(outName.getParent());
				} catch (IOException e1) {
					throw new UncheckedIOException(e1);
				}
				try (InputStream is = zipFile.getInputStream(entry);
						BufferedOutputStream os = new BufferedOutputStream(Files.newOutputStream(outName))) {
					byte[] buf = new byte[1024];
					while (is.read(buf) >= 0) {
						os.write(buf);
					}
				} catch (IOException e) {
					throw new UncheckedIOException(e);
				}
			});

		} catch (IOException e) {
			throw new UncheckedIOException(e);
		}
	}
}

使いまわす

まだZIPファイルのやり取りは続くので使いまわせるように作り直します。
ファイル名は起動引数で渡すようにして、ドラッグアンドドロップで展開できるようにします。
launch4jなるものを利用すればjarをexeファイルにできるようなのですが、客先常駐なので(

参考:https://qiita.com/bugtrap/items/15864474076767a7a957

ZipDecoder.java
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UncheckedIOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.zip.ZipFile;

public class ZipDecoder {

	public static void main(String[] args) {
		if (args.length == 0) {
			System.out.println("There are no Arguments.");
		}
		Arrays.asList(args).stream().forEach(ZipDecoder::decode);
	}

	public static void decode(String strPath) {
		if (strPath == null || !strPath.toLowerCase().endsWith(".zip")) {
			System.out.println("Argument is not zip file.");
			return;
		}
		Path zipFilePath = Paths.get(strPath);
		String outDir = zipFilePath.toString().replace(".zip", "");
		if (Files.notExists(zipFilePath)) {
			System.out.println("Argument is not file path.");
			return;
		}
		try (ZipFile zipFile = new ZipFile(zipFilePath.toFile(), Charset.forName("UTF-8"))) {
			zipFile.stream().filter(entry -> !entry.isDirectory()).forEach(entry -> {
				Path outName = Paths.get(outDir, entry.getName());
				try {
					Files.createDirectories(outName.getParent());
				} catch (IOException e1) {
					throw new UncheckedIOException(e1);
				}
				try (InputStream is = zipFile.getInputStream(entry);
						BufferedOutputStream os = new BufferedOutputStream(Files.newOutputStream(outName))) {
					byte[] buf = new byte[1024];
					while (is.read(buf) >= 0) {
						os.write(buf);
					}
				} catch (IOException e) {
					throw new UncheckedIOException(e);
				}
			});

		} catch (IOException e) {
			throw new UncheckedIOException(e);
		}
	}
}

call-decoder.bat
@echo off

rem コマンドチェック
where java 2> nul > nul || goto :notfound

java -jar ZipDecoder.jar %*

echo 展開完了しました
goto :end

:notfound
echo javaコマンドにPATHを通してください
goto :end

:end
pause

2つのzipファイルを選択して、batファイルにドラッグアンドドロップ

image.png

ドラッグアンドドロップで展開できました。

image.png

javaファイルとbatファイル2つあるの面倒

bat内でjavaファイル作ってコンパイルしてそれ使えばいいんじゃね?
ということでやってみました。

decord.bat
@echo off

rem コマンドチェック
where java 2> nul > nul || goto :notfound

echo import java.io.BufferedOutputStream;                                                                         > ZipDecoder.java
echo import java.io.IOException;                                                                                  >> ZipDecoder.java
echo import java.io.InputStream;                                                                                  >> ZipDecoder.java
echo import java.io.UncheckedIOException;                                                                         >> ZipDecoder.java
echo import java.nio.charset.Charset;                                                                             >> ZipDecoder.java
echo import java.nio.file.Files;                                                                                  >> ZipDecoder.java
echo import java.nio.file.Path;                                                                                   >> ZipDecoder.java
echo import java.nio.file.Paths;                                                                                  >> ZipDecoder.java
echo import java.util.Arrays;                                                                                     >> ZipDecoder.java
echo import java.util.zip.ZipFile;                                                                                >> ZipDecoder.java
echo public class ZipDecoder {                                                                                    >> ZipDecoder.java
echo 	public static void main(String[] args) {                                                                  >> ZipDecoder.java
echo 		if (args.length == 0) {                                                                               >> ZipDecoder.java
echo 			System.out.println("There are no Arguments.");                                                    >> ZipDecoder.java
echo 		}                                                                                                     >> ZipDecoder.java
echo 		Arrays.asList(args).stream().forEach(ZipDecoder::decode);                                             >> ZipDecoder.java
echo 	}                                                                                                         >> ZipDecoder.java
echo 	public static void decode(String strPath) {                                                               >> ZipDecoder.java
echo 		if (strPath == null ^|^| !strPath.toLowerCase().endsWith(".zip")) {                                     >> ZipDecoder.java
echo 			System.out.println("Argument is not zip file.");                                                  >> ZipDecoder.java
echo 			return;                                                                                           >> ZipDecoder.java
echo 		}                                                                                                     >> ZipDecoder.java
echo 		Path zipFilePath = Paths.get(strPath);                                                                >> ZipDecoder.java
echo 		String outDir = zipFilePath.toString().replace(".zip", "");                                           >> ZipDecoder.java
echo 		if (Files.notExists(zipFilePath)) {                                                                   >> ZipDecoder.java
echo 			System.out.println("Argument is not file path.");                                                 >> ZipDecoder.java
echo 			return;                                                                                           >> ZipDecoder.java
echo 		}                                                                                                     >> ZipDecoder.java
echo 		try (ZipFile zipFile = new ZipFile(zipFilePath.toFile(), Charset.forName("UTF-8"))) {                 >> ZipDecoder.java
echo 			zipFile.stream().filter(entry -^> !entry.isDirectory()).forEach(entry -^> {                         >> ZipDecoder.java
echo 				Path outName = Paths.get(outDir, entry.getName());                                            >> ZipDecoder.java
echo 				try {                                                                                         >> ZipDecoder.java
echo 					Files.createDirectories(outName.getParent());                                             >> ZipDecoder.java
echo 				} catch (IOException e1) {                                                                    >> ZipDecoder.java
echo 					throw new UncheckedIOException(e1);                                                       >> ZipDecoder.java
echo 				}                                                                                             >> ZipDecoder.java
echo 				try (InputStream is = zipFile.getInputStream(entry);                                          >> ZipDecoder.java
echo 						BufferedOutputStream os = new BufferedOutputStream(Files.newOutputStream(outName))) { >> ZipDecoder.java
echo 					byte[] buf = new byte[1024];                                                              >> ZipDecoder.java
echo 					while (is.read(buf) ^>= 0) {                                                               >> ZipDecoder.java
echo 						os.write(buf);                                                                        >> ZipDecoder.java
echo 					}                                                                                         >> ZipDecoder.java
echo 				} catch (IOException e) {                                                                     >> ZipDecoder.java
echo 					throw new UncheckedIOException(e);                                                        >> ZipDecoder.java
echo 				}                                                                                             >> ZipDecoder.java
echo 			});                                                                                               >> ZipDecoder.java
echo 		} catch (IOException e) {                                                                             >> ZipDecoder.java
echo 			throw new UncheckedIOException(e);                                                                >> ZipDecoder.java
echo 		}                                                                                                     >> ZipDecoder.java
echo 	}                                                                                                         >> ZipDecoder.java
echo }                                                                                                            >> ZipDecoder.java

javac ZipDecoder.java

java ZipDecoder %*

del ZipDecoder.java
del ZipDecoder.class

echo 展開完了しました
goto :end

:notfound
echo javaコマンドにPATHを通してください
goto :end

:end
pause

一部記号をエスケープしたら普通に出力できた。

image.png

zipファイルをドラッグアンドドロップ

image.png

展開できた。

補足

今回のソースはjava8以上にパスが通っていたら使えます。

5
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?