【问题标题】:parsing error when getting the file depends on file creation time获取文件时解析错误取决于文件创建时间
【发布时间】:2011-10-13 13:09:05
【问题描述】:

我有这样的路径..."C:\restore\restoredb\"

在那个路径中我有这样的文件..

 backup-2011-10-12T17-16-51.zip
 backup-2011-10-11T13-24-45.zip

我有一个表格,在那个表格中我有一个列表框和组合框(cbrestore)我有这样的组合框项目......月,3个月,6个月,年......

我想要的是,如果我选择组合框项目(月份),我想使用文件创建时间显示在这些日期(2011 年 12 月 10 日至 2011 年 12 月 9 日)之间存储在该文件夹中的文件名即,像这样..File.Getcreationtime..

如果我选择组合框项目(3 个月),我想在这些日期(2011 年 12 月 10 日至 2011 年 12 月 7 日)之间显示存储在该文件夹中的文件名..在列表框中..

为此,我已经尝试过这样......

 List<String> t = Directory.GetFiles(@"C:\restore\restoredb\").ToList();
List<String> y = new List<string>();
List<String> u = new List<string>();



foreach (var zzz in t)
{
    y.Add(Path.GetFileName(zzz));
}


if (comboBox1.Text == "Month")
{
    u =
   (from String s in y where ((DateTime.Now.Month - (DateTime.Parse(File.GetCreationTime(s)) < 1) && (DateTime.Now.Year - DateTime.Parse(s.Substring(8, 10)).Year == 0) select s).
       ToList();
}

但我说错了

“system.datatime.parse(string) 的最佳重载方法匹配有一些无效参数.... 像这样我在这一行出现错误(DateTime.Parse(File.GetCreationTime(s))

有没有人能帮忙解决这个问题..... 非常感谢提前...

【问题讨论】:

    标签: c# .net winforms file


    【解决方案1】:

    我似乎需要对您一直使用的代码进行一些额外的更改。下面是组合框的新代码:

        private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
    
            List<Files> yourNewList = Files.GetFiles();
    
            List<String> u = new List<string>();
    
    
            if (comboBox1.Text == "Month")
            {
                u = (from Files f in yourNewList
                     where DateTime.Parse(f.CreationDate.Substring(0, 10)) > DateTime.Now.AddMonths(-1)
                     select f.FileName).ToList();
            }
            else if (comboBox1.Text == "3 Month")
            {
                u = (from Files f in yourNewList
                     where DateTime.Parse(f.CreationDate.Substring(0, 10)) > DateTime.Now.AddMonths(-3)
                     select f.FileName).ToList();
            }
            else if (comboBox1.Text == "1 Year")
            {
                u = (from Files f in yourNewList
                     where DateTime.Parse(f.CreationDate.Substring(0, 10)) > DateTime.Now.AddMonths(-12)
                     select f.FileName).ToList();
            }
    
            listBox1.DataSource = u;
        }
    

    这是使用我创建的一个类,它存储具有文件名和创建日期/时间的文件对象:

    您可以看到其中许多共享相同的创建日期(4 月的那个是我发现使用的旧 zip 文件),这是我昨天制作这些文件的目的,以帮助您。我不能欺骗 windows 从文件中提取的创建日期。

    该类本身使用此代码:

    public class Files
    {
        public string FileName { get; private set; }
        public string CreationDate { get; private set; }
    
        public List<Files> theseFiles
        {
            get
            {
                return GetFiles();
            }
        }
    
        public Files(string fileName, string creationDate)
        {
            this.FileName = fileName;
            this.CreationDate = creationDate;
        }
    
    
        public static List<Files> GetFiles()
        {
            //Gets full file names
            List<String> t = Directory.GetFiles(@"C:\Users\justin\Desktop\New folder (2)\").ToList();
            List<String> t2 = new List<string>();
            foreach (var yyy in t)
            {
                t2.Add(Path.GetFileName(yyy));
            }
    
            //Creation Dates
    
            var dirInfo = new DirectoryInfo(@"C:\Users\justin\Desktop\New folder (2)");
            List<String> fct = (from f in dirInfo.GetFiles("*", SearchOption.TopDirectoryOnly)
    
                                select f.CreationTime.Date.ToShortDateString()).ToList();
    
            List<String> y = new List<string>();
            foreach (var zzz in fct)
            {
                y.Add(zzz);
            }
    
            //Creats a collection of the file objects for you to use
            List<Files> gg = new List<Files>();
    
    
            for (int x = 0; x < t2.Count(); x++)
            {
                //Adjusts the dates to add 0's in the off chance that they aren't there
                if(DateTime.Parse(y[x]).Month < 10)
                {
                    y[x] = "0" + y[x];
                }
                if(DateTime.Parse(y[x]).Day < 10)
                {
                    y[x] = y[x].Insert(3, "0");
                }
                Files thefile = new Files(t2[x].ToString(), y[x].ToString());
                gg.Add(thefile);
    
            }
    
            return gg;
    
        }
    
        public override string ToString()
        {
            return string.Format("{0} , {1}", FileName, this.CreationDate);
        }
    }
    

    您需要做的就是在您的项目中添加一个名为 Files 的类,并将该代码粘贴到其中。 (请确保更改类中的目录,因为它当前指向我的文件夹)

    然后将代码从上到下粘贴到表单的 .cs 页面中的 SelectedIndexChanged 方法中。

    请记住,if 条件基于创建时间,这就是为什么您会看到不属于那里的文件名(例如日期为 9/11/2010 的文件名)。 (再一次,我昨天创建了所有这些文件,日期为 2011 年 4 月 4 日的文件是我从 4 月找到的较旧的 zip 文件,并将其放在文件夹中进行测试。

    在两张图片中,您会看到添加了 1 个文件,根据您看到返回 gg 集合的 SS 顶部,这是有道理的。在那个 SS 中,唯一不属于昨天创建日期的文件是 2011 年 4 月 7 日的那个,这就是为什么当我选择“1 年”时它会出现。

    【讨论】:

      【解决方案2】:

      DateTime.Parse(argument) 参数类型是 StringFile.GetCreationTime(argument) 返回 DateTime 所以您试图将 DateTime 值作为字符串类型参数传递

      所以只需像下面这样改变条件:

      where ((DateTime.Now.Month - File.GetCreationTime(s).Month) < 1) 
             && 
             (DateTime.Now.Year - DateTime.Parse(s.Substring(8, 10)).Year == 0)
      

      编辑:

      要检查文件创建月份是否是以前的,我建议使用以下内容:

      DateTime now = DateTime.Now;
      DateTime fileCreationTime = File.GetCreationTime(s);
      
      bool isPreviousMonth = (DateTime.Now.Month == 1 ? 12 : DateTime.Now.Month - 1) 
                             ==   fileCreationTime.Month;
      

      EDIT2:

      string path = @"C:\restore\restoredb\";            
      IList<String> allFiles = Directory.GetFiles(path).ToList();
      IList<String> fileNames = new List<string>();
      IList<String> filesCreatedInThisMonth = new List<string>();
      fileNames = allFiles.Select(filePath => Path.GetFileName(filePath)).ToList();
      
      if (comboBox1.Text == "Month")
      {
          filesCreatedInThisMonth =
              allFiles.Where(fileName =>
                      {
                          return File.GetCreationTime(fileName).Month
                                  == (DateTime.Now.Month == 1 ? 12 : DateTime.Now.Month - 1)
                                  &&
                                  (DateTime.Now.Year == DateTime.Parse(fileName.Substring(8, 10)).Year);
                      }).ToList();
       }
      

      EDIT3:

      IList<String> filesCreatedInThisMonth = new List<string>();
      IList<String> fileNames = new List<string>();
      // Key - Full file path
      // Value - File creation DateTime extracted from the file name
      IDictionary<string, DateTime> filePathToDateMap =
          Directory.GetFiles(path).ToDictionary(
              filePath => filePath,
              filePath => DateTime.Parse(Path.GetFileName(filePath).Substring(8, 10)));
      
      // mapEntry - KeyValuePair
      // Key - filePath, Value - creation DateTime extracted from the file name
      filesCreatedInThisMonth =
              filePathToDateMap.Where(mapEntry =>
                      {
                          return File.GetCreationTime(mapEntry.Key).Month
                                  == (DateTime.Now.Month == 1 ? 12 : DateTime.Now.Month - 1)
                                  &&
                                  (DateTime.Now.Year == mapEntry.Value.Year);
                      }).Select(entry => entry.Key)
                      .ToList();           
      

      或者文件创建时间不是从文件名而是从真实创建时间检索的情况:

      IDictionary<string, DateTime> filePathToDateMap =
      Directory.GetFiles(path).ToDictionary(
          filePath => filePath,
          filePath => File.GetCreationTime(filePath));
      

      【讨论】:

      • sll,我试过这个 File.GetCreationTime(s).Month 但没有得到上个月创建的文件名.....
      • 我怎样才能得到当月的所有文件......如果我检查上述条件......你能详细说明......
      • 如何在 getfiles = 中实现这个条件? //bool isLess = now.Month != fileCreationTime.Month && now.Subtract(fileCreationTime).TotalDays > 30;
      • @errorcode105 :我已经更新了isPreviousMonth 条件,请参阅答案编辑部分
      • 非常感谢,但我不想在这个地方包含文件名,fileName.Substring(8, 10)).Year 有没有其他方法可以做到这一点.. 请你解释一下..
      【解决方案3】:

      你的错误在这里:

      (DateTime.Parse(File.GetCreationTime(s))
      

      File.GetCreationTime(s) 返回 DateTime,而不是字符串(DateTime.Parse 期望的类型...)

      您应该在不带 DateTime.Parse 的情况下替换 File.GetCreationTime(s) 的先前代码

      【讨论】:

        【解决方案4】:

        在您的示例代码中,您通过File.GetCreationTime 使用文件创建时间进行月份比较,但您使用的似乎是嵌入在文件名中的文件创建时间(从索引 7 开始)来检查那一年。旁注:Substring(int, int) 使用从零开始的索引,因此您的代码应使用 Substring(7, 10)Substring(8, 10) 将被关闭。

        如果使用嵌入在文件名中的日期是可以接受的(相对于操作系统的时间戳),那么这将获得上个月内创建的所有文件名:

        string path = @"C:\restore\restoredb\";
        IList<String> allFiles = Directory.GetFiles(path).ToList();
        IList<String> fileNames = allFiles.Select(filePath => Path.GetFileName(filePath)).ToList();     
        
        List<String> filesCreatedInLastMonth = new List<string>();
        DateTime endDate = DateTime.Now;
        DateTime beginDate = endDate.AddMonths(-1);
        foreach (var fileName in fileNames)
        {
            DateTime dt = DateTime.Parse(fileName.Substring(7, 10));
            if ((beginDate <= dt) && (dt <= endDate))
            {
                filesCreatedInLastMonth.Add(fileName);
            }
        }
        

        这可以很容易地针对其他日期范围进行修改。

        要改用文件创建时间,请将foreach 块内的第一行更改为:

        DateTime dt = File.GetCreationTime(path + fileName);
        

        【讨论】:

        • 如果问题是基于文件本身的标题,这有效,但不能解决他使用 File.Getcreationtime 的问题。还有 endDate.AddMonth(-1);应该是 endDate.AddMonths(-1);并且子字符串调用应该来自 (8,10) 而不是 (7,10)。
        • @KreepN - 谢谢,我修复了AddMonths。至于使用Substring,文件名的格式为:“backup-2011-10-12T17-16-51.zip”。日期从第 8 个字符开始,但Substring 使用从零开始的索引,因此日期字符串的第一个字符位于索引 7。
        • @Mike - 我的错,我使用的是他的旧文件命名模式(恢复与备份),这是 1 个字母的差异:P。好眼力。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-10-25
        • 2013-01-20
        • 1970-01-01
        • 2011-10-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多