Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.92/13: Рейтинг темы: голосов - 13, средняя оценка - 4.92
 Аватар для VLK
198 / 170 / 19
Регистрация: 05.05.2013
Сообщений: 1,236

Получение и возвращение неопределенной коллекции

27.08.2015, 16:17. Показов 2497. Ответов 13
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Для начала, если кто то придумает название более информативное буду благодарен.

Мне надо два метода, они оба будут работать с файлами txt, первый будет считывать и возвращать все содержимое файла в виде коллекции (каждая строка - новый элемент), второй принимать коллекцию и записывать ее в файл (не дописывать в конец а перезаписывать если файл существует)

Загвоздка в том что коллекция может быть List или HashSet или SortedSet или Queue или Stack, если во все перечисленное нельзя впихнуть Queue или Stack, то я от них откажусь.

на данный момент это выглядит так (но тут все через List работает, мне надо уйти от этого):
Кликните здесь для просмотра всего текста
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
 
public static class FileManager2
{
    public static List<string> GetAllFileLines(string FilePath, bool IgnoreEmptyString)
    {
        List<string> list = new List<string>();
        try
        {
            StreamReader file = new StreamReader(FilePath);
            string temp;
 
            while ((temp = file.ReadLine()) != null)
            {
                if (IgnoreEmptyString && temp != "") list.Add(temp);
                else list.Add(temp);
            }
 
            file.Close();
            return list;
        }
        catch
        {
            return list;
        }
    }
 
    public static bool CreateAndAddList(string FilePath, List<string> list)
    {
        if (File.Exists(FilePath) == false)
        {
            string dir = Path.GetDirectoryName(FilePath);
 
            if (string.IsNullOrEmpty(dir) == false) Directory.CreateDirectory(dir);
 
            File.CreateText(FilePath).Close();
        }
 
        try
        {
            StreamWriter file = new StreamWriter(FilePath);
            foreach (string temp in list) file.WriteLine(temp);
            file.Close();
 
            return true;
        }
        catch
        {
            return false;
        }
    }
}


Первый вопрос, можно ли как-нибудь что бы метод работал со всеми 5 коллекциями?

Второй, как лучше это сделать? Как вариант:
C#
1
2
3
4
public static bool CreateAndAddList(string FilePath, ICollection<string> list);
 
// тут в list будут записаны все данные из файла
public static void GetAllFileLines(string FilePath, ref ICollection<string> list, bool IgnoreEmptyString);
но мне внутри GetAllFileLines надо обнулить list причем не через Clear, а через = new ..., только new что.

по этому как то не очень мне этот вариант, а до вызова метода очищать список мне не хочется.

Может как то можно через обобщения, только как мне перечислить все эти варианты списков, я делаю так:
C#
1
2
3
    where C : HashSet<string>
    where C : SortedSet<string>
    where C : List<string>
но внутри метода я не могу сделать:
C#
1
2
3
C list = new C();
// или
C<string> list = new C<string>();
если я к перечислению добавляю
C#
1
where C: new()
получаю ошибку что все кроме new лишнее.
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
27.08.2015, 16:17
Ответы с готовыми решениями:

Получение коллекции из ассинхронного вызова
Здравствуйте. Есть классы, с помощью которых парсится json файл public class SampleDataItem { public...

Получение элементов с индексами при обходе коллекции
В Python можно обойти коллекцию сразу получая элементы и индексы: for item_index, item_itself in enumerate(collection): Как такое...

Получение коллекций из элементов коллекции, которые будут объединены по какому-то свойству
Здравствуйте. Подскажите новичку. Есть коллекция элементов с определенными свойствами. Как можно и можно ли вообще, создать из этой...

13
Эксперт .NET
 Аватар для insite2012
5548 / 4311 / 1218
Регистрация: 12.10.2013
Сообщений: 12,371
Записей в блоге: 2
27.08.2015, 16:55
Цитата Сообщение от VLK Посмотреть сообщение
только как мне перечислить все эти варианты списков
Используйте обобщенные интерфейсы, которые реализует все эти коллекции.
Вот эти они все реализуют.
ICollection<T>, IEnumerable<T>
0
307 / 284 / 102
Регистрация: 06.05.2014
Сообщений: 861
27.08.2015, 17:15
VLK,
Кликните здесь для просмотра всего текста
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public static ICollection<string> ReadFile(string FilePath, bool IgnoreEmptyString)
{
    try
    {
        string tmp = File.ReadAllText(FilePath);
        return new HashSet<string>(tmp.Split(new char[] { '\n' }, IgnoreEmptyString == true ? StringSplitOptions.RemoveEmptyEntries : StringSplitOptions.None));
    }
    catch
    {
        return new HashSet<string>();
    }
}
 
public static bool WriteFile(string FilePath, ICollection<string> list)
{
    try
    {
        if (!Directory.Exists(Path.GetDirectoryName(FilePath)))
            Directory.CreateDirectory(Path.GetDirectoryName(FilePath));
        File.WriteAllText(FilePath, String.Join(Environment.NewLine, list.ToArray()));
        return true;
    }
    catch
    {
        return false;
    }
}
Не идеально, но всё же...
P.S. И я бы не рекомендовал return'ить что-либо при возникновении исключения - их необходимо обрабатывать, а не игнорировать.
0
 Аватар для VLK
198 / 170 / 19
Регистрация: 05.05.2013
Сообщений: 1,236
27.08.2015, 17:16  [ТС]
insite2012, а как это должно выглядеть в коде? я в этом плане ума не приложу.
да и там писать всего ни чего, можно?
0
Эксперт .NET
 Аватар для insite2012
5548 / 4311 / 1218
Регистрация: 12.10.2013
Сообщений: 12,371
Записей в блоге: 2
27.08.2015, 17:31
Цитата Сообщение от VLK Посмотреть сообщение
как это должно выглядеть в коде?
Не вникал в вашу задачу, но может типа такого...
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace ConsoleApplication19 {
    static class Program {
        static void Main(string[] args) {
            string[] lines = { "ONE", "TWO", "THREE", "FOUR" };
            ICollection<string> result = lines.GetCollection<string>();
        }
        static ICollection<T> GetCollection<T>(this IEnumerable<T> collection) {
            //Тут логика обработки.....
            return new SortedSet<T>(collection);
        }
    }
}
0
 Аватар для rockandroll
16 / 16 / 8
Регистрация: 05.08.2015
Сообщений: 79
27.08.2015, 18:55
BozKurt, не так ли дорога операция Split, чтобы не написать парочку лишних строк кода?

C#
1
2
3
4
5
try
    {
        string tmp = File.ReadAllText(FilePath);
        return new HashSet<string>(tmp.Split(new char[] { '\n' }, IgnoreEmptyString == true ?   StringSplitOptions.RemoveEmptyEntries : StringSplitOptions.None));
    }
вот например со стека:

What happens when you do a split on a string containing 1355049 comma separated strings of 16 characters each, having total character length of 25745930 ?

1. An Array of pointers to string object: Contiguous virtual address space of 4 (address pointer)*1355049 = 5420196 (arrays size) + 16 (for book keeping) = 5420212.

2. Non-contiguous virtual address space for 1355049 strings, each of 54 bytes. It does not mean all those 1.3 million strings would be scattered all across the heap, but they will not be allocated on LOH. GC will allocate them on bunches on Gen0 heap.

3. Split.Function will create internal array of System.Int32[] of size 25745930, consuming (102983736 bytes) ~98MB of LOH, which is very expensive L.
Плюс мне было интересно проверить у себя что быстрее. На небольшом объеме до 100 тыс строк String.Split работал на 2ms быстрее а вот на 1 млн строк (может и меньше) он естественно уже вылетает с "out of memory exception".
так что вариант читать построчно не так уж и плох. тем более что он по времени уступает в несколько ms.
0
 Аватар для VLK
198 / 170 / 19
Регистрация: 05.05.2013
Сообщений: 1,236
27.08.2015, 19:55  [ТС]
ну и вот я такое сделал:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
public static class FileManager2
{
    public static COLLECTION GetAllFileLines<COLLECTION>(string FilePath, bool IgnoreEmptyString) where COLLECTION : ICollection<string>, new()
    {
        COLLECTION list = new COLLECTION();
        try
        {
            StreamReader file = new StreamReader(FilePath);
            string temp;
 
            while ((temp = file.ReadLine()) != null)
            {
                if (IgnoreEmptyString && temp != "") list.Add(temp);
                else list.Add(temp);
            }
 
            file.Close();
            return list;
        }
        catch
        {
            return list;
        }
    }
 
 
 
 
    public static bool CreateAndAddList(string FilePath, ICollection list)
    {
        if (File.Exists(FilePath) == false)
        {
            string dir = Path.GetDirectoryName(FilePath);
 
            if (string.IsNullOrEmpty(dir) == false) Directory.CreateDirectory(dir);
 
            File.CreateText(FilePath).Close();
        }
 
        try
        {
            StreamWriter file = new StreamWriter(FilePath);
            foreach (string temp in list) file.WriteLine(temp);
            file.Close();
 
            return true;
        }
        catch
        {
            return false;
        }
    }
}
Добавлено через 1 минуту
BozKurt, rockandroll, кстати, а почему ReadAllText, я вот построчно читаю (ReadLine), это плохо (хуже)?
0
 Аватар для rockandroll
16 / 16 / 8
Регистрация: 05.08.2015
Сообщений: 79
27.08.2015, 20:04
в данном случае мой ответ был как раз в сторону того, что тут лучше ReadLine и тебе не нужно лишний раз делать Split операцию.

...или, перечитав свой коммент, я понял что недописал. Сравнение было между тем чтобы сделать ReadAllText,
а потом "сплитить" и построчной записи в лист с помощью ReadLine. так вот второе лучше в случае, как минимум, больших файлов (многострочных).
0
 Аватар для VLK
198 / 170 / 19
Регистрация: 05.05.2013
Сообщений: 1,236
27.08.2015, 21:08  [ТС]
Вот конечный вариант, даже с описанием:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
 
public static class FileManager
{
      /// <summary>
      /// Получает все строки из файла в виде указанной коллекции, каждая строка - новый элемент коллекции,
      /// если файл не существует или возникла ошибка при чтении, будет возвращена пустая коллекция
      /// </summary>
      /// <typeparam name="CT">Коллекция реализованная на интерфейсе ICollection с типом string,   
      /// List, HashSet или SortedSet</typeparam>
      /// <param name="FilePath">путь к файлу</param>
      /// <param name="IgnoreEmptyString">если  строка равна "", записывать его в коллекцию или нет,
      /// TRUE - незаписывать, FALSE - записывать</param>
      /// <returns>Коллекцию реализованную на интерфейсе ICollection с типом string,   
      /// если файл не существует или возникла ошибка при чтении, будет возвращена пустая коллекция</returns>
      public static CT GetAllFileLines<CT>(string FilePath, bool IgnoreEmptyString)   
          where CT : ICollection<string>, new()
      {
          CT sameCollection = new CT();
          try
          {
              StreamReader file = new StreamReader(FilePath);
              string temp;
 
              while ((temp = file.ReadLine()) != null)
              {
                  if (IgnoreEmptyString && temp != "") sameCollection.Add(temp);
                  else sameCollection.Add(temp);
              }
 
              file.Close();
              return sameCollection;
          }
          catch
          {
              return sameCollection;
          }
      }
 
      /// <summary>
      /// Записывает в указанный файл все элементы коллекции, каждый элемент с новой строки,   
      /// все содержимое файла до записи будет удалено,
      /// если файл не существует, он будет создан
      /// </summary>
      /// <param name="FilePath">путь к файлу, если файл не существует, он будет создан</param>
      /// <param name="SameCollection">коллекция, будет записана построчно в файл (каждый новый элемент с новой строки),   
      /// коллекция реализованная через интерфейс IEnumerable с типом string</param>
      /// <returns>TRUE при успешной записи, FALSE при возникновении какой-нибудь исключительной ситуации</returns>
      public static bool RewriteFile(string FilePath, IEnumerable<string> SameCollection) // IEnumerable ICollection
      {
          if (File.Exists(FilePath) == false)
          {
              string dir = Path.GetDirectoryName(FilePath);
              if (string.IsNullOrEmpty(dir) == false) Directory.CreateDirectory(dir);
              File.CreateText(FilePath).Close();
          }
 
          try
          {
              StreamWriter file = new StreamWriter(FilePath);
              foreach (string temp in SameCollection) file.WriteLine(temp);
              file.Close();
 
              return true;
          }
          catch
          {
              return false;
          }
      }
 
}
запись в файл:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
string[] arr = { "one", "two", "three" };
List<string> list = new List<string>(arr);
HashSet<string> hashSet = new HashSet<string>(arr);
SortedSet<string> sortedSet = new SortedSet<string>(arr);
Queue<string> queue = new Queue<string>(arr);
Stack<string> stack = new Stack<string>(arr);
 
FileManager.RewriteFile(@"M:\test1.txt", list);
FileManager.RewriteFile(@"M:\test2.txt", hashSet);              
FileManager.RewriteFile(@"M:\test3.txt", sortedSet);
 
FileManager.RewriteFile(@"M:\test4.txt", queue);
FileManager.RewriteFile(@"M:\test5.txt", stack);
 
FileManager.RewriteFile(@"M:\test6.txt", arr);
чтение из файла:
C#
1
2
3
var data1 = FileManager.GetAllFileLines<List<string>>(@"M:\test.txt", true);
var data2 = FileManager.GetAllFileLines<HashSet<string>>(@"M:\test.txt", true);
var data3 = FileManager.GetAllFileLines<SortedSet<string>>(@"M:\test.txt", true);
0
Master of Orion
Эксперт .NET
 Аватар для Psilon
6102 / 4958 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
27.08.2015, 21:31
Лучший ответ Сообщение было отмечено VLK как решение

Решение

VLK,
1) глотает исключения
2) может вернуть только коллекцию string'ов
3) может быть короче и понятнее записано стандартными средствами (не придется лезть разбираться, что за файлменеджер такой):
C#
1
2
3
var data1 = new List<string>(File.ReadLines(@"M:\test.txt"));
var data2 = new HashSet<string>(File.ReadLines(@"M:\test.txt"));
var data3 = new SortedSet<string>(File.ReadLines(@"M:\test.txt"));
Пропуск пустых строк можно просто докинув один Where.

Вместо Rewrite просто вызывается File.WriteAllLines, которая точно также имеет перегрузку с IEnumerable<string> или более подходящая.

Добавлено через 1 минуту
4) в случае исключения во время записи поток остается незакрытым.
2
 Аватар для VLK
198 / 170 / 19
Регистрация: 05.05.2013
Сообщений: 1,236
27.08.2015, 22:11  [ТС]
Psilon, спасибо, но как говорится нет худа без добра, за то я немного разобрался как писать обобщения, а то мои старые записи кривые.

Еще такой вопрос, а есть что то в одну строчку, создать файл если он не существует, в том числе и с папками, ну допустим у меня на M:\ нет папки data, а мне надо сделать
C#
1
2
string[] arr = { "one", "two", "three" };
File.WriteAllLines(@"M:\data\test.txt", arr);
я же ошибку получу сразу из-за этой папки.

но если файл существует что бы с ним ни чего не сделалось.

Добавлено через 1 минуту
у меня собственно идея написания этого FileManager и появилась из-за того что мне надо было создавать папки еще автоматически.
0
Master of Orion
Эксперт .NET
 Аватар для Psilon
6102 / 4958 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
28.08.2015, 00:57
VLK, ну если вы в одном месте так делаете, то прям на месте можно. Если нет, то просто 2 строчки пишем (без своих записывальщиков) и всё
C#
1
2
3
4
5
6
7
8
    public static class XFile
    {
        public static void WriteAllLines(string path, string[] lines)
        {
            Directory.CreateDirectory(Path.GetDirectoryName(path));
            File.WriteAllLines(path, lines);
        }
    }
1
 Аватар для rockandroll
16 / 16 / 8
Регистрация: 05.08.2015
Сообщений: 79
28.08.2015, 07:17
только лучше не
C#
1
while ((temp = file.ReadLine()) != null)
а вот так

C#
1
while (file.Peek() > 0)
хотя это наверное вопрос стиля. или один я так пишу?
1
Эксперт .NETАвтор FAQ
 Аватар для Storm23
10427 / 5157 / 1825
Регистрация: 11.01.2015
Сообщений: 6,226
Записей в блоге: 34
28.08.2015, 07:45
rockandroll,
C#
1
while (file.Peek() >= 0)...
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
28.08.2015, 07:45
Помогаю со студенческими работами здесь

Как удалить элемент из коллекции, во время перебора этой коллекции foreach?
Прив. Смотрите что. Есть сервер, на нем 2 класса - Server &amp; ClientConnection. При подключении нового клиента в Server создается новый...

Сделать сортировку коллекции вместо создания новой коллекции с передачей IOrderedEnumerable<T>
Есть: SortableObservableCollection&lt;T&gt; using System; using System.Collections.Generic; using System.Collections.ObjectModel; using...

Доступ из элемента коллекции к другим элементам коллекции
Подскажите как получить данные из другого элемента коллекции? В приведенном примере необходимо реализовать метод который бы брал значение...

Трехмерный массив неопределенной длины
Можно задать двумерный массив с отложенной инициализацией: private double _CorrelationArray = new double; И даже такое выражение не...

Анонимные коллекции в другие коллекции, как?
Здравствуйте. Говорю сразу, я не уверен что есть такой термин как анонимная коллекция. Наверно будет правильно сказать анонимная...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
14
Ответ Создать тему
Новые блоги и статьи
Переходник USB-CAN-GPIO
Eddy_Em 20.03.2026
Достаточно давно на работе возникла необходимость в переходнике CAN-USB с гальваноразвязкой, оный и был разработан. Однако, все меня терзала совесть, что аж 48-ногий МК используется так тупо: просто. . .
Оттенки серого
Argus19 18.03.2026
Оттенки серого Нашёл в интернете 3 прекрасных модуля: Модуль класса открытия диалога открытия/ сохранения файла на Win32 API; Модуль класса быстрого перекодирования цветного изображения в оттенки. . .
SDL3 для Desktop (MinGW): Рисуем цветные прямоугольники с помощью рисовальщика SDL3 на Си и C++
8Observer8 17.03.2026
Содержание блога Финальные проекты на Си и на C++: finish-rectangles-sdl3-c. zip finish-rectangles-sdl3-cpp. zip
Символические и жёсткие ссылки в Linux.
algri14 15.03.2026
Существует два типа ссылок — символические и жёсткие. Ссылка в Linux — это запись в каталоге, которая может указывать либо на inode «файла-ИСТОЧНИКА», тогда это будет «жёсткая ссылка» (hard link),. . .
[Owen Logic] Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора
ФедосеевПавел 14.03.2026
Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора ВВЕДЕНИЕ Выполняя задание на управление насосной группой заполнения резервуара,. . .
делаю науч статью по влиянию грибов на сукцессию
anaschu 13.03.2026
прикрепляю статью
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога Финальные проекты на Си и на C++: hello-sdl3-c. zip hello-sdl3-cpp. zip Результат:
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru