こんにちわ。

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は省略

このQ&Aに関連する最新のQ&A

A 回答 (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のソースを参考にして書いてみてはどうでしょうか?
    • good
    • 0

こんばんわ。



サイト検索して以下の情報を見つけました。

ZipInputStreamはUTF-8固定で日本語名ファイルを解凍不可能です。
org.apache.tools.zip.ZipFile
ZipEntry、Enumeration取得
ZipFileにZipEntryを引数にしてファイルごとの解凍されたInputStreamが取り出せる。

とのことです。
    • good
    • 0

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

QZIP内の特定のファイルのみ抽出してZIP作成

ZIPファイル内の特定のファイルのみ抽出してZIPファイルを作成
したいのですが、パイプ等を使ってうまくできないでしょうか?

次のようにコマンドをいくつかあわせればとりあえず出来るのですが…
mkdir temp
unzip src.zip *.jpg -d temp
cd temp
zip -m ..\dst.zip *

もっとよい方法をご存知の方がいましたらご教授願います。

次のようにも試してみたのですが、うまくいきませんでした。
unzip -p src.zip *.jpg | zip dst.zip -

OSはWindowsXPです。
ZIPプログラムは必要であれば特定のZIPプログラムを
使用してもいいです。

Aベストアンサー

ANo.1 です。
そうですね。簡単なコマンドですむ方法はむずかしいかもしれませんね。
それでは、思いついたことをいくつか。

(1) zip 内のファイルを削除する方法の場合。
新しい zip ファイルを 3 個つくるなら、3 個以上のコマンドが必要でしょう。

copy src.zip 1.zip & zip -d 1.zip "*" -x "?.jpg" "??.jpg" "???.jpg"
copy src.zip 1000.zip & zip -d 1000.zip "*" -x "1???.jpg"
copy src.zip 2000.zip & zip -d 2000.zip "*" -x "2???.jpg"

上の 3 行を 1 行につないでもよいのでしょうが、ややこしくなるだけでしょう。
ファイル名が簡単なワイルドカードで表せる場合は、これでどうでしょうか。

(2) *.jpg のファイル名が簡単なワイルドカードで指定できない場合。
(たとえば数字といっしょにアルファベットが混じるファイル名があって、それは zip ファイルにしたくないとか)
ファイル名がいろいろあって簡単に指定できない場合は、ファイル名のリストを作っておくのがわかりやすいでしょう。
ファイル名がわからないときは
zipinfo -1 src.zip "1???.jpg" > 1000.lst
などとしていったんリストを作って、余計なファイルが混じるならあとで編集するなどの手間が必要かもしれません。
そのうえで、unzip でひとつずつ展開して、そのたびに zip でアーカイブに加えていくとかは、どうでしょう。

for /f %i in (dst.lst) do (
unzip src.zip %i
zip -m dst.zip %i
)

バッチファイルにして、dst のところを 1 とか 1000 とか 2000 とかのコマンドライン・パラメータで与えるのもいいかもしれません。
ファイル名の番号に規則性があるならリストファイルにしないで、
for /l %i in (1 1 999)
などと、連続した番号を生成するのもありかなと思います。

ANo.1 です。
そうですね。簡単なコマンドですむ方法はむずかしいかもしれませんね。
それでは、思いついたことをいくつか。

(1) zip 内のファイルを削除する方法の場合。
新しい zip ファイルを 3 個つくるなら、3 個以上のコマンドが必要でしょう。

copy src.zip 1.zip & zip -d 1.zip "*" -x "?.jpg" "??.jpg" "???.jpg"
copy src.zip 1000.zip & zip -d 1000.zip "*" -x "1???.jpg"
copy src.zip 2000.zip & zip -d 2000.zip "*" -x "2???.jpg"

上の 3 行を 1 行につないでもよいのでしょうが、...続きを読む

QString a = "a"; と String b = new String ("b"); の違い

String a = "a";
String b = new String ("b");

お伺いしたいのですが、
b は String のインスタンスを作ってると思いますが、
a はどんなことをしてるのでしょうか?

Aベストアンサー

お二人の回答を具体的に言うと、こういうことです。
String a1 = "a";
String a2 = "a";
String b1 = new String ("b");
String b2 = new String ("b");

a1のために、aという文字列のインスタンスが作られますが、
a2に代入されるのは、a1に使われたインスタンスが再利用されます。
これは、
if(a1 == a2) System.out.print("a1と同じインスタンス");
の結果でもわかります。

一方、b1とb2は、bという文字列オブジェクトを引数に、新しいインスタンスを生成する指示がありますので、b1とb2と、その初期化に使った無名のStringインスタンスの3つがメモリ上に存在することになります。
if(b1 != b2) System.out.print("b1とは違うインスタンス");
の結果でもわかると思います。

したがって、
String b = new String ("b"); というのは、Integerに例えると
Integer i = new Integer(new Integer(1)); という処理を
していることになり、ひとつ無駄なインスタンス生成となります。

お二人の回答を具体的に言うと、こういうことです。
String a1 = "a";
String a2 = "a";
String b1 = new String ("b");
String b2 = new String ("b");

a1のために、aという文字列のインスタンスが作られますが、
a2に代入されるのは、a1に使われたインスタンスが再利用されます。
これは、
if(a1 == a2) System.out.print("a1と同じインスタンス");
の結果でもわかります。

一方、b1とb2は、bという文字列オブジェクトを引数に、新しいインスタンスを生成する指示がありますので、b1とb2と、その...続きを読む

QPythonでZIP中のZIPを操作する方法

【PythonでZIPファイル中のZIPファイルを操作したい】

PythonでZIP内のZIPを再帰的に探して操作したいと考えています。
スクリプトを書いてみたのですが、どうもうまくいきません。
どなたかマズところをご教示いただけないでしょうか?

以下のような構造のデータファイルを用意しました。
  SampleZip1.zip
    Sample1.txt
    Sample2.txt
    SampleZip1-1.zip
      Sample1-1-1.txt
      Sample1-1-2.txt
    SampleZip1-2.zip
      Sample1-2-1.txt
      Sample1-2-2.txt

以下がテストスクリプトです。
  import zipfile
  
  def listZipFile( fileName, indent ) :
  if not zipfile.is_zipfile( fileName ) :
    print( "not zip" + indent + fileName )
  return
  
  print( "zip" + indent + fileName )
  
  zip = zipfile.ZipFile( fileName, 'r' )
  
  for f in zip.namelist():
    listZipFile( f, "¥t"+ indent )
  
  zip.close()
  
  zipFileName = 'SampleZip1.zip'
  listZipFile( zipFileName, "¥t" )

が、結果は以下の通りで、ZIPの中のZIPをZIPファイルと判定してくれないみたいです。
  >findZip.py
  zip SampleZip1.zip
  not zip SampleZip1-2.zip
  not zip Sample1.txt
  not zip Sample2.txt
  not zip SampleZip1-1.zip

ZIPファイル中のファイルに対してzipfile.ZipFile()を使うのは無理があるのかなぁ?
一時ファイルにでもいったん出さないとダメ?
などと想像しているのですが・・・

どなたかよろしくお願いいたします。

【PythonでZIPファイル中のZIPファイルを操作したい】

PythonでZIP内のZIPを再帰的に探して操作したいと考えています。
スクリプトを書いてみたのですが、どうもうまくいきません。
どなたかマズところをご教示いただけないでしょうか?

以下のような構造のデータファイルを用意しました。
  SampleZip1.zip
    Sample1.txt
    Sample2.txt
    SampleZip1-1.zip
      Sample1-1-1.txt
      Sample1-1-2.txt
    SampleZip1-2.zip
      Sample1-2-1.txt
      S...続きを読む

Aベストアンサー

このサイトでは、連続する空白は1つにまとめられ、タブ文字は削られます。
Pythonではインデントが重要な役目を持っているので、全角空白を使うとか、別な文字(^だの_だの)で代りにするとしましょう。

> for f in zip.namelist():
で取り出せるfは、ZIPの中での一覧での名前です。実際にそのファイルがファイルシステム上に存在するわけではないし、その「ZIp内のファイル」にアクセスするために「ファイルのように振舞うオブジェクト」を返すわけでもありません。isZipfileで失敗するのは当然でしょう。

zipfileのマニュアルを読んでみると
read(ZIP内の名前)
でバイト列として取り出せるようなので、
fp=StringIO.StriingIO(zip.read(f))
などとファイル風オブジェクトにして
    listZipFile( fp, "¥t"+ indent )
とするのはどうでしょう。

Qread(buf,int,int)メソッドで1文字取得する

javaを使ってプログラミングを勉強しています。

read(buf,int,int)メソッドで受信したバイトデータをbufに格納していると思うのですが、
格納したバイトの最後の文字を取得する方法が分かりません。

送信側では送信バイトの最後の文字をsにして送信します。
受信側では読み込んだバイトデータの最後の文字がsだったら、
ループを抜けるというようにしたいのです。

どうやって最後の文字を取得するのでしょうか?

Aベストアンサー

read(byte[], int, int)の返値を見れば何バイト読み込めたのかは分かるのですから、その値を使って配列の添字を計算するだけです。

QDebian Linuxでzip: command not found

Debian Linuxでzip: command not foundエラー。

LinuxコマンドでZIPファイルを作ろうとすると、
エラーが発生してしまいます。

zipコマンドをインストールしたいのですが、
インストールコマンド(rpm? apt-get?)がわからず、
インストール用ファイルもWebから見つけられませんでした。

OSはDebian GNU/Linux(Debian 5.0 lenny)です。

WindowsVistaにダウンロードしてきた時に特別な方法を使わず解凍できれば、
ZIP形式にはこだわりません。

zipコマンドを使える方法について詳しい方がいましたら、
教えていただけますでしょうか。
--------------------------------------
# zip test_201010.zip *.gz
-bash: zip: command not found

# whereis zip
zip:

# apt-cache zip
E: Invalid operation zip

# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
--------------------------------------

Debian Linuxでzip: command not foundエラー。

LinuxコマンドでZIPファイルを作ろうとすると、
エラーが発生してしまいます。

zipコマンドをインストールしたいのですが、
インストールコマンド(rpm? apt-get?)がわからず、
インストール用ファイルもWebから見つけられませんでした。

OSはDebian GNU/Linux(Debian 5.0 lenny)です。

WindowsVistaにダウンロードしてきた時に特別な方法を使わず解凍できれば、
ZIP形式にはこだわりません。

zipコマンドを使える方法について詳しい方がいましたら、
教えて...続きを読む

Aベストアンサー

こんにちは。zipをインストールするには"apt-get install zip"でいいのではないでしょうか。下記のページに詳しく載っていました。

http://sato-si.at.webry.info/200703/article_3.html

パッケージ名を探すには、"apt-cache search zip"でいいみたいですね。いったんダウンロードする場合は下記のサイトからたどるといいと思います。Lenny用のzipです。

http://packages.debian.org/stable/utils/zip

蛇足ながら、Debian Linuxにzipをインストールしない、またはできない場合、"tar -cf (格納ファイル名) *.gz"で単一格納ファイルにまとめて、tarアーカイブに対応した展開用ソフトをWindows側にインストールする方法も考えられます。Lhaplus、Lhazなどが使えるようです。

http://www.vector.co.jp/vpack/filearea/win/util/arc/

Q&= ~0x0c; &= ~0x03; |=1;

JavaScriptで分からないコードがあるので教えてください。


■変数設定
var hoge = 0;


■変数格納
・キーを押した時の条件分岐
  ~なら hoge |= 1;
  または hoge |= 2;
  または hoge |= 3;
  または hoge |= 8;

・キーを離した時の条件分岐
  ~なら hoge &= ~0x0c;
  または hoge &= ~0x03;


■変数使用
・swithch文の条件分岐に利用
  (hoge&0x03)
  (hoge&0x0c)


■質問
・どういう意味でしょうか?
・文字コード?
・ビット演算?

Aベストアンサー

ビット演算してるわね

x = x + a

x += a
って書くことができるの

つまり
hoge |= 1

hoge = hoge | 1
のことね

~はNOTのこと

0x
はアスキーコードの16進数表記ねきっと

0x0c は改ページを意味していて
0x03 は文章の最後を意味している
と思われるわ
全文がないので推測だけど

Qダウンロード後 zipファイル削除

アクセスログをZIPファイルにしてダウンロードした後ファイルが自動的に削除されるようにしようと思っていますが、失敗続きです。
今までの軌跡、
1、ZIPファイルをArchive::Zipで作成、print "Location×××.zip:\n\n";でダウンロード後、当該ZIPファイルをunlink
結果、失敗 404エラーになる
2、ZIPファイルをArchive::Zipで作成、print "Location×××.zip:\n\n";でダウンロード後、当該ZIPファイルをENDサブルーチンでunlink
結果、失敗 404エラーになる
3、File::TempをZIPに利用できないか試みるがArchive::Zipはファイルハンドルを使わないため利用できないのではと断念。
とまあこんな感じで現在に至っています。

なぜ削除しなければならないのかというと外部からアクセスされるとアクセスログがダウンロードできるとこまるからです。なのでダウンロード後すぐに削除、できればダウンロード後すぐ削除されれば理想と思っています。
3、に関してですが、ならばZIPにしないでテキストでダウンロードさせればいいじゃんと思うかもしれませんが、色々なファイルをまとめてダウンロードさせたいと思っているので、それはできない状況。

手段を知っている方助けてください。

アクセスログをZIPファイルにしてダウンロードした後ファイルが自動的に削除されるようにしようと思っていますが、失敗続きです。
今までの軌跡、
1、ZIPファイルをArchive::Zipで作成、print "Location×××.zip:\n\n";でダウンロード後、当該ZIPファイルをunlink
結果、失敗 404エラーになる
2、ZIPファイルをArchive::Zipで作成、print "Location×××.zip:\n\n";でダウンロード後、当該ZIPファイルをENDサブルーチンでunlink
結果、失敗 404エラーになる
3、File::TempをZIPに利用できないか試みるがArchi...続きを読む

Aベストアンサー

ファイルのダウンロードをさせならが、ファイル名を宣言すればOKです。


print qq|Content-Type: application/octet-stream\n|;
print qq|Content-Type: application/download; name="$filename"\n|; # $filename=target.zip
print qq|Content-Disposition: attachment; filename="$filename"\n|;
# print qq|Content-Length: $filesize\n|; # 設定すればダウンロード時間が表示されます
print qq|\n|;

Qnew RegExp('[\\?&]' + hog

下記、正規表現の意味を教えてください

var x = new RegExp('[\\?&]' + hoge);



■調べてみた限りでは下記のような感じだと思うのですが…
\?
・0文字または1文字の\

[\?]
・「0文字または1文字の\」の何れか

[\?&]
・「0文字または1文字の\」の何れか、の最後にマッチ

[\\?&]
・最初の\はエスケープ

new RegExp('[\\?&]' + hoge);
・引数で受け取った文字列の最後の\をエスケープした内容にhogeを追加した文字列を返す

Aベストアンサー

概ね、#1の方が仰るとおりですが、一つだけ訂正事項があります。

[] は "\" と "]" と "^" (先頭に限る) 以外はエスケープせずともメタキャラクタとして扱われません。
ただし、文字列リテラルとして扱う場合は "\" がメタキャラクタとなる為、new RegExp 内で "\\" を表現する為には "\\\\" と記述する必要があります(文字列リテラル、正規表現で2回エスケープが発生する為)。
従って、new RegExp('[\\?&]') は "?" または "&" にマッチする正規表現となります。

console.log(new RegExp('[\\?&]').test('\\')); // false
console.log(new RegExp('[\\?&]').test('?')); // true
console.log(new RegExp('[\\?&]').test('&')); // true

文字クラス内の "\\" は後続文字をエスケープする意味しかもたず、この場合はなくても結果が変わりません。
コード製作者のミスと思われます。

# Re: re97さん

概ね、#1の方が仰るとおりですが、一つだけ訂正事項があります。

[] は "\" と "]" と "^" (先頭に限る) 以外はエスケープせずともメタキャラクタとして扱われません。
ただし、文字列リテラルとして扱う場合は "\" がメタキャラクタとなる為、new RegExp 内で "\\" を表現する為には "\\\\" と記述する必要があります(文字列リテラル、正規表現で2回エスケープが発生する為)。
従って、new RegExp('[\\?&]') は "?" または "&" にマッチする正規表現となります。

console.log(new RegExp('[\\?&]').test('\\'))...続きを読む

Q間違えて、77ZIPをインストールしてしまいました

間違えて、77ZIPというモノをインストールしてしまいました。

すると、今まで普通のZIPファイルだったものが、全て77ZIPに変更されてしまいました。

間違いに気づいて、77ZIPを削除してしまったので、今度は77ZIPに変更されたファイルが
開かなくなりました。

77ZIPになってしまったファイルを、前の普通のZIPファイルに戻すことはできますでしょうか?

パソコン初心者なので、できるだけ簡単に教えていただければ助かります。

お詳しい方がいらっしゃいましたら、ご面倒をかけますが、どうぞよろしくお願いいたします。

Aベストアンサー

77ZIPというのは、ZIP解凍ソフトですよ。
関連付けが77ZIPになっただけじゃないですか?
変更されたと思っているZIPファイルを、ダブルクリックで開いてみてください。
開けるのであれば、関連付け(規定のプログラム)を変更するだけです。
ZIPファイルを右クリックして、「プログラムから開く」で「エクスプローラー」を選択。

質問にない余計なおせっかいですが、
Babyron tool barやBabyron Searchなどが入ってしまったなどの被害はありませんか?
そちらについては、下記サイトに削除法があります。
http://www.geocities.co.jp/Playtown-Yoyo/6130/notes/babylon-toolbar-search.htm

QA a = new A(){}; の構文の意味が分からない。

下記サイトのコードを読んでいて、

ResponseListener listener = new ResponseListener() {
//略
};

という書き方があったのですが、どういう意味になるのでしょうか?
インスタンスの作り方は単に

A a = new A();

だと思うのですが…。

http://www.snmp4j.org/doc/org/snmp4j/Snmp.html

Aベストアンサー

無名クラスと呼ばれるものよ。
私も良くやるわ。

ちなみに
A a = new A();
はできないわよ。
Aはインターフェースだからね。


上記の場合、正式に実装するなら、
ResponseListenerをimplementsした
MyResponseListener(仮名)を別途作成し、
それを
ResponseListener listener = new MyResponseListener();
とする必要があるわ。
でも、このMyResponseListenerは
今ここでしか使わない、他からまったく参照する必要のない
超ローカルなクラスなのよ。
このメソッドが終了すればGCにかけてもいいわけ。
そんな場合、わざわざクラスを1つ作る必要なくて
その場でちょちょいとやってしまうことができるのよ。
それが無名クラスっていう実装方法よ。

http://www.javaroad.jp/java_class15.htm

FileFilterやCompare、Runnableなんかで
他のクラスで再利用しないときは良くやるわ。

無名クラスと呼ばれるものよ。
私も良くやるわ。

ちなみに
A a = new A();
はできないわよ。
Aはインターフェースだからね。


上記の場合、正式に実装するなら、
ResponseListenerをimplementsした
MyResponseListener(仮名)を別途作成し、
それを
ResponseListener listener = new MyResponseListener();
とする必要があるわ。
でも、このMyResponseListenerは
今ここでしか使わない、他からまったく参照する必要のない
超ローカルなクラスなのよ。
このメソッドが終了すればGCにかけても...続きを読む


人気Q&Aランキング