Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: просмотр больших файлов  (Прочитано 26142 раз)
0 Пользователей и 2 Гостей смотрят эту тему.
lex452
Интересующийся

ru
Offline Offline

« : 10-02-2011 16:11 » 

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

Код:
using System;
using System.Drawing;
using System.Windows.Forms;
using System.IO;
using System.Text;

namespace WindowsFormsApplication75
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            OpenFileDialog ofd = new OpenFileDialog();
            if (ofd.ShowDialog(this) == System.Windows.Forms.DialogResult.OK)
            {
                FileStream stream = new FileStream(ofd.FileName, FileMode.Open, FileAccess.Read);
                FileViewer viewer = new FileViewer(stream);
                viewer.Parent = this;
                viewer.Dock = DockStyle.Fill;
            }
        }
    }

    //Просмотрщик больших файлов
    public class FileViewer : UserControl
    {
        Stream stream;
        int CharHeight;
        int CharWidth;

        public FileViewer(Stream stream)
        {
            this.stream = stream;
            //
            Font = new Font(FontFamily.GenericMonospace, 10);
            CharHeight = 15;
            CharWidth = 9;
            //
            AutoScroll = true;
            SetStyle(ControlStyles.AllPaintingInWmPaint, true);
            SetStyle(ControlStyles.UserPaint, true);
            SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
        }

        protected override void Dispose(bool disposing)
        {
            base.Dispose(disposing);
            stream.Dispose();
        }

        protected override void OnResize(EventArgs e)
        {
            base.OnResize(e);
            if (ClientRectangle.Width > 0)
            {
                int symbolsPerPageLine = ClientRectangle.Width / CharWidth;
                int linesPerPage = ClientRectangle.Height / CharHeight;
                int linesCount = (int)stream.Length / symbolsPerPageLine;
                AutoScrollMinSize = new Size(1, 1 + linesCount + ClientRectangle.Height - linesPerPage);
                VerticalScroll.SmallChange = 1;
                VerticalScroll.LargeChange = ClientRectangle.Height / CharHeight;
                Invalidate();
            }
        }

        protected override void OnScroll(ScrollEventArgs se)
        {
            base.OnScroll(se);
            Invalidate();
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            //
            int symbolsPerLine = ClientRectangle.Width / CharWidth;
            int linesPerPage = ClientRectangle.Height / CharHeight;
            int startPos = VerticalScroll.Value * symbolsPerLine;
            stream.Seek(startPos, SeekOrigin.Begin);
            //
            byte[] buffer = new byte[symbolsPerLine];
            //
            for(int y=0; y < linesPerPage; y++)
            if (stream.Position < stream.Length)
            {
                int count = stream.Read(buffer, 0, buffer.Length);
                char[] chars = Encoding.Default.GetChars(buffer, 0, count);
                for (int x = 0; x < chars.Length; x++)
                    e.Graphics.DrawString(chars[x].ToString(), Font, Brushes.Black, x * CharWidth, y * CharHeight);
            }
        }
    }
}
подскажите как переделать ее так чтобы файл можно было просматривать таким же образом, но через richTexBox?Не понял
« Последнее редактирование: 10-02-2011 19:42 от Джон » Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #1 : 10-02-2011 16:53 » 

lex452, унаследовать от RichTextBox, сделать моноширинный шрифт, и вместо рисования на экране записывать текст в соответствующие свойства RichTextBox. Естественно, скроллинг либо потеряется, либо придётся загружать весь файл целиком, либо реализовывать скроллинг отдельно.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
lex452
Интересующийся

ru
Offline Offline

« Ответ #2 : 10-02-2011 17:50 » 

в том то и дело, что целый файл не получится никак загрузить, и времени много займет и тупо он не поместиться в richTextBox
Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #3 : 10-02-2011 17:59 » 

lex452, и?
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
lex452
Интересующийся

ru
Offline Offline

« Ответ #4 : 10-02-2011 18:06 » 

весь функционал значит не получится перенести в textBox???
Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #5 : 10-02-2011 18:07 » 

lex452, интересно и содержательно поговорили. Ну, успехов...
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
lex452
Интересующийся

ru
Offline Offline

« Ответ #6 : 10-02-2011 18:10 » 

я пробовал и не смог сделать чтобы при скролинге файл подгружался динамически, может есть какие то идеи?  Как определить скролинг в какую сторону идет вверх или низ???
Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #7 : 10-02-2011 20:28 » 

lex452, какой "весь функционал"? О чём вообще речь? Что значит, как определить, куда идёт скроллинг, если скроллинг у RichTextBox относится только к содержимому этого text box, которое является лишь частью файла - это вообще неадекватный скроллинг, его нельзя использовать, потому что scroll bar должен знать про весь файл, а не про его часть.

Ты слышал слова "постановка задачи", "техническое задание" и т.п.? Где всё это? Какие пользовательские функции должны присутствовать в конечном решении, которое ты хочешь получить? Какое отношение к этим пользовательским функциям имеет RichTextBox? Почему мне или другим читателям об этом надо догадываться? Телепатов тут нет, RichTextBox не умеет работать с файлами по частям - это в первую очередь редактор и устроен он именно для этого, а приведённое тобою решение вовсе не является редактором, это просто отрисовка куска текстового файла, и устроена она соответственно.

Если использовать гротеск, то твоя проблема выглядит, как нижеследующая:

Есть код:
Код: (ASM)
mov ah, 08h
Как мне его переделать, чтобы получилась операционная система?

Ответ: никак, потому что строчка ассемблерного кода - это про Фому, а операционная система - это про Ерёму.

P.S.
Цитата: lex452
я пробовал и не смог сделать
Если пробовал, то показывай, что и как пробовал.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
lex452
Интересующийся

ru
Offline Offline

« Ответ #8 : 10-02-2011 21:47 » 

Нужен просмотр больших файлов, (с разными кодировками и все такое), типа как в FarManager ну или Lister в тоталкоммандере. Для отображения файла хочу использовать richTextBox (не вижу лучшего компонента для этой цели), но некоторые файлы по просту не помещаются в richTextBox или их открытие занимает слишком много времени. Я думал реализовать это загрузкой в richTextBox файла не полностью, а частями способными поместиться на экран и при скролинге удалять первые строки и добавлять в конец новые, пропорционально скролингу. а вот как реализовать это не знаю, потому что даже не нашел как определить в какую сторону прокручивается скроллбар вверх или вниз. Подскажите может есть другие идеи как это сделать?Не понял?
Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #9 : 11-02-2011 06:02 » 

Цитата: lex452
Нужен просмотр больших файлов, (с разными кодировками и все такое), типа как в FarManager ну или Lister в тоталкоммандере. Для отображения файла хочу использовать richTextBox (не вижу лучшего компонента для этой цели)
Я по приведённому коду вижу, что уже имеющееся у тебя решение работает в общих чертах как Lister в TotalCommander. Поэтому утверждение "нет лучшего компонента для этой цели" - либо ерунда, либо цель указана неправильно. Я лично никакой необходимости в RichTextBox пока не вижу.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #10 : 11-02-2011 07:48 » 

Я с RichText пробовал работать только в WinAPI и было это лет 10 назад - говорю о том, как было состояние дел в win 9x, но не думаю, что кардинально что-то изменилось.  Подгрузка текста на ходу там не предусмотрена - только заливка разом всего буфера. Т.ч. считаю, построчная смена (для имитации скролирования для больших объемов) будет проблемой.
Коли есть уже реализованный компонент, который рендерит текст и делает это так, как надо, то нет смысла использовать RichTextBox.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
lex452
Интересующийся

ru
Offline Offline

« Ответ #11 : 11-02-2011 10:17 » 

В этом компоненте я не понял как сделать перенос строк чтоб не сплошным текстом печаталось
Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #12 : 11-02-2011 12:49 » 

lex452, вручную сделать. Количество строк и столбцов известно - каждую строку из буфера при выводе на экран переносить на другую строку столько раз, сколько нужно. При этом запоминать количество добавленных строк и учитывать при прокрутке и при выполнении seek файлового потока.

RXL, на самом деле рендером RichTextBox можно воспользоваться, если завести Bitmap, а при OnPaint сначала загружать текст в невидимый RichTextBox, и переопределить его OnPaint таким образом, чтобы Graphics он брал не с экрана, а из Bitmap. Аналог собственной двойной буфферизации. Но правильно подключить неразмещённый на форме RichTextBox к событиям формы - это задача, требущая аккуратности. ScrollBar при этом могут быть независимыми элементами управления, а не свойством UserControl.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
lex452
Интересующийся

ru
Offline Offline

« Ответ #13 : 11-02-2011 18:09 » 

А кто сказал что на форме нет richTextBox??? он там есть поподробнее опишите как это сделать???
Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #14 : 11-02-2011 20:25 » 

Цитата: lex452
А кто сказал что на форме нет richTextBox???
Я сказал.

Цитата: lex452
поподробнее опишите как это сделать???
Ты предлагаешь мне написать для тебя готовый компонент? Идею я изложил, а копаться в MSDN и писать код я не собираюсь - мне это неинтересно.

Интересными мне бывают сложные для меня проблемы, которые я не знаю, как решать. Интересным бывает научить человека, который хочет учиться. Ты желания учиться не показываешь. Пока ты показал, судя по всем признакам, кусок чужого кода, в котором ты не понимаешь отдельных строчек, не показал ни одной строчки своего, пожаловался на судьбу в духе "не получается" и высказал пожелания в духе "разжевать и в рот положить".

Так дела не делаются.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
lex452
Интересующийся

ru
Offline Offline

« Ответ #15 : 12-02-2011 14:06 » 

так дело в том что  я не знаю даже с чего начать, потому что не смог найти некоторых свойств которые мне необходимы. Например для отслеживания скрола  в richTextBox. А желание научиться у меня есть как раз, код свой не могу выложить потому что пишу прогу на работе, а от туда скинуть ничего нельзя(((
Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #16 : 12-02-2011 15:03 » 

lex452, для начала расскажи о себе и об этой задаче. Что это за программу ты пишешь, для решения каких задач пишется эта программа, почему ты выбрал те инструменты, которые выбрал? Каков твой уровень профессиональной программистской подготовки: студент профильной или непрофильной специальности, специалист непрофильной специальности, которому по работе пришлось столкнуться с необходимостью программировать (если да, то какова основная специальность), любитель?

Эта информация позволит наладить общение, поскольку я сейчас даже не знаю, на каком языке с каким уровнем доходчивости с тобой разговаривать. Кроме того, важно знать, чего ты хочешь получить в результате - это позволит правильно расставить акценты в разговорах. Например, непрофильный специалист, которому надо побыстрее решить одноразовую задачу - это одно, студент, которому надо научиться решать любые подобные задачи - это совсем другое.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
lex452
Интересующийся

ru
Offline Offline

« Ответ #17 : 13-02-2011 20:08 » 

Я не студент, но по работе столкнулся с необходимостью учиться программировать, мой уровень это можно сказать начальный. В приложении я загружаю список файлов в listBox
и необходимо реализовать функцию просмотра файла (аналогично Far (F3)), чтобы пользователям привыкшим работать в Far, не нужно было привыкать к работе с новым приложением. При просмотре необходима возможность смены кодировки (Win и Dos), желательно переключаться между файлами по нажатию (+ -).
Решил использовать richTextBox, потому что как я понял он практически для этого и предназначен, но столкнулся с проблемой, что большие файлы не могут полностью поместиться в компоненте (возникает ошибка OutOfMemory), и загрузка всего файла занимает много времени, что создает неудобство при работе. На форумах подсказали что в Far файлы загружаются не полностью, а подгружаются в зависимости от скрола. Я попытался это реализовать но не смог найти свойство отвечающее за позицию скролбара и не понял как определить в какую сторону перемещается скроллбар, поэтому получилось что даже начать не с чего. Вот, если есть какие нибудь идеи буду очень благодарен.


Добавлено через 1 минуту и 50 секунд:
И для меня это больше не одноразовая задача, просто я ее сам перед собой поставил и главная цель это научиться.
« Последнее редактирование: 13-02-2011 20:10 от lex452 » Записан
Dale
Блюзмен
Команда клуба

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #18 : 13-02-2011 21:29 » 

Я бы использовал такой подход:

1. Разместил на форме элемент для просмотра текста (кстати, если текст не содержит сложного форматирования с разными шрифтами, раскраской и т.д., то вполне можно обойтись обычным textBox) с выключенным вертикальным scrollbar'ом.

2. Прилепил отдельно справа вертикальный скроллбар.

3. Смастерил клас для работы с текстовым файлом, который кэширует ранее просмотренный текст (для скроллинга назад без задержек) и подчитывает в кэш еще не просмотренный текст (для скроллинга вперед без задержек).

4. Заносил в textBox ровно столько строк, сколько умещается в нем.

5. При скроллинге вниз удалял самую верхнюю строку textBox и добавлял вниз очередную строку из кэша.

6. При скроллинге вверх удалял самую нижнюю строку textBox и добавлял вверх очередную строку из кэша.

В пп. 5 и 6 нужно предусмотреть синхронизацию содержимого текстового окошка с положением scrollbar.

Добавлено через 3 минуты и 35 секунд:
Для синхронизации textBox и scrollbar удобно воспользоваться паттерном GoF Mediator.
« Последнее редактирование: 13-02-2011 21:33 от Dale » Записан

Всего лишь неделя кодирования с последующей неделей отладки могут сэкономить целый час, потраченный на планирование программы. - Дж. Коплин.

Ходить по воде и разрабатывать программное обеспечение по спецификациям очень просто, когда и то, и другое заморожено. - Edward V. Berard

Любые проблемы в информатике решаются добавлением еще одного уровня косвенности – кроме, разумеется, проблемы переизбытка уровней косвенности. — Дэвид Уилер.
lex452
Интересующийся

ru
Offline Offline

« Ответ #19 : 14-02-2011 04:31 » 

Я приблизительно mfr и хочу сделать, только вот какие свойства использовать чтобы отследить куда происходит скрол вверх или низ и как сделать скрол изменяемым по сравнению с размером текста, скрол же всегда одинаковый
Записан
Вад
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #20 : 14-02-2011 05:53 » 

lex452, взять размер файла и просто засунуть его в качестве размера скролла (можно разделить на примерную ширину одной строки, особенно если шрифт моноширинный, чтобы "плашка" скролла была более разумная).

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

То есть, в самом простом случае: имеем строку в 80 символов, открываем файл на 80000 символов и получаем 1000 строк. Пусть на экран помещается 25 строк: тогда скролл будет принимать значения 0..(999-25), или 0..974. (Ну, или 0..999, если не париться о том, что проскроллится до места, где последняя строка будет наверху, а за ней - пустота). Теперь тыкаемся в скролл, попадаем, допустим, на значение скролла 250 (куда-то в 1/4 всей полосы): 250*80 = 20000. Идём и рисуем в textBox, начиная с 20000-ного символа в файле.
« Последнее редактирование: 14-02-2011 06:01 от Вад » Записан
lex452
Интересующийся

ru
Offline Offline

« Ответ #21 : 14-02-2011 10:47 » new

Все равно не понял, как отследить положение скрола??? какое свойство?? и как понять куда он листает вверх или низ??
Записан
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #22 : 14-02-2011 11:26 » 

lex452, скролбар - это GUI элемент, который генерит события пользовательского ввода. См. его описание в MSDN.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Dale
Блюзмен
Команда клуба

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #23 : 14-02-2011 11:50 » 

Все равно не понял, как отследить положение скрола??? какое свойство??

Нужно отслеживать текущую позицию в файле и синхронизировать с ней:
1. textBox;
2. scrollbar;
3. текстовый кэш.

и как понять куда он листает вверх или низ??

Сама по себе программа просмотра ничего не листает. Измениться текущая позиция в файле может в результате:
1. нажатия клавиш управления курсором (вверх/вниз на строчку);
2. нажатия клавиш PadeUp/Down (вверх/вниз на экран);
3. протяжки скроллбара мышью;
4. поиска текста по образцу.

Интерфейсные элементы должны синхронизироваться с событием изменения текущей позиции (см. предыдущий пункт).
Записан

Всего лишь неделя кодирования с последующей неделей отладки могут сэкономить целый час, потраченный на планирование программы. - Дж. Коплин.

Ходить по воде и разрабатывать программное обеспечение по спецификациям очень просто, когда и то, и другое заморожено. - Edward V. Berard

Любые проблемы в информатике решаются добавлением еще одного уровня косвенности – кроме, разумеется, проблемы переизбытка уровней косвенности. — Дэвид Уилер.
lex452
Интересующийся

ru
Offline Offline

« Ответ #24 : 14-02-2011 15:05 » 

Подскажите какре событие возникает при прокручивании колесиком мыши?Не понял И как определять вверх или низ???

Добавлено через 17 минут и 33 секунды:
И я вот еще о чем думал, как отследить какую часть текста считал в прошлый раз?? Постоянно осуществлять поиск по тексту??? А вдруг в нем будут одинаковые строки???

Добавлено через 15 минут и 17 секунд:
И еще как понять что курсор дошел до конца текста, т.е. то что он на нижней строке textBoxa??

Добавлено через 13 минут и 37 секунд:
 и ничего не нашел про gof mediator? где про это почитать??
« Последнее редактирование: 14-02-2011 15:22 от lex452 » Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #25 : 14-02-2011 16:25 » 

Цитата: lex452
Подскажите какре событие возникает при прокручивании колесиком мыши?
MouseWheel. Подробности в MSDN.

Цитата: lex452
И я вот еще о чем думал, как отследить какую часть текста считал в прошлый раз?? Постоянно осуществлять поиск по тексту??? А вдруг в нем будут одинаковые строки???
Текст тут ни при чём. Чтение определяется позицией в файле - это число, индекс байта. Любой кусок определяется позицией начала и конца. Соотнести позицию с интервалом или два числовых интервала между собой и определить, что делать дальше - задача тривиальная. Нужно только продумать как следует, нарисовать на листочке карандашом, что и как меняется.

Цитата: lex452
И еще как понять что курсор дошел до конца текста, т.е. то что он на нижней строке textBoxa??
Зачем курсор для просмотра?

Цитата: lex452
и ничего не нашел про gof mediator? где про это почитать??
Вот это очень странно. По строчке gof mediator Гугл и Яндекс выдают вагон ссылок. Из них (даже на русском языке) не составляет труда выяснить, что GoF - это условное обозначение так называемой "банды четырёх", а собственно шаблон называется mediator.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
lex452
Интересующийся

ru
Offline Offline

« Ответ #26 : 15-02-2011 12:15 » 

Текст тут ни при чём. Чтение определяется позицией в файле - это число, индекс байта. Любой кусок определяется позицией начала и конца. Соотнести позицию с интервалом или два числовых интервала между собой и определить, что делать дальше - задача тривиальная. Нужно только продумать как следует, нарисовать на листочке карандашом, что и как меняется.

Каким способом ты предлагаешь считывать файл, и где там будет этот байт начала и конца, и интервалы??
Записан
Вад
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #27 : 15-02-2011 12:25 » 

У FileStream есть не только метод Read, позволяющий читать нужное количество байт начиная с текущей позиции (или смещения относительно неё), но также метод Seek (переход на нужную позицию в файле) и свойство Length, указывающее общий размер файла. Детали, как всегда, в MSDN.
« Последнее редактирование: 15-02-2011 12:27 от Вад » Записан
lex452
Интересующийся

ru
Offline Offline

« Ответ #28 : 15-02-2011 12:48 » 

Я работал с FileStream ? только вот считывал обычно по строчно, кстати а в FileStream нельзя задать количество считываемых строк и позицию строки в файле??

Добавлено через 1 день, 4 часа, 58 минут и 16 секунд:
Получилось считывать файл с буфером равным размеру видимой части textBox1 через FileStream, но только если текст будет заполнять textBox1 полностью, а строки на самом деле переносятся и их получается больше чем может поместиться в видимой части textBox1. Может можно как-то считывать по строкам и запоминать на какой строке остановилось предидущее считывание??
Еще столкнулся с проблемой что при преобразовании byte в char не отображается русская буква 'Ф', в чем может быть проблема??
« Последнее редактирование: 16-02-2011 17:47 от lex452 » Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines