• 締切済み

Zipファイル解凍処理について

こんにちわ。 Javaの解凍処理について質問です。 Test.zipがあって、その中身が「テスト.xls」とした時、うまく解凍ができません。 Zipファイルの中身が日本語名ではなく、「Test.xls」であれば正常に解凍ができます。 下記の書き方では日本語名のファイルの入ったZipファイルを解凍することはできないのでしょうか? どなたかご教授お願い致します。 String fname = null; FileInputStream fis = null; BufferedInputStream bis = null; ZipInputStream zis = null; ZipEntry zent = null; FileOutputStream fos = null; try { fis = new FileInputStream(FilePath); bis = new BufferedInputStream(fis); zis = new ZipInputStream(bis); byte[] buf = new byte[1024]; int len; // アーカイブ中に含まれるファイル情報の取得 while ((zent = zis.getNextEntry()) != null) { int intResult = zent.toString().indexOf("."); int intLength = zent.toString().length(); //ファイル名の変更(フォルダ名+社員コード)StringBuffer BuffRename = new StringBuffer(); BuffRename.append("D:\\test\\"); BuffRename.append(zent.getName().substring(0,intResult)); BuffRename.append(SyainCd); BuffRename.append(zent.getName().substring(intResult,intLength)); fname = BuffRename.toString(); //書き込みファイルをオープン fos = new FileOutputStream(fname); while (-1 != (len = zis.read(buf, 0, buf.length))) { fos.write(buf, 0, len); } //★★★ fos.close(); } Catch・finallyは省略

  • Java
  • 回答数2
  • ありがとう数1

みんなの回答

  • aton
  • ベストアンサー率47% (160/334)
回答No.2

#1の方が書いておられる通り,java.util.ZipInputStreamはUTF-8にしか対応していないようです。 #試しにjarで, #日本語(SJIS)エントリーをもつzipファイルを開いてみたところ, #ZipInputStream.getNextEntry()から呼び出されている #ZipIputStream.getUTF8String()というメソッドで #IllegalArugumentExceptionが発生しました。 illusion_catさんがどういう目的でzipの解凍処理をjavaで書こうとしているのかがわからないので,役に立たないアドバイスかもしれませんが,解凍対象のzipファイルを自分で作るような状況であれば,作成時に日本語(SJIS等)のエントリー名をUTF-8に変換してzipファイルに格納し,解凍時にそれを元の文字コードに戻すようにする,というのが一つの方法として考えられます。 そうでなくもっと根本的な対処としては,例えば自分でZipInputStreamクラスを継承するクラス(例えばMyZipInputStream)をつくって,そこにZipEntry名の文字コードを指定できるgetNextEntryメソッド(例えばgetNextEntry(String charEncoding))を追加するという方法も考えられます。 MyZipInputStream.getNextEntry(String) の中身の処理は,zipファイルのフォーマットをベースに,Javaのソースを参考にして書いてみてはどうでしょうか?

  • sanaqa
  • ベストアンサー率30% (13/42)
回答No.1

こんばんわ。 サイト検索して以下の情報を見つけました。 ZipInputStreamはUTF-8固定で日本語名ファイルを解凍不可能です。 org.apache.tools.zip.ZipFile ZipEntry、Enumeration取得 ZipFileにZipEntryを引数にしてファイルごとの解凍されたInputStreamが取り出せる。 とのことです。

関連するQ&A

  • 固定長データのbyteスキップについて

    バイナリ入出力でご質問がございます。 下記の例のように各レコードにある 先頭5byte付与されたデータを スキップ(破棄)して 各レコード10byteずつ読み込みたいのですが なにかサンプルデータもしくは アドバイス頂けないでしょうか? どうぞよろしくお願い致します。 例 1レコード 10byte (先頭5byte付与) LLLLL1234567890 LLLLL1234567890 LLLLL1234567890 LLLLL1234567890 LLLLL1234567890 ↓ 1234567890 1234567890 1234567890 1234567890 1234567890 import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.nio.ByteBuffer; import java.io.ByteArrayOutputStream; public class dat{ public static void main(String[] args) { String inputFileName = ""; String outputFileName = ""; // ファイルオブジェクトの生成 File inputFile = new File(inputFileName); File outputFile = new File(outputFileName); try { FileInputStream fis = new FileInputStream(inputFile); BufferedInputStream bis = new BufferedInputStream(fis); FileOutputStream fos = new FileOutputStream(outputFile); BufferedOutputStream bos = new BufferedOutputStream(fos); byte[] buf = new byte[17]; int len = 0; while ((len = bis.read(buf, 0, 17)) == 17) { bos.write(buf, 0, 17); } bos.flush(); bos.close(); bis.close(); } catch(Exception e) { e.printStackTrace(); } }

    • ベストアンサー
    • Java
  • レコード長からのbyteスキップ設定について

    QNo.8229324から あらたに新規でご質問させて頂きます。 1レコードごとに10byteあったとします。 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 レコード長からスキップ設定を35byteと設定したとします。 40byteごとに頭の付与された5byteをスキップさせたいのですが なにかサンプル及びアドバイス頂けますでしょうか? 仕様案 (1)まずはレコード先端の5byteをスキップ (2)次は35byteを超えた時点で5byteスキップを繰り返し。 どうぞ宜しくお願い致します。 import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.nio.ByteBuffer; import java.io.ByteArrayOutputStream; public class dat{ public static void main(String[] args) { String inputFileName = ""; String outputFileName = ""; // ファイルオブジェクトの生成 File inputFile = new File(inputFileName); File outputFile = new File(outputFileName); try { FileInputStream fis = new FileInputStream(inputFile); BufferedInputStream bis = new BufferedInputStream(fis); FileOutputStream fos = new FileOutputStream(outputFile); BufferedOutputStream bos = new BufferedOutputStream(fos); byte[] buf = new byte[17]; int len = 0; while ((len = bis.read(buf, 0, 17)) == 17) { bos.write(buf, 0, 17); } bos.flush(); bos.close(); bis.close(); } catch(Exception e) { e.printStackTrace(); } }

    • ベストアンサー
    • Java
  • 固定長データの情報処理について

    現在情報処理についての勉強中ですが import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.nio.ByteBuffer; public class dat_stream { public static void main(String[] args) { // 読み込むファイルの名前 String inputFileName = "ファイル名"; // 書き込むファイルの名前 String outputFileName = "ファイル名"; // ファイルオブジェクトの生成 File inputFile = new File(inputFileName); File outputFile = new File(outputFileName); try { // 入力ストリームの生成 FileInputStream fis = new FileInputStream(inputFile); BufferedInputStream bis = new BufferedInputStream(fis); // 出力ストリームの生成 FileOutputStream fos = new FileOutputStream(outputFile); BufferedOutputStream bos = new BufferedOutputStream(fos); // 読み込み用バイト配列 byte[] buf = new byte[9]; // ファイルへの読み書き int len = 0; while ( ( len = bis.read(buf) ) != -1 ) { bos.write(buf, 0, len); } // 後始末 bos.flush(); bos.close(); bis.close(); // エラーがあった場合は、スタックトレースを出力 } catch(Exception e) { e.printStackTrace(); } } } を使用してDATデータの入出力を考えています。 F0 F2 12 34 56 78 9C 00 50といった9byteの固定長データが あったとします。 (1)1byteから2byteはそのまま入出力 F0 F2 →F0 F2 (2)3byte~7byteパック10進数からアンパック(ゾーン)10進数に変換 12 34 56 78 9C →F1 F2 F3 F4 F5 F6 F7 F8 F9 こちらに関しては上位桁・下位桁で計算し正の数・負の数等も 考えなければいけないと思うのですが・・・ (3)バイナリ進数からゾーン10進数に変換 00 50→F0 F0 F8 F0 計算方法)0*16進数3剰 + 0*16進数2剰 + 5*16進数1剰+ 0 このような(1)~(3)のようなバイナリ入出力を考えた場合 1レコードが9byteで 10レコードで90byteだった場合の 書き出し方法について情報処理について詳しい方いましたら アドバイスください。 なお数値変換については今後勉強していければと思っております。 どうぞよろしくお願い致します。

    • ベストアンサー
    • Java
  • ファイル圧縮について。

    ファイル圧縮について質問させてください。 以下のようなメソッドを作成したのですが、 public run(String strFiles[], String strZipFileName) { int i = 0; int iLen = 0; FileInputStream fis = null; FileOutputStream fos = null; ZipOutputStream zos = null; ZipEntry zent = null; byte[] buf = new byte[1024*10*10]; try { fos = new FileOutputStream(strZipFileName); zos = new ZipOutputStream(fos); for (i = 0; i < strFiles.length(); i++) { fis = new FileInputStream(strFiles[i]); zent = new ZipEntry(strFiles[i]); zos.putNextEntry(zent); while (-1 != (iLen = fis.read(buf))) { zos.write(buf, 0, iLen); } zos.flush(); zos.closeEntry(); fis.close(); } } catch(Exception e) { System.err.println(e); } finally { try { zos.close(); // ※1 fos.close(); // ※2 } catch(Exception e) { System.err.println(e); } } } サイズの小さいファイルや、 特定のサイズのファイル(13k程度)を対象とした時、 高い確率で、空の圧縮ファイルが作成される事があります。 ログを出力しながら確認すると、このような現象が起きた場合、 圧縮ファイルをcloseする直前(※1)では作成されたファイルはサイズがあるのですが、 圧縮ファイルをcloseした直後(※2)ではファイルのサイズが0になってしまいます。 また、2台あるサーバの内、1台だけでこの現象が起こっています。 javaのバージョンは1.3です。 何故このような現象が起こってしまうのか、 ご存知の方がいらっしゃいましたら教えていただけないでしょうか。 宜しくお願いします。

    • ベストアンサー
    • Java
  • zipフォルダの解凍

    いつもお世話になっています。 zipフォルダ実行時のことで質問します。 指定のファイルをzipフォルダに格納して、フォルダ名を指定して格納することはできました。 それで、逆に、zipフォルダにどんなファイルがあるかを確かめたいと思ったのですが、可能なのでしょうか? zipフォルダに格納できたので、それを逆に変えてしようとしたのですが、いまいちわかりません。 zipフォルダに格納したソースは以下です。 import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; public class ZipOutStream_Test { public static void main(String[] args) throws Exception { File zipf = new File("D:/zip_Java.zip"); //zipファイルに埋め込むfile名 File[] files = { new File("directory.txt") }; ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(zipf)); try { encode(zos,files); } catch (IOException e) { }catch(Exception e) { }finally { zos.close(); } } static byte[] buf = new byte[1024]; public static void encode(ZipOutputStream zos, File[] files) throws Exception { for(File f: files) { if(f.isDirectory() ) { encode(zos, f.listFiles() ); }else { ZipEntry ze = new ZipEntry(f.getPath().replace('\\', '/')); zos.putNextEntry(ze); InputStream is = new BufferedInputStream(new FileInputStream(f)); for (;;) { int len = is.read(buf); if (len < 0) break; zos.write(buf, 0, len); } is.close(); } } } } 宜しくお願いします。

    • ベストアンサー
    • Java
  • ファイルロック後の書き込みについて

    ファイルAをロックしファイルBを読み込み ファイルAに書き込むプログラムを作成しています。 単体起動では問題無く動くのですが 複数起動するとファイルの書き込みが行われなくなってしまいます。 ロックしたプログラム以外はロックエラーになり ロックについては正常に動いているように見えます。 なぜ書き込みが行われなくなってしまうかご教授いただけますか? import java.io.* ; import java.nio.*; import java.nio.channels.*; public class CopyFile { public static void main(String[] args) throws Exception { try{ FileInputStream fis = null; FileOutputStream output = null; FileChannel outChannel = null; FileLock outFileLock = null; byte buf[] = new byte[2048]; int len; int count = 0; if (args.length != 2) { System.out.println("使用法: java CopyFile ファイル名1 ファイル名2"); System.exit(0); } //if String source= args[0]; String target= args[1]; File sourceFile = new File(source); File targetFile = new File(target); fis = new FileInputStream(sourceFile); output = new FileOutputStream(targetFile); outChannel = output.getChannel(); outFileLock = outChannel.tryLock(); if (outFileLock == null) { System.out.println("rock error!!"); System.exit(0); } else { while ((len = fis.read(buf)) != -1) { output.write(buf, 0, len); count += len; } Thread.sleep(5000); output.flush(); output.close(); fis.close(); } }catch(Exception e){ System.out.println(e); } } } // Class CopyFile

    • ベストアンサー
    • Java
  • jspのプログラムについて

    jspファイルで データベースの中のテーブルの中身をCSVファイルに出力するプログラムを教えてください。 delete文で中身を消すプログラムは書けたのですが、これはできません。 conn = null; st=null; conn=DriverManager.getConnection("jdbc:mysql://localhost/データベース名?" + "user=ユーザー名&password=パスワード&useUnicode=true&characterEncoding=utf8"); st=conn.createStatement(); StringBuffer buf = new StringBuffer(); buf.append("delete from where id="+id); st.executeUpdate(buf.toString()); これで削除はできました。 なのでbuf.appendの中身を buf.append("SELECT from テーブル名 INTO OUTFILE "c:/data" "); これに書き換えればできると思ったのですができません。 よろしくお願いします。

    • ベストアンサー
    • Java
  • ファイルサイズを変更したい

    visualstudio2010を使用しています。 c言語で書いているのですが、 test.txt ←abcdefg ファイルサイズ1KB Wtest.txt←書き込み用ファイル 上記のようなファイルがあり、バイナリでtest.txtを読み込みWtest.txtに書き込みたいと思っています。 その際に、1KBのtest.txtを5KBになるまでバイナリで「abcdefg」の後に0を代入したいのですがどう書けば良いのかわかりません。 FILE *fp, *fpw; char *fname = "test.txt"; char *fname_w = "Wtest.txt"; unsigned char buf[10000]; int size; fp = fopen( fname, "rb" ); if( fp == NULL ){ printf( "%sファイルが開けません\n", fname ); return -1; } fpw = fopen(fname_w, "wb"); if(fpw == NULL){ printf( "%sファイルが開けません\n", fname_w ); return -1; } size = fread( buf, sizeof( unsigned char ), sizeof (fp), fp ); /*ここに処理を追加したい*/ fwrite( buf, sizeof( unsigned char ), size, fpw);

  • Servletで画像を表示させたい時。

    例えばdocBaseがtestで、test直下にlogoフォルダがあって、その中に foobar.jpgと言う画像ファイルがあった場合、次のソースコードで出るはずなのですが、 /* イメージ画像の表示 */ package srd; import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class dispLogo extends HttpServlet { public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { res.setContentType("image/jpeg"); BufferedInputStream bis = new BufferedInputStream(new FileInputStream("\\usr\\local\\test\\logo\\foobar.jpg")); ServletOutputStream out = res.getOutputStream(); int n; byte[] buf = new byte[512]; while ((n = bis.read(buf)) != -1) { out.write(buf, 0, n); } bis.close(); } } どうしても、画像のあるパスが分からないというエラーメッセージがでてしまいます。 画像はtmpフォルダに入れるべきなのでしょうか。それでも上手く表示されません。 どなたか分かる方がいましたら、教えてください。

  • strutsでファイルダウンロード(WinでOK,linuxでNG)

    strutsでWindowsのexeファイルのダウンロードを実装しましたが、Windows上のtomcatにdeployすると正常にダウンロードできるのに、linux(fedora-core3)上のtomcatにdeployすると、ダウンロードしたファイルがhtmlになってしまいます。 hoge.exeという名前のファイルはダウンロードできるのですが、それが実はテキストで、メモ帳で開くと、ダウンロード画面のhtmlが表示されます。 この状況は何によって生み出されているのでしょうか。 お分かりになる方、ヒントをお願いいたします。 以下にファイルダウンロード部のソース(抜粋)を掲載させていただきます。 ----- 以下ソース ----- protected void download(HttpServletResponse response, String fileType, String filename) { try { // exeファイルのダウンロード時 if (fileType.equals("application/octet-stream")) { response.setHeader("Content-Disposition", "attachment; filename=" + filename); } response.setContentType(fileType); BufferedInputStream bis = new BufferedInputStream(new FileInputStream(filename)); BufferedOutputStream bos = new BufferedOutputStream(response.getOutputStream()); byte[] buf = new byte[128]; int size; while ((size = bis.read(buf, 0, buf.length)) != -1) { bos.write(buf, 0, size); } bos.close(); bis.close(); } catch (IOException e) { throw new thisSystemException("could not send file[" + filename + "]"); }

    • ベストアンサー
    • Java

専門家に質問してみよう