2012-03-13 12 views
2

私はたぶん約500時間を費やしました。これを読んで、MSDNのドキュメントを読むと、私は望む方法で動作することを拒否します。名前でFileSystemInfo []をソート

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

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); 
} 
+0

ファイル名のパターンを変更することは可能でしょうか?例えば。 1.pngから01.pngへ? –

+1

これを試してみてくださいhttp://stackoverflow.com/questions/1601834/c-implementation-of-or-alternative-to-strcmplogicalw-in-shlwapi-dll、 'StrCmpLogicalW'はソートの「魔法」を行うWindows APIですファイル名を「論理的」な形で表します。 – xanatos

答えて

3

これは、特にファイルの問題ではない - それは辞書順に比較されている名前の問題です。

拡張子を付けずに名前を取得し、それを整数として解析し、そのように2つの名前を比較しようとしているように思えます。失敗した場合は辞書順に戻すことができます。

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

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); 
} 
3

は、あなたは彼らがでソートしたい(私は仮定している)にも関わらず、文字列として名を比較しています。

あなたはファイルがすべてのことがわかっている場合は10の最初の文字は、(1)9.

の最初の文字より小さいので、これは「10」は「9」の前に来て、よく知られた問題です名前付きの名前で構成されている場合は、カスタムソートルーチンを変更して、名前を整数に変換して適切に並べ替えることができます。

0

私はこの同じ問題に遭遇しましたが、自分でリストをソートする代わりに、6桁の「0」のパディングキーを使用してファイル名を変更しました。

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

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

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

0

linqと正規表現を少し修正するのはどうですか?

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? 
関連する問題