2012-09-12 13 views
6

私は、URLからファイルを読み込むはずのjavaプログラムを持っています(URLの場所はIIS Webサイトの下の仮想ディレクトリです。他のファイルシステムの場所と同様に扱います)。残念ながら、読み込む必要があるすべてのファイルへのパスには、ディレクトリ名の1つにシャープ記号(#)が含まれています。変更するために何もできません。このプログラムは、(テストとして)パスにそのポンド記号がない場所を指しているときに、美しく動作します。Java URIのポンド記号の符号化

私は、プログラムに渡された文字列からURLを作成することから始めました。ある

file://serverIPaddress/Documents/\%232012/09/07/16/DOC4671179.DOC 

シャープ記号で、:私は、コマンドライン上でそれをこのようなパスを渡された場合/Documents/#2012/09/11のようなファイルパス(ドキュメントは、Windowsのシェアがある)のために、私は、プログラムが正常に処理するために得ることができ%23として手動でエンコードされ、バックスラッシュは%23の%をエスケープします。

はそのURLを取得するだけで1行がありました:

URL url = new URL(filePath); // filePath is passed in 

をしかし、プログラムはそのようなエンコードされたパスをスプーン-供給することになるだろうされていないので、私はポンドをエンコードする方法を見つけ出す必要がありましたプログラムで署名します。 how to encode URL to avoid special characters in javaにある良いアドバイスに続き、私は複数の引数のコンストラクタを使用してURIを作成しました(私は、その変更に対応するために3つの個別のパラメータにプログラムに渡していたパラメータを分割しました)。ここにそのようなものがあります:

URI uri = new URI(protocol, host, filePath, null); // all values are passed in 

ポンド記号を正しく符号化しました。

file://serverIPaddress/Documents/%232012/09/07/16/DOC4671179.DOC 

しかし%23の前にバックスラッシュせずに、プログラムはそれがバックスラッシュの恩恵なしにパスを誤って解釈だと思われるので、Connection refusedに戻ってきた:私のURIでした。

だから私は自分でバックスラッシュを追加します。同じURIを作成し、rawPathを抽出し、少しの文字列操作で%23の前にバックスラッシュを入れました。バックスラッシュとエンコード%の両方で

file://<serverIPaddress>/Documents/%5C%25232012/09/07/16/DOC4671179.DOC 

:私は、このようなURIを与えたこと、予想通り、しかし

URI uri = new URI(protocol, host, filePath, null); // all values are passed in 
String rawPath = uri.getRawPath(); 
int pctPos = rawPath.indexOf("%"); 
String escaped = new String("\\"); 
String firstPart = rawPath.substring(0,pctPos); 
String secondPart = rawPath.substring(pctPos); 
String newPath = firstPart + escaped + secondPart; 
URI uri2 = new URI(protocol, host, newPath, null); 

:私は、その新しい文字列を使用して、新しいURIを作成しました。意味はありますが、実行時にはまだ動作しません。

URL APIは言う:

URLクラス自体がRFC2396で定義されたエスケープ機構によれば、任意のURLコンポーネント を符号化または復号しません。それは は、[OK]を、私は思ったので

URLを呼び出すのではなく、二URIを作成する前にエスケープする必要が任意のフィールドを、エンコードする呼び出し側の 責任であり、私はそれからURLを作成します

URI uri = new URI(protocol, host, filePath, null); // all values are passed in 
String rawPath = uri.getRawPath(); 
int pctPos = rawPath.indexOf("%"); 
String escaped = new String("\\"); 
String firstPart = rawPath.substring(0,pctPos); 
String secondPart = rawPath.substring(pctPos); 
String newPath = firstPart + escaped + secondPart; 
URL url = new URL(protocol + "://" + host + newPath); 

しかし、そのアプローチでは、と私の新しいパスが良い見ていても::結果のURLは、として戻ってくる

/Documents/\%232012/09/07/16/DOC4671179.DOC 

私は最後の試みで生成された新しい文字列:%23の代わりに、バックスラッシュの前に余分なスラッシュと

file://serverIPAddress/Documents//%232012/09/07/16/DOC4671179.DOC 

これで私はアイデアを使い果たしました。

  • この最後のアプローチでバックスラッシュをURLにスラッシュにするのはなんですか?

  • 必要なURI/URLを取得するにはどうすればよいですか?

  • 私は質問する必要があります:%23が正当なURIまたはURLの一部である場合、なぜ%23の%がエスケープされなければならないのですか?代わりにそれについて?

+0

「接続が拒否されました」というURLに何を渡していますか? – nneonneo

+0

この関連するServerFaultの質問のいくつかの情報:http://serverfault.com/q/257680 – barrowc

+0

nneonneo - 私はあなたの質問を理解しているかわかりません。プログラムは、URLへの接続を開き、InputStreamを取得し、次にInputStreamReader、次にBufferedReaderを読み込み、ファイルから読み取ります。接続を拒否するエラーは、InputStreamを取得しようとしたときに発生します。 URLConnection urlConn = url.openConnection(); urlConn.setDoInput(true); InputStream is = urlConn.getInputStream(); InputStreamReader isr =新しいInputStreamReader(あり); br = new BufferedReader(isr); – user1664369

答えて

0

「\」が必要な理由がわかりません。それはサーバーコードに依存します。実際には "\"はURLの法的な文字ではありません。%5C

URIのクラスはかなり面倒です。ファイルのURLを "\"から "/"に変更することがあります。

代わりにこれを試してみてください:

String filePath = "/Documents/#2012/09/11"; 
    filePath = filePath.replace("#", "\\#"); 
    URI uri = new URI("file", "serverAddress", filePath, null); 

"#" を "%5C%23" に変更されます。それが動作するかどうかを確認します。

+0

提案していただきありがとうございます。予想通り、 'replace'はURIを' file:// serverAddress/Documents /%5C%232012/09/11/filename'としますが、そのURIはInputStreamを取得しようとすると "IOException:connection refused" (URIからURLを作成した後、URLへの接続を開くなど)。 – user1664369

+0

新しいURL( "file://" + serverAddress + filePath.replace( "#"、 "\\%23") ' – irreputable

+0

良いアイデアですが、URLには' file:// 172.28.60.68/Documents //%232012/09/11/DOC4671179.DOC' - 要求されたバックスラッシュの代わりにフォワードスラッシュ。そのクラスについて、バックスラッシュが嫌いなものがあります。文字列コンストラクタ内のUNCパスが動作するかもしれません。私は生産上の問題によって引き離されていますが、私は瞬間を取るときに試してみます。 – user1664369

関連する問題