Форум программистов, компьютерный форум, киберфорум
C# .NET
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.97/32: Рейтинг темы: голосов - 32, средняя оценка - 4.97
1 / 1 / 0
Регистрация: 01.06.2013
Сообщений: 11
1

Многопоточное чтение больших файлов

21.07.2014, 22:05. Показов 6686. Ответов 4
Метки нет (Все метки)

Привет всем!
Подскажите пожалуйста как реализовать многопоточное чтение файла рамером 1gb и больше без загрузки в память?
Пробовал читать блочно, но теряется часть текста из-за того что ридер читает определенное количество байт
В идеале должно быть что-то на подобии блочного чтения только читать строки от и до без загрузки в память.

Добавлено через 2 минуты
И забыл добавить, и что бы все это работало в пределах .NET 3.5 (на крайняк 4.0).
Заранее благодарен
__________________
Помощь в написании контрольных, курсовых и дипломных работ здесь
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
21.07.2014, 22:05
Ответы с готовыми решениями:

Подскажите паттерн для задачи (многопоточное чтение и обработка файлов)
Добрый день! Есть следующая задача. Нужно делать многопоточную программу. 2 потока читают данные...

Чтение и обработка больших файлов
Нужно прочитать большой файл (несколько гигабайт), поделить содержимое файла на int'ы и посчитать...

Чтение больших файлов (несколько гигабайт)
Доброго времени! Нужно прочесть и пропарсить крупный файл весом в несколько гигабайт. Подскажите...

Чтение запись файлов *.csv больших размеров
Доброго времени суток, форумчане! Нужно сделать: • прочитать данные таймсерий из файла...

4
674 / 420 / 44
Регистрация: 09.07.2012
Сообщений: 1,419
22.07.2014, 09:45 2
Файл текстовый? Может открыть его, узнать сколько строк, узнать сколько логических процессоров на ПК и поделить эти значения и прочитать каждым получившимся потоком свою часть файла? Читать можно без необходимости синхронизации, хотя они и не должны пересекаться при правильном расчете.

Лучше использовать асинхронное чтение, так потоки не будут блокироваться ожидая ответа, и возможно одного хватит. (Пример кода в теме которая указана ниже)

StreamReader.ReadLine
NET 4.0 -> File.ReadLines

Прочитайте тему "how to read big text files in C# Threads" на social.msdn.microsoft.com
1
Master of Orion
Эксперт .NET
6088 / 4944 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
22.07.2014, 11:48 3
kill4you, узким местом в любом случае будет диск, если только SSD не используется.

Поэтому да, как сказали выше, неблокирующее чтение вам поможет. Почитайте книжку вот эту, там многие вопросы оговорены, в том числе и этот.
2
Эксперт .NET
15555 / 11804 / 3097
Регистрация: 17.09.2011
Сообщений: 19,716
22.07.2014, 16:27 4
Цитата Сообщение от kill4you Посмотреть сообщение
Подскажите пожалуйста как реализовать многопоточное чтение файла рамером 1gb и больше без загрузки в память?
Вообще без загрузки — никак. Строки ведь считывать куда-то надо.
Другое дело, что уже считанные и обработанные строки в памяти держать не обязательно — пусть их сборщик снесет.

Простой пример, как можно организовать синхронизированный доступ к файлу из нескольких потоков:
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
76
77
class Program
{
    // Класс для передачи данных в поток
    class StateObject<T>
    {
        public T UserState { get; private set; }
        public object SyncRoot { get; private set; }
        public bool IsCancelled { get; set; }
 
        public StateObject(T state, object syncRoot)
        {
            UserState = state;
            SyncRoot = syncRoot;
        }
    }
 
    static void Main()
    {
        // Открытие файла для чтения
        using (var reader = new StreamReader("bigfile.txt", Encoding.UTF8))
        {
            // Объект, хранящий ссылку на файловый поток, ссылку для синхронизации и флаг для отмены
            var state = new StateObject<StreamReader>(reader, new object());
 
            // Запуск десяти потоков для построчной обработки текстового файла.
            var threads = new Thread[10];
            for (int i = 0; i < threads.Length; i++)
            {
                threads[i] = new Thread(ThreadProc);
                threads[i].Start(state);
            }
 
            // Ожидание окончания работы всех потоков или отменты по нажатию любой клавиши
            while (threads.Any(t => t.ThreadState != ThreadState.Stopped))
            {
                if (Console.KeyAvailable)
                    state.IsCancelled = true;
                Thread.Sleep(200);
            }
        }
    }
 
    // Метод, выполняющийся в отдельном потоке
    static void ThreadProc(object arg)
    {
        Console.WriteLine("Worker thread started.");
 
        var state = arg as StateObject<StreamReader>;
        var reader = state.UserState;
        var sync = state.SyncRoot;
 
        // Построчное считывание файла, пока операция не отменена пользователем или все строки не считаны.
        while (!state.IsCancelled)
        {
            string line;
 
            // Считывание строки из файла.
            lock (sync) 
                line = reader.ReadLine();
 
            // Строки кончились, цикл завершается.
            if (line == null) break;
 
            // Обработка строки. Может занять длительное время.
            Process(line);
        }
        Console.WriteLine("Worker thread finished.");
    }
 
    static void Process(string line)
    {
        Console.WriteLine("Processing line '{0}'", line);
 
        // Обработка строки занимает некоторое время.
        Thread.Sleep(TimeSpan.FromSeconds(1));
    }
}
Разумеется, данный подход не самый хороший, так как считывание очередной строки производится по запросу — это медленно! В каждый момент работает либо процессор, обрабатывая считанную строку, либо диск, считывая следующую. В худшем случае все потоки будут висеть, закончив обрабатывать строчку, пока один из них будет считывать очередную.

Лучше все-таки организовать один поток для считывания строк, а остальные потоки — для их обработки. То есть реализовать паттерн поставщик/потребитель. Тогда все будут при деле: и диск, и цп.
4
27 / 27 / 5
Регистрация: 24.03.2013
Сообщений: 238
22.07.2014, 22:26 5
Вот отличное описание на русском паттерна Producer/Consumer: http://hashcode.ru/research/22... er-pattern
3
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
22.07.2014, 22:26

Чтение в richtextbox больших файлов сопровождается большим потреблением памяти приложением
Здравствуйте! Вот мне не понятно: я читаю содержимое файла в RichTextBox (вес этого файла 207 мб)....

Многопоточное чтение по одному элементу из списка
Допустим есть список с ProgressBar и есть список потоков. Каждый поток должен взять по одному...

Многопоточное чтение больших файлов
Доброго времени суток! Нужен совет. Имеется, скажем, 10 текстовых файлов 1.txt;2.txt и т.д. и...

Чтение больших файлов Excel
пытаюсь считать данные с XLSX файла (500 000 строк). на MSDN наткнутся на статью каким образом это...

Чтение больших файлов в DataGridView
Приветствую вас. Вопрос в том как можно можно отобразить данный из файла большого объёма скажем 1g....

Чтение файлов больших размеров >1Гб
Товарищи, подскажите как прочитать файл размером больше 1Гб.. у меня при чтении оперативка...


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

Или воспользуйтесь поиском по форуму:
5
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2022, CyberForum.ru