开发者

Match files that have username before delimiter C#

开发者 https://www.devze.com 2023-03-23 23:51 出处:网络
Hi all wonder if someone can help, as i\'m scratching my head a bit. I\'ve got the following code, which will go and get开发者_如何学Python multiple files from a specific directory based on the userna

Hi all wonder if someone can help, as i'm scratching my head a bit. I've got the following code, which will go and get开发者_如何学Python multiple files from a specific directory based on the username. I only want to return files that; are in .xls, .xlsx or .pdf format; that have the username contained in the filename; that the first letter of the username is equal to the first letter of the filename; that the filename matches exactly the username before a delimiter.

The final bit is where i am struggling; the code which i have currently will return to following files: v_ashby-smith_2010_testtesttesttest.xlsx, v_ashby-smith_2011_testtesttesttest.xls, v_ashby-smithson_2010_testtesttesttest.xls

However i need it not to return the file v_ashby-smithson_2010_testtesttesttest.xls as this file is not exactly the same as the username (v_ashby-smith). I thought about someone getting the files that match the username before a delimiter, for example XX. Any ideas?

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


Based on your filenames -

  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();

Based on your description

  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();

But note, if you have a user v_ashby-smith and another called vv_ashby-smith , then the former may also get files for the latter.


One approach would be to use a regular expression, replacing:

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

with

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

(Include System.Text.RegularExpressions)

IsMatch will return true if the filename includes the username immediately preceded or followed by a word break (symbol, space, start of string, end of string) or number.


If you are designing this from scratch, without a legacy constraint, I would use a Unique Identifier instead of a users name for the filename, as you are bound to get collisions under the current implementation. That would also simplify your code, as you could create specific boundaries for the id using delimiters. If you need to have the files somewhat human readable, you could append the users name in there as well, outside of your id delimiter.

Think something like this :

1923_V_Ashby_Smith.xml where 1923 = user_id for user.

do a .Split('_') and you have your user id at [0]

This works because user_id's are designed to be unique, if you don't have a unique way to identify a user, then you need to back up and think about the design a bit more before considering implementing this.

0

精彩评论

暂无评论...
验证码 换一张
取 消