[解決済み] Javaで文字列を安全にエンコードしてファイル名として使用するにはどうすればよいですか?
2022-06-15 15:06:40
質問
外部プロセスから文字列を受信しています。私はその文字列を使用してファイル名を作成し、そのファイルに書き込むことを望んでいます。これを行うための私のコードスニペットは次のとおりです。
String s = ... // comes from external source
File currentFile = new File(System.getProperty("user.home"), s);
PrintWriter currentWriter = new PrintWriter(currentFile);
s が Unix 系 OS の '/' のような無効な文字を含む場合、java.io.FileNotFoundException が(正しく)スローされます。
ファイル名として使用できるように文字列を安全にエンコードするにはどうしたらよいでしょうか。
編集:私が望んでいるのは、これをやってくれるAPIコールです。
私はこれをすることができます。
String s = ... // comes from external source
File currentFile = new File(System.getProperty("user.home"), URLEncoder.encode(s, "UTF-8"));
PrintWriter currentWriter = new PrintWriter(currentFile);
しかし、私はURLEncoderがこの目的のために信頼できるかどうかわからない。
どのように解決するのですか?
元のファイルと同じような結果を得たい場合、SHA-1 やその他のハッシュ方式では解決できません。 衝突を避けなければならない場合、単純な置換や悪い文字の除去も解決策にはなりません。
代わりに、次のようなものが必要です。 (注意: これは説明のための例として扱われるべきで、コピー アンド ペーストするためのものではありません)。
char fileSep = '/'; // ... or do this portably.
char escape = '%'; // ... or some other legal char.
String s = ...
int len = s.length();
StringBuilder sb = new StringBuilder(len);
for (int i = 0; i < len; i++) {
char ch = s.charAt(i);
if (ch < ' ' || ch >= 0x7F || ch == fileSep || ... // add other illegal chars
|| (ch == '.' && i == 0) // we don't want to collide with "." or ".."!
|| ch == escape) {
sb.append(escape);
if (ch < 0x10) {
sb.append('0');
}
sb.append(Integer.toHexString(ch));
} else {
sb.append(ch);
}
}
File currentFile = new File(System.getProperty("user.home"), sb.toString());
PrintWriter currentWriter = new PrintWriter(currentFile);
この解決策は可逆的なエンコーディング(衝突がない)をもたらし、エンコードされた文字列はほとんどの場合、元の文字列に類似しています。 私はあなたが8ビット文字を使用していると仮定しています。
URLEncoder
は動作しますが、合法的なファイル名文字全体をエンコードしてしまうという欠点があります。
可逆性が保証されない解決策を望むなら、エスケープ シーケンスで置き換えるのではなく、単に「悪い」文字を削除してください。
上記のエンコーディングの逆も同様に簡単に実装できるはずです。
関連
-
SocketTimeoutExceptionの解決方法です。読み込みがタイムアウトした
-
[解決済み] JavaScriptで文字列が部分文字列を含むかどうかを確認する方法は?
-
[解決済み] JavaでInputStreamを読み込んでStringに変換するにはどうすればよいですか?
-
[解決済み] Javaでメモリーリークを発生させるにはどうしたらいいですか?
-
[解決済み] JavaでArrayListではなくLinkedListを使用するのはいつですか?
-
[解決済み] JavaでStringをintに変換するにはどうしたらいいですか?
-
[解決済み] 文字列の単語を反復処理するにはどうすればよいですか?
-
[解決済み] Javaで文字列を分割する方法
-
[解決済み] ファイルの内容からJavaの文字列を作成するにはどうすればよいですか?
-
[解決済み】JavaScriptで文字列の出現箇所をすべて置換する方法
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
スタイルシートとして解釈されるリソースが、MIMEタイプtext/htmlで転送される。
-
Java Exceptionが発生しました エラー解決
-
final, finally, finalizeの違いについて話してください。
-
SpringBootApplication を型解決できない。
-
をインスタンス化することができません。
-
Android Studio 3.1.2 で v4, v7 パッケージが見つからない シンボル 'AppCompatActivity' を解決できない
-
VMの初期化中にエラーが発生しました java/lang/NoClassDefFoundError: java/lang/Object
-
自動配線された依存性のインジェクションに失敗しました。
-
Eclipse起動エラー:javaは起動したが、終了コード=1を返した(ネット上の様々な落とし穴)
-
JSPで「リストが型解決できない!」の解決方法