Форум: "Основная";
Текущий архив: 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