Получить все файлы и положить их в список, указанный в переменной. C#. Help

enjoy1337

Client
Регистрация
14.12.2016
Сообщения
45
Благодарностей
2
Баллы
8
Друзья, всем привет! Стоит задача - уместить эти два действия в один кубик C# кода:

1. Получить путь всех файлов, содержащихся в папке, путь к которой указан в переменной "folder_name";
2. Поместить путь всех файлов в список с именем, указанным в переменной "list_name".

Возможно, для получения путей можно использовать этот код. Но как дальше?
C#:
Directory.GetFiles(project.Variables[@"folder_name"].Value);
Прошу помощи
 

RipWay

Client
Регистрация
21.11.2013
Сообщения
80
Благодарностей
36
Баллы
18
C#:
var listFiles = project.Lists["Список файлов"]; // имя списка в ZP
var dirFiles = Directory.GetFiles(project.Variables["folder_name"].Value); // Путь к папке с файлами
lock(SyncObjects.ListSyncer)
{
foreach(string file in dirFiles) {
    listFiles.Add(file);
}
}
 
Последнее редактирование:

enjoy1337

Client
Регистрация
14.12.2016
Сообщения
45
Благодарностей
2
Баллы
8
C#:
var listFiles = project.Lists["Список файлов"]; // имя списка в ZP
var dirFiles = Directory.GetFiles(project.Variables["folder_name"].Value); // Путь к папке с файлами

foreach(string file in dirFiles) {
    listFiles.Add(file);
}
А если имя списка постоянно меняется, то как сделать, чтобы его брало из переменной?

Опишу вкратце суть шаблона, может так будет более понятен контекст:
Шаблон берет из списка путь к папке с фото. Затем получает список всех фото в этой папке (3-7 штук), кладет их в список "photos" и затем берет строки с удалением, загружая фото на сайт. В один поток шаблон работает отлично. Но вот как это реализовать в многопотоке (20-30 потоков)? Ведь нужно, чтобы фото с разных папок не путались в списке "photos".

Первое, что пришло в голову:
1. Получить путь к папке с фото;
2. Сгенерировать рандомное имя нового txt файла;
3. Создать txt файл с этим именем;
4. Поместить пути к фото в список "photos";
5. Объединить элементы из этого списка в переменную "temp_for_photos";
6. Удалить все строки из списка "photos";
7. Положить пути к фото из переменной "temp_for_photos" во временно сгенерированный список (пункт 3);
8. Загрузить фото на сайт;
9.Удалить временный список.
Test Screenshot.png
И так для каждого потока. Таким образом шанс, что фото в списке "photos" пересекутся - небольшой, но он все же остается. Может можно как-то реализовать это более изящным способом, чтобы пересечений в потоках точно не было? Уверен, что ответ где-то на поверхности, но пока не нахожу его. Пример шаблона прилагаю
 

Вложения

  • 4,1 МБ Просмотры: 77

RipWay

Client
Регистрация
21.11.2013
Сообщения
80
Благодарностей
36
Баллы
18
Попробуй так. Тут с использованием временных списков не привязанных к файлам. Если я правильно понял, то проблем в многопотоке с ними не должно быть. Поправьте если не так. Сам проверить не могу сейчас.
C#:
List <string> tempListFiles = new List <string>(); // Временный список не привязаный к файлу
var dirFilesList = project.Lists["Список с путями"]; // Список с путями в ZP
string dirFiles;

// Берем строку из списка dirFilesList
lock (SyncObjects.ListSyncer)
{
    dirFiles = dirFilesList[0];
    dirFilesList.RemoveAt(0);
    if (string.IsNullOrEmpty(dirFiles)) return "Переменная пуста!";
}

var getDirFiles = Directory.GetFiles(dirFiles); // берем список файлов

// перебираем и добавляем в временный список или перебираем и выполняем действия с файлами
lock (SyncObjects.ListSyncer)
{
    foreach (string file in getDirFiles)
    {
        tempListFiles.Add(file);
        project.SendInfoToLog(file);
    }
}
 
  • Спасибо
Реакции: enjoy1337

enjoy1337

Client
Регистрация
14.12.2016
Сообщения
45
Благодарностей
2
Баллы
8
Попробуй так. Тут с использованием временных списков не привязанных к файлам. Если я правильно понял, то проблем в многопотоке с ними не должно быть. Поправьте если не так. Сам проверить не могу сейчас.
C#:
List <string> tempListFiles = new List <string>(); // Временный список не привязаный к файлу
var dirFilesList = project.Lists["Список с путями"]; // Список с путями в ZP
string dirFiles;

// Берем строку из списка dirFilesList
lock (SyncObjects.ListSyncer)
{
    dirFiles = dirFilesList[0];
    dirFilesList.RemoveAt(0);
    if (string.IsNullOrEmpty(dirFiles)) return "Переменная пуста!";
}

var getDirFiles = Directory.GetFiles(dirFiles); // берем список файлов

// перебираем и добавляем в временный список или перебираем и выполняем действия с файлами
lock (SyncObjects.ListSyncer)
{
    foreach (string file in getDirFiles)
    {
        tempListFiles.Add(file);
        project.SendInfoToLog(file);
    }
}
Пока сделал на костылях, так как нужно было быстрее решить задачу. Но код тоже разберу. Спасибо.
 

Alexmd

Client
Регистрация
10.12.2018
Сообщения
1 021
Благодарностей
1 385
Баллы
113
Вам всего-то нужно отвязать список photos от файла и удалить файл photos.txt за ненадобностью. Так каждый поток будет работать со своим личным списком photos.
Вот и весь код.
C#:
//соберем в список все директории с картинками
List<string> dirList = new List<string>(Directory.GetDirectories(string.Format(@"{0}\Photos\", project.Directory)).ToList());
if(dirList.Count == 0)
    throw new Exception("Нет директорий с картинками, укажите верный путь");
//чтобы брать случайную директорию при каждом обращении перемешиваем список
for(int i = 0; i < 7; i++)
    dirList.Shuffle();
//соберем в список все пути к файлам картинкам из случайной директории
project.Lists["photos"].AddRange(Directory.GetFiles(dirList.First()).ToList());

Так остается только возможность забора разными потоками одной и той же папки с фото. Для этого уже нужно городить отдельный блеклист с использованными каталогами и вот с ним уже работать в локе, но думаю, такой задачи все-таки не стоит, хотя это также не сложно.
C#:
lock(SyncObject){
    List<string> dirList = new List<string>(Directory.GetDirectories(string.Format(@"{0}\Photos\", project.Directory)).ToList().Where(x=>!project.Lists["folders"].Any(x.Contains)));
    if(dirList.Count == 0)
        throw new Exception("Использованы все директории или нет директорий с картинками, укажите верный путь");
    string imgDir = dirList.First();
    project.Lists["photos"].AddRange(Directory.GetFiles(imgDir).ToList());
    project.Lists["folders"].Add(imgDir);
}
Прикрепил переделанный шаблон для разбора.
 

Вложения

Последнее редактирование:
  • Спасибо
Реакции: enjoy1337

enjoy1337

Client
Регистрация
14.12.2016
Сообщения
45
Благодарностей
2
Баллы
8
Вам всего-то нужно отвязать список photos от файла и удалить файл photos.txt за ненадобностью. Так каждый поток будет работать со своим личным списком photos.
Вот и весь код.
C#:
//соберем в список все директории с картинками
List<string> dirList = new List<string>(Directory.GetDirectories(string.Format(@"{0}\Photos\", project.Directory)).ToList());
if(dirList.Count == 0)
    throw new Exception("Нет директорий с картинками, укажите верный путь");
//чтобы брать случайную директорию при каждом обращении перемешиваем список
for(int i = 0; i < 7; i++)
    dirList.Shuffle();
//соберем в список все пути к файлам картинкам из случайной директории
project.Lists["photos"].AddRange(Directory.GetFiles(dirList.First()).ToList());

Так остается только возможность забора разными потоками одной и той же папки с фото. Для этого уже нужно городить отдельный блеклист с использованными каталогами и вот с ним уже работать в локе, но думаю, такой задачи все-таки не стоит, хотя это также не сложно.
C#:
lock(SyncObject){
    List<string> dirList = new List<string>(Directory.GetDirectories(string.Format(@"{0}\Photos\", project.Directory)).ToList().Where(x=>!project.Lists["folders"].Any(x.Contains)));
    if(dirList.Count == 0)
        throw new Exception("Использованы все директории или нет директорий с картинками, укажите верный путь");
    string imgDir = dirList.First();
    project.Lists["photos"].AddRange(Directory.GetFiles(imgDir).ToList());
    project.Lists["folders"].Add(imgDir);
}
Прикрепил переделанный шаблон для разбора.
Отвязка списка от файла действительно решила вопрос. Как часто и бывает - ищешь решение в дебрях, а оно на поверхности. Огромное вам спасибо за такой развернутый ответ и за шаблон с примером!
 
  • Спасибо
Реакции: Alexmd

Harvertalex

Client
Регистрация
21.11.2018
Сообщения
34
Благодарностей
2
Баллы
8
Попробуй так. Тут с использованием временных списков не привязанных к файлам. Если я правильно понял, то проблем в многопотоке с ними не должно быть. Поправьте если не так. Сам проверить не могу сейчас.
C#:
List <string> tempListFiles = new List <string>(); // Временный список не привязаный к файлу
var dirFilesList = project.Lists["Список с путями"]; // Список с путями в ZP
string dirFiles;

// Берем строку из списка dirFilesList
lock (SyncObjects.ListSyncer)
{
    dirFiles = dirFilesList[0];
    dirFilesList.RemoveAt(0);
    if (string.IsNullOrEmpty(dirFiles)) return "Переменная пуста!";
}

var getDirFiles = Directory.GetFiles(dirFiles); // берем список файлов

// перебираем и добавляем в временный список или перебираем и выполняем действия с файлами
lock (SyncObjects.ListSyncer)
{
    foreach (string file in getDirFiles)
    {
        tempListFiles.Add(file);
        project.SendInfoToLog(file);
    }
}
А как забрать не весь список файлов, а только рандомное количество названий после переместить именно эту пачку файлов в другую директорию?
 

Harvertalex

Client
Регистрация
21.11.2018
Сообщения
34
Благодарностей
2
Баллы
8
В общем вот так)

C#:
// задаем общую папку для виртуальной машины
string vmDir = project.Directory + @"\resourses\temp\" + project.Variables["name_vd"].Value;
    if (!Directory.Exists(vmDir)) Directory.CreateDirectory(vmDir);
    
List <string> tempListFiles = new List <string>(); // Временный список не привязаный к файлу
string dir = project.Directory + @"\resourses\temp\";
string avatarImg = project.Directory + @"\resourses\img\avatars\";
string avatarUsed = project.Directory + @"\resourses\img\avatarsUsed\";
string img = project.Directory + @"\resourses\img\img\";
string imgUsed = project.Directory + @"\resourses\img\imgUsed\";
string avatar = Path.Combine(vmDir, "avatar");
if (!Directory.Exists(avatar)) Directory.CreateDirectory(avatar);
string content = Path.Combine(vmDir, "content");
if (!Directory.Exists(content)) Directory.CreateDirectory(content);

//Перемещаем пути к файлам в список аватарок
var dirFiles = Directory.GetFiles(avatarImg); // Путь к папке с файлами
lock (SyncObjects.ListSyncer)
{
    tempListFiles.Clear();
    foreach (string file in dirFiles)
    {
        tempListFiles.Add(file);
    }
}
//работаем с файлами
//аватарки
lock (SyncObjects.ListSyncer)
{
    for (int i = 1; i < 10; i++)
    {
        //Получаем рандомный путь к файлу
        int random = new Random().Next(tempListFiles.Count);
        string random_File = tempListFiles[random];
        string new_path = Path.Combine(avatar, Path.GetFileName(random_File));
        File.Copy(random_File, new_path, true);
        string used_path = Path.Combine(avatarUsed, Path.GetFileName(random_File));
        File.Move(random_File, used_path);
        tempListFiles.Remove(random_File);
        }
    }
//Перемещаем пути к файлам в список контента
var dirFiles2 = Directory.GetFiles(img); // Путь к папке с файлами
lock (SyncObjects.ListSyncer)
{
    tempListFiles.Clear();
    foreach (string file in dirFiles2)
    {
        tempListFiles.Add(file);
    }
    
}
//работаем с файлами
//контент
lock (SyncObjects.ListSyncer)
{
    for (int i = 1; i < 30; i++)
    {
        //Получаем рандомный путь к файлу
        int random = new Random().Next(tempListFiles.Count);
        string random_File = tempListFiles[random];
        string new_path = Path.Combine(content, Path.GetFileName(random_File));
        File.Copy(random_File, new_path, true);
        string used_path = Path.Combine(imgUsed, Path.GetFileName(random_File));
        File.Move(random_File, used_path);
        tempListFiles.Remove(random_File);
        }
    }
 

Mikhail B.

Moderator
Регистрация
23.12.2014
Сообщения
14 328
Благодарностей
5 431
Баллы
113
C#:
var listFiles = project.Lists["Список файлов"]; // имя списка в ZP
var dirFiles = Directory.GetFiles(project.Variables["folder_name"].Value); // Путь к папке с файлами
lock(SyncObjects.ListSyncer)
{
foreach(string file in dirFiles) {
    listFiles.Add(file);
}
}
В многопоток бы еще его оптимизировать, что бы перед локом проверял список на наличие в нем строк. И если есть, значит другой поток успел взять и обработать список. Или надо в локе проверять список на наличие строк?
 

Кто просматривает тему: (Всего: 1, Пользователи: 0, Гости: 1)