2016-02-25 6 views
1

У меня есть таблица MySQL со списком имени файла. Я хотел бы получить список всех файлов в каталоге, только если их имена отсутствуют в таблице.Получить все файлы не существует int a datatable

я могу поместить список файлов в базы данных в Datatable и написать что-то вроде:

string[] files = Directory.GetFiles(directory); 
foreach (Datarow row in dataTable.Rows) 
    for (int i=0; i<files.Length; i++) 
     if (row[0].equals(files[i]) { 
      files[i].delete(); 
      break; 
     } 

Верхний код является лишь псевдо-пример. Не могу ли я напрямую использовать Directory.GetFiles (каталог), указав фильтр, чтобы не писать все итерации?

+1

Нет, нет способа использовать его, но вы можете уменьшить свой код, используя * if (files.IndexOf (строка [0] .ToString()) <0) ... * – Gusman

+0

например, если вы хотите получить список файлов, которые заканчиваются на '.txt', вы можете сделать следующее: ' var files = Directory.GetFiles (AppDomain.CurrentDomain.BaseDirectory) .Where (name => name.EndsWith (". txt")) ToList (); 'поэтому, если бы вы могли это сделать .. почему вы не могли заменить метод' .EndsWith' '.Contains' и получить все файлы, содержащие конкретное строковое значение ..? – MethodMan

ответ

2

пожалуйста, найти фрагмент кода ниже

решил сделать это в шагах - иметь более поддерживаемому коду

void Main() 
{ 
    // given a list of files from db 
    DataTable dataTable = new DataTable("x"); 
    dataTable.Columns.Add("file", typeof(string)); 
    dataTable.Rows.Add("HaxLogs.txt");dataTable.Rows.Add("swapfile.sys");dataTable.Rows.Add("four.txt"); 
    var directory = "c:\\"; 
    var directoryFilesWithPaths = Directory.GetFiles(directory) 
      .Select(x=> new FileEntry { Path = x, FileName = Path.GetFileName(x)}); 

      var directoryFiles = directoryFilesWithPaths.Select(x => x.FileName).ToList(); 
      var filesList = (from DataRow dr in dataTable.Rows 
          select dr[0].ToString()).ToList(); 

      var filesToProcess = directoryFiles.Except(filesList); 
     foreach (var file in filesToProcess) 
     { 
      // process file here 

      Console.WriteLine(file); 
     } 

}

+0

Привет, есть проблема, о которой я не сказал: в datatable есть имена файлов без путей, но с ** String [] files = Directory.GetFiles (tDirectory.Text, "*. *", System. IO.SearchOption.AllDirectories); ** Я получаю также пути. – helloimyourmind

+0

Я пробовал с ** var filesToProcess = files.Select (Path.GetFileName) .Except (filesList); ** но не работает. – helloimyourmind

+0

есть ** patch ** :-) – profesor79

1

Решение LINQ является:

Directory.GetFiles(directory) 
     .Where(x => !dataTable.AsEnumerable() 
       .Select(row => row[0].ToString()) 
       .Contains(x)) 
+0

Я пробовал ваше решение, но результатом является список всех файлов в каталоге, а не фильтрация. – helloimyourmind

+0

Одним из возможных объяснений является то, что таблица содержит совершенно разные данные, чем результаты Directory.GetFiles. Например, таблица может иметь имена файлов, но GetFiles возвращает полные пути. – JimG

+0

Да, это так, как вы сказали. Мне нужно выбрать весь файл, заканчивающийся строкой базы данных. – helloimyourmind

1

Это это мое решение:

ArrayList files = new ArrayList(); 
files.AddRange(Directory.GetFiles(directory, "*.*", SearchOption.AllDirectories)); 
     foreach (DataRow row in tableFiles.Rows) 
     { 
      for (int i = 0; i < files.Count; i++) 
       if (files[i].ToString().EndsWith(row[0].ToString())) 
       { 
        files.RemoveAt(i); 
        break; 
       } 
     } 

Я также попытался с Path.GetFileName (файлы [я] .ToString() для того, чтобы использовать Равно вместо EndsWith, но с 8500 файлами, это решение занимает 2 секунды, с GetFileName 10 секунд.

+0

выглядит красиво - но цикл может быть дорогим – profesor79

+0

Но таким образом у меня все еще есть полное имя файла, как вы думаете, можем ли мы улучшить это решение? – helloimyourmind

+0

Это правда - эта информация о количестве файлов должна быть в вашем вопросе. – profesor79

 Смежные вопросы

  • Нет связанных вопросов^_^