Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2006.04.23;
Скачать: [xml.tar.bz2];

Вниз

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

 
MegaVolt ©   (2006-03-15 13:28) [0]

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


 
MBo ©   (2006-03-15 13:59) [1]

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


 
Leonid Troyanovsky ©   (2006-03-15 14:02) [2]


> MegaVolt ©   (15.03.06 13:28)  

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


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

--
Regards, LVT.


 
MegaVolt ©   (2006-03-15 14:14) [3]

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


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


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


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


 
MegaVolt ©   (2006-03-15 14:35) [5]

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

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


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


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


Для разных.

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

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

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

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

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

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

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


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

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


 
Amoeba ©   (2006-03-15 14:47) [8]


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

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


 
Leonid Troyanovsky ©   (2006-03-15 15:28) [9]


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

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


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

--
Regards, LVT.


 
MegaVolt ©   (2006-03-15 15:28) [10]

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

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

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

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


 
MegaVolt ©   (2006-03-15 15:31) [11]

Сергей М.

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

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


 
MBo ©   (2006-03-15 15:39) [12]

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

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


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


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


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


 
Leonid Troyanovsky ©   (2006-03-15 15:44) [14]


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

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

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

--
Regards, LVT.


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

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

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

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

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

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

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


 
Leonid Troyanovsky ©   (2006-03-15 18:27) [16]


> 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 19:27) [17]

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

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


 
Leonid Troyanovsky ©   (2006-03-15 19:41) [18]


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

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


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

--
Regards, LVT.


 
MegaVolt ©   (2006-03-16 11:35) [19]

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

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


 
Leonid Troyanovsky ©   (2006-03-16 14:07) [20]


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

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


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

--
Regards, LVT.



Страницы: 1 вся ветка

Форум: "Основная";
Текущий архив: 2006.04.23;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.51 MB
Время: 0.011 c
15-1143907200
ArtemESC
2006-04-01 20:00
2006.04.23
Типа шутки штоли...


1-1142496507
Леван
2006-03-16 11:08
2006.04.23
Как найти в end, соответствующий begin-у


6-1136763104
Pasha13
2006-01-09 02:31
2006.04.23
перехват сообщений Outlooka


15-1144156383
Курдль
2006-04-04 17:13
2006.04.23
Кто нибудь имеет, что сказать про QT ?


15-1143802154
Virtual FreeBSD 4.10
2006-03-31 14:49
2006.04.23
VMWare





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский