Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Как сдвинуть данные в потоке?


MegaVolt ©   (2006-03-15 13:28:00) 

Как в потоке TFileStream сдвинуть данные например для того чтобы вставить в середину кусок? Для памяти есть move а для потока есть что то аналогичное? Или только через буфер? Скопировал кусок перезаписал на новое место и так до тех пор пока всё не сдвинетсЯ?


Leonid Troyanovsky   (2006-03-16 14:07:00) [1]


> MegaVolt ©   (16.03.06 11:35) [19]

> При чтении максимальная скорость получалась при чтении блоками
> по 32К это имхо больше


Не знаю, как со чтением, требуется-то чтение-запись.
Не думаю, что, скажем, опережающее чтение здесь сильно поможет.
Т.е., сделать размер буфера = размеру кластеру и оставить потуги
оптимизации системе.

--
Regards, LVT.


MegaVolt   (2006-03-16 11:35:00) [2]

>Размер кластера?

При чтении максимальная скорость получалась при чтении блоками по 32К это имхо больше коррелирует с кешем процессора чем с кластером.
Возможно при чтении-записи цифирь будет другая. В идеале она должна равнятся точно длинне текущей дорожки. Однако учитывая что файл может быть фрагментирован вся эта оптимизация пойдёт коту под хвост.


Leonid Troyanovsky   (2006-03-15 19:41:00) [3]


> MegaVolt ©   (15.03.06 19:27) [17]

> Я пока решил делать копирование блочков в пределах одного
> FileStream размер нужно подобрать чтобы веник не сильно


Размер кластера?

--
Regards, LVT.


MegaVolt   (2006-03-15 19:27:00) [4]

>Если сделаешь, расскажи.

Я пока решил делать копирование блочков в пределах одного FileStream размер нужно подобрать чтобы веник не сильно гремел.


Leonid Troyanovsky   (2006-03-15 18:27:00) [5]


> MegaVolt ©   (15.03.06 17:38) [15]

> >Если  речь о экономии (вероятно, файл большой), то, возможно,
>  что даже пара MapView где-то в 64K.

> Упс... непонял идеи :(


Предположим, что файл большой, тогда создать просмотр на
весь хвост файла  может быть невыгодно (при малом объеме памяти).
Т.е., создадим два просмотра такого (небольшого) размера, что
они заведомо не будут сбрасываться из кеша страниц при работе Move.
Эти просмотры находятся последовательно друг за другом
(правый из них в конце файла).
Затем Move, после чего второй просмотр закрывается и открывается
новый, теперь перед первым и т.д.

Только надо не забыть, что у MapView
the offset must be a multiple of the allocation granularity.
Иначе говоря, для того, чтобы сделать правильно мы должны определить,
сколько пар по 64К уложатся между точкой вставки и новой длиной файла
(старая+длина вставки).
Самая левая пара может лежать левее реальной точки
вставки. Поэтому последняя команда Move, сдвигающая
самый левый просмотр  должна это учесть.

Ну, и, наконец, Move который будет копировать вставку.
Если размер вставки более 64К, алгоритм вставки аналогичен:
в левый просмотр Move в точку вставки до конца просмотра,
далее, уже порциями по 64К, и n байтов - в последний.

Если сделаешь, расскажи.
Особенно интересно было б сравнить с простым перемещением блоками,
скажем, размером в кластер.

--
Regards, LVT.


MegaVolt   (2006-03-15 17:38:00) [6]

> MBo
>А что в двух файлах не нравится?

Место под результирующий файл. Если исходный большой то это не есть гуд.

> Сергей М
>При двух файлстримах без этого не обойтись.

А зачем второй стрим? Если все данные в памяти можно писать и в тот же. И начальные данные не трогать.

> Leonid Troyanovsky
>Если  речь о экономии (вероятно, файл большой), то, возможно, что даже пара MapView где-то в 64K.

Упс... непонял идеи :(


Leonid Troyanovsky   (2006-03-15 15:44:00) [7]


> MBo ©   (15.03.06 14:46) [7]

> 3. отобразить MMF (CreateFileMapping+MapViewOfFile)  

Если  речь о экономии (вероятно, файл большой), то,
возможно, что даже пара MapView где-то в 64K.

--
Regards, LVT.


Сергей М.   (2006-03-15 15:41:00) [8]


> MegaVolt ©   (15.03.06 15:31) [11]


При двух файлстримах без этого не обойтись.


MBo   (2006-03-15 15:39:00) [9]

>MegaVolt
> Блоками какого размера будут переносится данные?
об этом позаботится Move и механизм маппинга Windows

Однако способ с двумя файлами проще. А что в двух файлах не нравится?


MegaVolt   (2006-03-15 15:31:00) [10]

Сергей М.

Я не совсем понял зачем читать из потока то что было до точки вставки а потом писать то же на то же место?

Этот вариант я и предлогал в самом вопросе только чтобы не занимать память на весь файл я бы копировал кусками помельче. Но принцип тот же.


MegaVolt   (2006-03-15 15:28:00) [11]

>Вставка в середину или начало файла невозможно. Так что иного способа, как создать новый файл, переписать в него начало старого, добавить вставляемое и дописать остаток, не существует.

Ну почему же вот в [7]  предложен один из вариантов.

>MBo
>а такое не устроит?

Подходит конечно. Только не совсем понятно как это будет реализовано на физическом уровне. Блоками какого размера будут переносится данные? Короче сильно ли будет трещать веник?


Leonid Troyanovsky   (2006-03-15 15:28:00) [12]


> Сергей М. ©   (15.03.06 14:44) [6]

> SingleFileStream.WriteBuffer(before, ..); //пишешь из памяти
> все то что фигурировало в изменяемом файле ДО точки вставки


Там оно уже есть, т.е. просто Position на точку вставки.

--
Regards, LVT.


Amoeba   (2006-03-15 14:47:00) [13]


> MegaVolt ©   (15.03.06 14:35) [5]
> >Он-то как раз и обеспечивается использованием двух FileStream'ов.
>
>
> Созданных для одного и того же файла?

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


MBo   (2006-03-15 14:46:00) [14]

а такое не устроит?
1. Открыть файл (CreateFile)
2. Расширить его (SetFilePointer+SetEndOfFile)
3. отобразить MMF (CreateFileMapping+MapViewOfFile)  
4. Сдвинуть данные (Move)
5. Дописать в дырку
6. Закрыть всё


Сергей М.   (2006-03-15 14:44:00) [15]


> Созданных для одного и того же файла?


Для разных.

Ну а если и это неприемлемо, то :

SingleFileStream.ReadBuffer(before, ..); //читаешь в память все то что фигурирует в изменяемом файле ДО точки вставки

SingleFileStream.ReadBuffer(after, ..); //читаешь в память все то что фигурирует в изменяемом файле ЗА точкой вставки

SingleFileStream.Position := 0; //позиционируешь курсор в начало файла

SingleFileStream.WriteBuffer(before, ..); //пишешь из памяти все то что фигурировало в изменяемом файле ДО точки вставки

SingleFileStream.WriteBuffer(data_to_insert, ..); //пишешь то что требуется вставить в этой позиции

SingleFileStream.WriteBuffer(after, ..); //пишешь из памяти все то что должно фигурировать в измененном файле следом за только что вставленными данными


MegaVolt   (2006-03-15 14:35:00) [16]

>Он-то как раз и обеспечивается использованием двух FileStream'ов.

Созданных для одного и того же файла?
Один на чтение второй на запись?
А глюков не получится?


Сергей М.   (2006-03-15 14:25:00) [17]


> минимум памяти


Он-то как раз и обеспечивается использованием двух FileStream'ов.


MegaVolt   (2006-03-15 14:14:00) [18]

Желательно исспользовать минимум памяти и тот же физический файл. Поэтому желателен единственный FileStream


Leonid Troyanovsky   (2006-03-15 14:02:00) [19]


> MegaVolt ©   (15.03.06 13:28)  

> Как в потоке TFileStream сдвинуть данные например для того


Что, в данном случае, важно использовать:
- единственный TFileStream
- TFileStream
- Move?

--
Regards, LVT.


MBo   (2006-03-15 13:59:00) [20]

Используй второй поток.


Наверх

Титульная страница Поиск, карта сайта Написать письмо