URLからファイルを読み取ることになっているJavaプログラムがあります(URLの場所はIIS Webサイトの下の仮想ディレクトリです。以下、最初のテストでは、他のファイルシステムの場所と同じように扱っています)。残念ながら、読み取る必要のあるすべてのファイルへのパスには、ディレクトリ名の1つにポンド記号(#)が含まれており、それを変更するために私ができることは何もありません。このプログラムは、(テストとして)パスにポンド記号がない場所を指すと、美しく機能します。
プログラムに渡された文字列からURLを作成することから始めました。(DocumentsがWindows共有である)のようなファイルパスの/Documents/#2012/09/11
場合、コマンドラインで次のようなパスを渡せば、プログラムを正常に処理できます。
file://serverIPaddress/Documents/\%232012/09/07/16/DOC4671179.DOC
つまり、ポンド記号が手動でとしてエンコードされ%23
、バックスラッシュが%23の%をエスケープします。
そのURLを取得するための行は1行だけでした。
URL url = new URL(filePath); // filePath is passed in
しかし、プログラムにはそのようなエンコードされたパスがスプーンで供給されることはないので、プログラムでポンド記号をエンコードする方法を理解する必要がありました。Javaで特殊文字を回避するためにURLをエンコードする方法で見つかった良いアドバイスを続けて、マルチ引数コンストラクターを使用してURIを作成しました(プログラムに渡したパラメーターを、その変更に対応するために3つの別々のパラメーターに分割しました) 。これがそのように見えた:
URI uri = new URI(protocol, host, filePath, null); // all values are passed in
これにより、ポンド記号が適切にエンコードされました。私のURIは次のとおりです。
file://serverIPaddress/Documents/%232012/09/07/16/DOC4671179.DOC
しかし、の前にバックスラッシュがないと%23
、プログラムはで戻ってきましたConnection refused
。おそらく、そのバックスラッシュの恩恵を受けずにパスを誤って解釈しているためです。
だから、私は自分でバックスラッシュを追加しようと思いました。同じURIを作成し、そのrawPathを抽出し、文字列を少し操作して、%23の前に円記号を付けました。次に、その新しい文字列を使用して新しい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を与えました:
file://<serverIPaddress>/Documents/%5C%25232012/09/07/16/DOC4671179.DOC
バックスラッシュと%の両方がエンコードされています。理にかなっていますが、実行時には機能しません。
URLAPIによると:
URLクラス自体は、RFC2396で定義されているエスケープメカニズムに従ってURLコンポーネントをエンコードまたはデコードしません。URLを呼び出す前にエスケープする必要があるフィールドをエンコードするのは、呼び出し元の責任です。
したがって、2番目の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);
しかし、そのアプローチでは、私の新しいパスは次のように見えましたが、
/Documents/\%232012/09/07/16/DOC4671179.DOC
結果のURLは次のように返されます。
file://serverIPAddress/Documents//%232012/09/07/16/DOC4671179.DOC
バックスラッシュの代わりに、%23の前に余分なスラッシュを付けます。
そしてそれで私はアイデアを使い果たしました。
この最後のアプローチのバックスラッシュがURLのフォワードスラッシュに変わる理由は何ですか?
必要なURI/URLを取得するにはどうすればよいですか?
または、おそらく私は尋ねる必要があります:%23が正当なURIまたはURLの一部である場合、プログラムが最初に%23の%をエスケープする必要があるのはなぜですか?代わりにそれについて何かできることがありますか?