【问题标题】:Sort files in ascending order按升序对文件进行排序
【发布时间】:2013-03-07 07:56:18
【问题描述】:

我有将 pdf 转换为 tif 图像文件的项目。并且输出文件在表格中编号。文件 1,文件 2,文件 3.......文件 20。 当我执行下面的代码来获取文件时,它们排列在列表中,如下所示,这是不正确的。任何想法如何解决这个问题?

FileInfo[] finfos = di.GetFiles("*.*");

finfos[0]=file1

finfos[1]=file10

finfos[2]=file11

finfos[3]=file12

....
...................

finfos[4]=file19

finfos[5]=file2

finfos[6]=file20

finfos[7]=file3

finfos[7]=file4

【问题讨论】:

  • 他们会一直被称为file{number} 吗?或者这只是一个例子,实际上它们可能是my pics {number}birthday {number} - Jim
  • 搜索 - 关于如何为此类排序制作比较器有几个类似的问题。此外,如果您只是将它们命名为“file0001”,那会容易得多。
  • 这个stackoverflow.com/questions/12373041/… 非常接近你想要的。
  • 是否有可能某些文件的文件名中没有数字?
  • DllImport StrCmpLogicalW 从 shlwapi.dll 并使用它对 finfos 数组进行排序。

标签: c# winforms list fileinfo


【解决方案1】:

如果所有文件都命名为mypic<number>.tif,并且目录中没有文件名称格式不同,请尝试以下操作:

        FileInfo[] orderedFI = finfos
            .OrderBy(fi => 
                // This will convert string representation of a number into actual integer
                int.Parse(
                    // this will extract the number from the filename
                    Regex.Match(Path.GetFileNameWithoutExtension(fi.Name), @"(\d+)").Groups[1].Value
                    ))
            .ToArray();

【讨论】:

  • 我也试过了,但我得到了一个例外。但这对我来说可能并不好,因为我正在制作一个漫画阅读器,也可以按照自然顺序阅读图像文件。我想我只是在某个地方遗漏了一些非常重要的东西。例如,现有的用 C# 编写的漫画阅读器如何能够简单地做到这一点?
  • 我看到它只有在目录中没有其他文件时才有效。由于我希望我的程序将所有可读的图像文件收集在一个列表中,而不管名称如何,有没有办法从最后 3 个扩展文件开始拆分文件作为参考并应用你的方法?
  • 如果需要对不同格式的文件名混合进行排序,例如11ab.tif1ab.tif2ab.tifabc.tifab1.tifab11.tifab2.tif、你想如何对它们进行排序?
  • +1。 @electricalbah,过滤掉要显示的文件真的取决于您。排序前的某种过滤(如 .Where(fn => fn.Contains("someprefix")) )可以轻松做到这一点。
【解决方案2】:

前导零可能是您的解决方案。如果您控制生成文件的代码,则从您的描述中不清楚。 如果不是,您可以使用一种方法来匹配 file1,... file9(即正则表达式或文件名长度)并重命名它们。 如果您控制代码,则使用格式化程序将数字转换为带前导零的字符串(即 2 位数字 {0:00})。

编辑:

使用以下草稿样本获得指导:

假设您在执行目录中有以下文件:file1.txt、file2.txt、file10.txt 和 file20.txt

foreach (string fn in System.IO.Directory.GetFiles(".", "file*.*"))
  if (System.Text.RegularExpressions.Regex.IsMatch(fn, @"file\d.txt"))
    System.IO.File.Move(fn, fn.Replace("file", "file0"));

以上代码会将file1.txt重命名为file01.txt,将file2.txt重命名为file02.txt。

【讨论】:

  • 我无法控制生成图像文件的文件,除此之外我还想读取具有相同编号的漫画图像文件。我认为您的第二个选项可能会有所帮助。但我是初学者,你能给我一些样本吗?
【解决方案3】:

如果它们是按创建日期排序的。

这是使用 List 解决问题的方法

class Program
{
    private static int CompareWithNumbers(FileInfo x, FileInfo y)
    {
        if (x == null)
        {
            if (y == null)
            {
                // If x is null and y is null, they're 
                // equal.  
                return 0;
            }
            else
            {
                // If x is null and y is not null, y 
                // is greater.  
                return -1;
            }
        }
        else
        {
            // If x is not null... 
            // 
            if (y == null)
            // ...and y is null, x is greater.
            {
                return 1;
            }
            else
            {

                int retval = x.CreationTime<y.CreationTime?-1:1;
                return retval;          

            }
        }
    }
    static void Main(string[] args)
    {
        DirectoryInfo di = new DirectoryInfo("d:\\temp");
        List<FileInfo> finfos = new List<FileInfo>();
        finfos.AddRange(di.GetFiles("*"));
        finfos.Sort(CompareWithNumbers);

        //you can do what ever you want
    }
}

【讨论】:

  • 请提供证明该声明的链接。 (显然不是Directory.GetFiles - “返回文件名的顺序不能保证”)
  • @AlexeiLevenkov 你能把一些文件从 1 重命名为 12 吗?获取 file1 后,file10 将是下一个而不是 file2
  • 我用 List 添加了一个解决方案
  • 我的第一条评论可能是错误的,因为我将“做排序”读作“它们已排序”,而它可能应该被读作“比你可以排序”。希望在某些时候删除此内容并首先发表评论。
猜你喜欢
  • 1970-01-01
  • 2013-05-29
  • 1970-01-01
  • 2013-05-30
  • 2019-07-23
  • 1970-01-01
  • 1970-01-01
  • 2023-04-11
  • 2012-11-29
相关资源
最近更新 更多