101

私のプログラムは、インターネットから任意の文字列を取得し、それらをファイル名に使用します。これらの文字列から悪い文字を削除する簡単な方法はありますか、それともカスタム関数を作成する必要がありますか?

4

14 に答える 14

184

うーん、人々がどの文字が有効であるかを推測しようとするとき、私はそれを嫌います。完全に移植性がない(常にMonoについて考えている)ことに加えて、以前のコメントは両方とも25以上の無効な文字を見逃していました。

foreach (var c in Path.GetInvalidFileNameChars()) 
{ 
  fileName = fileName.Replace(c, '-'); 
}

またはVBの場合:

'Clean just a filename
Dim filename As String = "salmnas dlajhdla kjha;dmas'lkasn"
For Each c In IO.Path.GetInvalidFileNameChars
    filename = filename.Replace(c, "")
Next

'See also IO.Path.GetInvalidPathChars
于 2008-12-02T07:35:06.203 に答える
45

無効な文字を削除するには:

static readonly char[] invalidFileNameChars = Path.GetInvalidFileNameChars();

// Builds a string out of valid chars
var validFilename = new string(filename.Where(ch => !invalidFileNameChars.Contains(ch)).ToArray());

無効な文字を置き換えるには:

static readonly char[] invalidFileNameChars = Path.GetInvalidFileNameChars();

// Builds a string out of valid chars and an _ for invalid ones
var validFilename = new string(filename.Select(ch => invalidFileNameChars.Contains(ch) ? '_' : ch).ToArray());

無効な文字を置き換える (そして、Hell* と Hell$ のような潜在的な名前の競合を回避するには):

static readonly IList<char> invalidFileNameChars = Path.GetInvalidFileNameChars();

// Builds a string out of valid chars and replaces invalid chars with a unique letter (Moves the Char into the letter range of unicode, starting at "A")
var validFilename = new string(filename.Select(ch => invalidFileNameChars.Contains(ch) ? Convert.ToChar(invalidFileNameChars.IndexOf(ch) + 65) : ch).ToArray());
于 2010-09-09T15:58:10.483 に答える
34

この質問はこれまで何度も出されてきましたが、 指摘されているように、適切ではありません。IO.Path.GetInvalidFileNameChars

まず、PRN や CON など、予約されていてファイル名に使用できない名前が多数あります。ルート フォルダーでのみ許可されていない他の名前があります。ピリオドで終わる名前も許可されていません。

第二に、さまざまな長さの制限があります。NTFS の完全なリストについては、こちらを参照してください。

第 3 に、他の制限があるファイルシステムにアタッチできます。たとえば、ISO 9660 ファイル名は「-」で始めることはできませんが、含めることはできます。

第 4 に、2 つのプロセスが「恣意的に」同じ名前を選んだらどうしますか?

一般に、ファイル名に外部で生成された名前を使用することはお勧めできません。独自のプライベート ファイル名を生成し、人間が判読できる名前を内部に保存することをお勧めします。

于 2010-09-09T16:24:47.190 に答える
22

私はGrauenwolfに同意し、強くお勧めしますPath.GetInvalidFileNameChars()

ここに私のC#の貢献があります:

string file = @"38?/.\}[+=n a882 a.a*/|n^%$ ad#(-))";
Array.ForEach(Path.GetInvalidFileNameChars(), 
      c => file = file.Replace(c.ToString(), String.Empty));

ps -- これは必要以上に不可解です -- 簡潔にしようとしていました。

于 2008-12-02T08:03:36.737 に答える
12

これが私が現在使用している関数です(C#の例についてjcollumに感謝します):

public static string MakeSafeFilename(string filename, char replaceChar)
{
    foreach (char c in System.IO.Path.GetInvalidFileNameChars())
    {
        filename = filename.Replace(c, replaceChar);
    }
    return filename;
}

便宜上、これを「ヘルパー」クラスに入れました。

于 2010-08-06T17:47:03.537 に答える
1

これを使用すると、すばやく簡単に理解できることがわかります。

<Extension()>
Public Function MakeSafeFileName(FileName As String) As String
    Return FileName.Where(Function(x) Not IO.Path.GetInvalidFileNameChars.Contains(x)).ToArray
End Function

これstringIEnumerable、 aがchar配列であり、配列stringを取るコンストラクター文字列があるため機能しcharます。

于 2013-04-09T18:28:04.637 に答える
0

Path.GetInvalidFileNameChars()多くの答えは、私には悪い解決策のように思える使用を提案しています。ブラックリストではなくホワイトリストを使用することをお勧めします。ハッカーは常に最終的にそれを回避する方法を見つけるからです。

使用できるコードの例を次に示します。

    string whitelist = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.";
    foreach (char c in filename)
    {
        if (!whitelist.Contains(c))
        {
            filename = filename.Replace(c, '-');
        }
    }
于 2019-01-11T14:59:18.657 に答える