在分隔符C#之前匹配具有用户名的文件

时间:2011-07-29 11:47:29

标签: c# asp.net-mvc

大家好奇,如果有人可以提供帮助,因为我有点头疼。我有以下代码,它将根据用户名从特定目录中获取多个文件。我只想返回那些文件;以.xls,.xlsx或.pdf格式;具有文件名中包含的用户名;用户名的第一个字母等于文件名的第一个字母;文件名与分隔符前的用户名完全匹配。

最后一点是我在努力的地方;我目前将返回以下文件的代码:v_ashby-smith_2010_testtesttesttest.xlsx,v_ashby-smith_2011_testtesttesttest.xls,v_ashby-smithson_2010_testtesttesttest.xls

但是我需要它不返回文件v_ashby-smithson_2010_testtesttesttest.xls,因为这个文件与用户名(v_ashby-smith)不完全相同。我想到有人在分隔符之前获取与用户名匹配的文件,例如XX。有什么想法吗?

public FileInfo[] ReadFiles(String userName)
{
  DirectoryInfo bonusInfoDirectory = null;
  FileInfo[] files = null;

  try
  {
    string userNameFirstLetter = userName.First().ToString();
    string directoryPath = System.Configuration.ConfigurationManager.AppSettings["DirectoryPath"];
    bonusInfoDirectory = new DirectoryInfo(directoryPath);
    files = bonusInfoDirectory.GetFiles().Where(f => f.Extension == ".xls" ||
      f.Extension == ".xlsx" || f.Extension == ".pdf")
      .Where(f => f.Name.Contains(userName))
      .Where(f => f.Name.First().ToString() == userNameFirstLetter)
      .OrderByDescending(f => f.Name).ToArray();
   }
   catch (DirectoryNotFoundException exp)
   {
     throw new DirectoryNotFoundException("Directory not found " + exp.Message);
   }
   catch (IOException exp)
   {
     throw new IOException("The Process cannot access the file because it is in use by
     another process " + exp.Message);
    }
    return files;
}

3 个答案:

答案 0 :(得分:1)

根据您的文件名 -

  string seperator = "_";
  string filespec = String.Format("{0}{1}*", userName, seperator );
  files = bonusInfoDirectory.GetFiles(filespec)
     .Where(f => f.Extension == ".xls" ||
                 f.Extension == ".xlsx" || 
                 f.Extension == ".pdf")
  .OrderByDescending(f => f.Name).ToArray();

根据您的描述

  string filespec = String.Format("{0}*", userNameFileLetter);
  string seperator = "_";
  string pattern = String.Format("{0}{1}", userName, seperator );
  files = bonusInfoDirectory.GetFiles(filespec)
     .Where(f => f.Extension == ".xls" ||
                f.Extension == ".xlsx" || 
                f.Extension == ".pdf")
    .Where(f->f.Name.Contains(pattern))
    .OrderByDescending(f => f.Name).ToArray();

但是请注意,如果你有一个用户v_ashby-smith而另一个叫vv_ashby-smith,那么前者也可以获得后者的文件。

答案 1 :(得分:0)

一种方法是使用正则表达式,替换:

.Where(f => f.Name.Contains(userName))

.Where(f=>Regex.IsMatch(
         f.Name,
         String.Format(
               @"(?:\b|\d){0}(?:\b|\d)",
               Regex.Escape(userName)
         )
      )

(包括System.Text.RegularExpressions)

如果文件名包含紧跟在分词符号前面的用户名(符号,空格,字符串开头,字符串结尾)或数字,

IsMatch将返回true。

答案 2 :(得分:0)

如果您是从头开始设计,没有遗留约束,我会使用唯一标识符而不是文件名的用户名,因为您必须在当前实现下获得冲突。这也可以简化您的代码,因为您可以使用分隔符为id创建特定的边界。如果您需要让文件具有人类可读性,那么您也可以在id分隔符之外附加用户名。

想想这样的事情:

1923_V_Ashby_Smith.xml,其中1923 = user_id for user。

执行.Split('_'),您的用户ID为[0]

这是因为user_id被设计为唯一的,如果你没有一种识别用户的独特方式,那么在考虑实现之前你需要备份并考虑更多的设计。