2013-07-04 4 views
5

getResourceAsStream -methodは感嘆符で終わるディレクトリで実行可能なjarを実行するたびにnullを返します。次のように私はLogo.pngを読んでいる感嘆符(!)で終わるディレクトリでリソースを開くことができません

src\ (Source Folder) 
    main\ (Package) 
     Main.java 
    res\ (Source Folder) 
     images\ 
      Logo.png 

public static void main(String[] args) throws IOException { 
    try (InputStream is = Main.class.getClassLoader().getResourceAsStream("images/Logo.png")) { 
     Image image = ImageIO.read(is); 
     System.out.println(image); 
    } 
} 

は2テストのために、添付ファイルを参照してください。次の例では、私は、Eclipseプロジェクトに次のディレクトリ構造を

を持っていますケース。まず、実行可能なjarはディレクトリ "D:¥test123!@#"から問題なく起動されます。第2に、実行可能なjarはディレクトリ "D:¥test123!@#!!!"から起動され、問題があります。

感嘆符で終わるディレクトリはサポートされていませんか?コードが間違っていますか?

ありがとうございます。おそらくこのためにバグやJavaのバグデータベースには多くの類似したバグのいずれかの

Error when running the executable jar in a directory ending with !

+0

通常の名前のディレクトリを作成/使用する理由はありますか? – mtk

+0

両方のディレクトリに同じjarファイルを置いてもよろしいですか? – Andremoniy

+0

ユーザーは自分のファイルシステムのどこからでもアプリケーションを実行できます。感嘆符付きのディレクトリはWindowsでサポートされています。 – Velth

答えて

7

http://bugs.sun.com/view_bug.do?bug_id=4523159

理由は、「!/」ジャーURLでは解釈されていることですJARファイル名とJAR内のパスの間の区切り文字として使用します。ディレクトリ名の末尾が!で終わると、ディレクトリの最後の "!/"文字列が正しく解釈されません。

のjar::ファイル:/// D:!/ test1231 @#!!! /test.jar /images/Logo.png

あなたのケースでは、実際には、次のURLでリソースにアクセスしようとしています

バグは約12年間開いており、修正される可能性は低いです。実際に私はそれが他のものを壊すことなく修正される方法を知らない。問題は、使用するデザインの決定です!感嘆符は、URLで許可される文字がある

jar:<URL for JAR file>!/<path within the JAR file> 

ので、それのように、JARファイル自体へのURLの両方で発生する可能性があります。JARファイルのURLスキームで特別な意味(セパレータ)との文字としてJARファイル内のパスと同じように、実際の "!/"セパレータを見つけることができないことがあります。

+0

Javaで何かをしてURLを "!/"で解析しなければならないと思ったが、バグだろう。とにかく、この問題を解決する回避策がありますか? – Velth

+0

いいえ、リンク先のバグにも記載されているように、この問題の回避策はありません。 – jarnbjo

1

Windowsで簡単に回避するには、パスに「/」の代わりに「\」を使用します。これは、完全なパスの後に "!/"文字シーケンスが見つかることを意味します。例えば:

new URL("jar:file:\\d:\\[email protected]#!!!\\test.jar!/images/Logo.png"); 

マイコード:

File jar = new File(jarPath + "/" + jarName); 
URL url = new URL("jar:" + jar.toURI() + "!" + dataFilePath); 
InputStream stream = null; 
try { 
    stream = url.openStream(); 
} catch (FileNotFoundException e) { 
    // Windows fix 
    URL urlFix = new URL("jar:" + jar.toURI().toString().replace('/', '\\') 
     + "!" + dataFilePath); 
    stream = urlFix.openStream(); 
} 

それはスペースのようなものを扱うので、私はtoURI()を使用します。

修正:Javaは投げ、その後、ファイルが存在するかどうかを確認していない場合はセパレータが排出されるまで、次の区切り(「!/」URLの一部)に継続するため

修正自体は次のようになります例外。だからそれは "d:\ test1231 @#!!" java.io.FileNotFoundExceptionがスローされ、存在する「d:\ test1231 @#!!! \ test.jar」が試されます。こうすれば、「!」があるかどうかは関係ありません。ファイルパスまたはjarファイルに保存されます。

また、「!/」は、違法なファイル名または特定のもの(「jarpath:」など)に切り替えることができます。

また、jarのファイルパスに別のパラメータを使用するようにしてください。

注:

それは、何かを上書きするハンドラを交換し、以降のjarファイルの中に見えるが、私は見ていない、最初のファイルを開くためのコードを変更することも可能です。

関連する問題