6

ユーザーが入力した名前からファイル名を生成する必要があります。これらの名前はどの言語でもかまいません。例えば:

  • "ジョンスミス"
  • 「高岡和子」
  • "محمدسعيدبنعبدالعزيزالفلسطيني"

これらは入力値を使用しているため、ファイル名に無効な文字が名前に含まれていないことを保証するものではありません。

ユーザーはブラウザからこれらのファイルをダウンロードするため、ファイル名がすべての構成のすべてのオペレーティングシステムで有効であることを確認する必要があります。

私は現在、単純な正規表現ですべての英数字以外の文字を削除することにより、英語圏の国でこれを行っています。

string = string.replaceAll("[^a-zA-Z0-9]", "");
string = string.replaceAll("\\s+", "_")

いくつかの変換例:

  • 「ジョン・スミス」->「John_Smith.ext」
  • "John O'Henry"-> "John_OHenry.ext"
  • 「ジョン・ヴァン・スミスIII」->「John_van_Smith_III.ext」

明らかに、これは国際的には機能しません。

すべてのファイルシステムで無効なすべての文字のブラックリストを見つけて生成し、名前からそれらを取り除くことを検討しました。包括的なリストを見つけることができませんでした。

可能であれば、共通のライブラリにある既存のコードを使用したいと思います。これはすでに解決された問題だと思いますが、国際的に機能する解決策を見つけることができません。

ファイル名は、ファイルをダウンロードするユーザー用であり、私用ではありません。これらのファイルを保存するつもりはありません。これらのファイルは、データベース内のデータからの要求に応じてサーバーによって動的に生成されます。ファイル名は、ファイルをダウンロードする人の便宜のためのものです。

4

6 に答える 6

4

[^a-zA-Z0-9]正規表現は、Unicode 文字または 128 コードポイントを超える文字を除外する非 ASCII 文字をフィルタリングします。

? \ / : | < > *アンダースコア ( )などの無効なファイル名文字を置き換えて、有効なファイル名のユーザー入力をフィルター処理する場合_:

import java.io.UnsupportedEncodingException;

public class ReplaceI18N {

    public static void main(String[] args) {
        String[] names = {
                "John Smith",
                "高岡和子",
                "محمد سعيد بن عبد العزيز الفلسطيني",                
                "|J:o<h>n?Sm\\it/h*", 
                "高?岡和\\子*", 
                "محمد /سعيد بن عبد ?العزيز :الفلسطيني\\"
                };

        for(String s: names){
            String u  = s;
            try {
                u = new String(s.getBytes(), "UTF-8");
            } catch (UnsupportedEncodingException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } 
            u = u.replaceAll("[\\?\\\\/:|<>\\*]", " "); //filter ? \ / : | < > *
            u = u.replaceAll("\\s+", "_");
            System.out.println(s + " = " + u);
        }
    }
}

出力:

John Smith = John_Smith
高岡和子 = 高岡和子
محمد سعيد بن عبد العزيز الفلسطيني = محمد_سعيد_بن_عبد_العزيز_الفلسطيني
|J:o<h>n?Sm\it/h* = _J_o_h_n_Sm_it_h_
高?岡和\子* = 高_岡和_子_
محمد /سعيد بن عبد ?العزيز :الفلسطيني\ = محمد_سعيد_بن_عبد_العزيز_الفلسطيني_

Unicode 文字を含む有効なファイル名は、正しい Unicode フォントを使用した UTF-8 エンコーディングをサポートする Web ページで表示できます。

さらに、それぞれが、Unicode をサポートする任意の OS ファイル システム上のそのファイルの正しい名前になります (Windows XP、Windows 7 で問題なくテストされています)。

i18n ファイル名

ただし、有効なファイル名をそれぞれ URL 文字列として渡したい場合は、必ず を使用して適切にエンコードしURLEncoder、後で を使用してエンコードされた各 URL をデコードしてURLDecoderください。

于 2012-04-14T07:14:51.323 に答える
0

適切なサニタイズを行わずに入力にファイル名を決定させると、セキュリティ攻撃が発生しやすくなります。ハッシュ関数(SHA-1、MD5)を使用して、有効なファイル名を生成できます。ハッシュから元の名前を取得することはできないことに注意してください。

また、単純なルックアップテーブルを作成できる場合は、名前に特別な識別子(連番やGUIDなど)を割り当て、その識別子をファイル名として使用できます。

もう一つ、同音異義語について考えたことはありますか?

于 2012-04-14T03:59:13.673 に答える
0

ファイル名をUTF-8としてエンコードしてから、結果をURLエンコードします。

'高岡和子' -> '%E9%AB%98%E5%B2%A1%E5%92%8C%E5%AD%90'
于 2012-04-14T04:02:34.183 に答える
0

WindowsはUnicodeファイル名をサポートしているように見えますが、Linuxはサポートしていることは知っていますが、OSXもサポートしているようです。おそらく、よく書かれていると、ファイル名を保存する前に、ファイル名の無効な文字が修正されます。

Unicodeファイル名だけを使用できるはずです。これが動作しないOSまたはブラウザはありますか?

于 2012-04-14T04:03:47.117 に答える
0

@eeeの答えを要約して言い換えると...

String sanitizeFilename(String unsanitized) {
     return unsanitized
                .replaceAll("[\\?\\\\/:|<>\\*]", " ") // filter out ? \ / : | < > *
                .replaceAll("\\s", "_");              // white space as underscores
}

(複数のスペースを 1 つに結合しないでください!)

于 2013-03-20T09:54:12.967 に答える
0

私のアドバイスは、アプリケーションが Unicode ファイル名をサポートするプラットフォームで実行されることを要件にすることです。最近はほとんどがそうしています。

人間の可読性と元の意味を保持し、衝突を回避しながら、Unicode から (指定されていない) 制限された文字セットにマップすることは実行可能ではないと思います。実際、Latin-1 から ASCII へのこのマッピングを行うことさえできません。

Unicode ファイル名をサポートしていないプラットフォームでアプリケーション実行する必要がある場合、場合によっては、人間の読みやすさやファイル名の意味を犠牲にする必要があります。さらに、(たとえば) ASCII 化された漢字、キリル文字、またはアクセントを取り除いた文字がエンド ユーザーに受け入れられるかどうかを検討してください。


私がしたいことは、ユーザーに次の 2 つのオプションから選択できるようにすることです。

  • アップロードされたファイルに Unicode ファイル名を使用するオプション。ほとんどのユーザーのマシンがこれをサポートするため、これがデフォルトであるべきです。

  • 元の文字列/テキストに関連しない生成された名前を使用するフォールバック オプション。

実際には、ユーザーのマシンが Unicode をサポートしていない場合、マシンのネイティブ エンコーディングを使用してエンコードされていないテキスト名を処理する際に大きな問題が発生します。それが何であるかを知るための完全に信頼できる方法はありません。それを理解するためのある程度信頼できる方法があったとしても...サーバー側で...すべてのUnicodeをそのエンコーディングにマッピングする問題は扱いにくいです。

オペレーティング システムを Unicode 対応のものにアップグレードすることをユーザーに奨励することをお勧めします。

于 2012-04-14T05:53:21.723 に答える