2

おそらく、これをグーグルで検索し、MSDN のドキュメントを読むのに約 500 時間を費やしましたが、それでも思い通りに動作しません。

次のようなファイルの名前で並べ替えることができます。

01.png
02.png
03.png
04.png

つまり、すべて同じファイル長です。

2 番目に長いファイル長のファイルがあると、すべてが地獄に落ちます。

たとえば、シーケンスでは次のようになります。

1.png
2.png
3.png
4.png
5.png
10.png
11.png

それは読みます:

1.png, 2.png then 10.png, 11.png

私はこれをしたくありません。

私のコード:

DirectoryInfo di = new DirectoryInfo(directoryLoc);
FileSystemInfo[] files = di.GetFileSystemInfos("*." + fileExtension);
Array.Sort<FileSystemInfo>(files, new Comparison<FileSystemInfo>(compareFiles));

foreach (FileInfo fri in files)
{
    fri.MoveTo(directoryLoc + "\\" + prefix + "{" + operationNumber.ToString() + "}" + (i - 1).ToString("D10") +
        "." + fileExtension);

    i--;
    x++;
    progressPB.Value = (x / fileCount) * 100;
}

// compare by file name
int compareFiles(FileSystemInfo a, FileSystemInfo b)
{
    // return a.LastWriteTime.CompareTo(b.LastWriteTime);
    return a.Name.CompareTo(b.Name);
}
4

5 に答える 5

3

特にファイルの長さの問題ではありません。名前が辞書順で比較されることの問題です。

この特定のケースでは、拡張子なしで名前を取得し、それを整数として解析して、そのように 2 つの名前を比較したいようです。それが失敗した場合は、辞書式順序にフォールバックできます。

もちろん、「debug1.png、debug2.png、...debug10.png」がある場合は機能しません...その場合、より洗練されたアルゴリズムが必要になります。

于 2012-03-13T10:55:10.127 に答える
3

名前をstringとして比較していますが、(私は推測していますが) numberで並べ替えたいと思っています。

これは、10 (1) の最初の文字が 9 の最初の文字よりも小さいため、「10」が「9」の前にくるよく知られた問題です。

ファイルがすべて番号付きの名前で構成されていることがわかっている場合は、カスタムの並べ替えルーチンを変更して、名前を整数に変換し、適切に並べ替えることができます。

于 2012-03-13T10:58:34.403 に答える
0

これと同じ問題に遭遇しましたが、リストを自分でソートする代わりに、6 桁の「0」を埋め込んだキーを使用してファイル名を変更しました。

私のリストは次のようになります。

000001.jpg
000002.jpg
000003.jpg
...
000010.jpg

ただし、ファイル名を変更できない場合は、独自のソート ルーチンを実装してアルファ ソートを処理する必要があります。

于 2012-03-13T11:05:46.030 に答える
0

順序を修正するために少しlinqとregexはどうですか?

var orderedFileSysInfos = 
  new DirectoryInfo(directoryloc)
    .GetFileSystemInfos("*." + fileExtension)
    //regex below grabs the first bunch of consecutive digits in file name
    //you might want something different
    .Select(fsi => new{fsi, match = Regex.Match(fsi.Name, @"\d+")})
    //filter away names without digits
    .Where(x => x.match.Success)
    //parse the digits to int
    .Select(x => new {x.fsi, order = int.Parse(x.match.Value)})
    //use this value to perform ordering
    .OrderBy(x => x.order)
    //select original FileSystemInfo
    .Select(x => x.fsi)
    //.ToArray() //maybe?
于 2012-03-13T11:06:58.870 に答える
0

コードは正しく、期待どおりに機能しています。並べ替えは数値ではなくアルファベット順に実行されます。

たとえば、文字列「1」、「10」、「2」はアルファベット順です。代わりに、ファイル名が常に数字に「.png」を加えたものであることがわかっている場合は、数字でソートできます。たとえば、次のようなものです。

int compareFiles(FileSystemInfo a, FileSystemInfo b)         
{             
    // Given an input 10.png, parses the filename as integer to return 10
    int first = int.Parse(Path.GetFileNameWithoutExtension(a.Name));
    int second = int.Parse(Path.GetFileNameWithoutExtension(b.Name));

    // Performs the comparison on the integer part of the filename
    return first.CompareTo(second);
}
于 2012-03-13T10:56:56.737 に答える