Форум: "Основная";
Текущий архив: 2005.08.28;
Скачать: [xml.tar.bz2];
ВнизПомогите новичку. Как массивы символов складывать.... Найти похожие ветки
← →
Senti © (2005-08-07 13:58) [0]Задача такая.
Мне приходят данные, которые записываются в Array [1..8192] of Char
Необходимо эти данные каждый раз добавлять в буфер, пока буфер не достигнет значения 200 кб, затем записывать на диск.
Все казалось бы просто. Но вот совсем глупый вопрос... Как новые данные добавлять в конец буфера и какой тип буфера должен быть Array of char ?
Я решил задачу, но это решение из рук вон плохое. Привожу выдержку из кода.
(s - глобальная переменная string, я использовал ее как буфер, Count - величина полученных данных : integer)m : Array [1..8192] of char;
ts : string;
begin
s:=m; SetLength(s,Count);
ts := ts + s;
end;
Вот решение, далеко не лучше и не быстрое. Слишком много операций производиться лишних. Задача стоит как можно быстрей сохранять данные в буфер.
Простите за ламерский вопрос....
← →
Senti © (2005-08-07 14:01) [1]
m : Array [1..8192] of char;
ts : string;
begin
ts:=m; SetLength(ts,Count);
s := s + ts;
end;
Я просто перепутал переменные, когда писал :)
← →
begin...end © (2005-08-07 14:07) [2]Приходят данные, каждый раз блоками по 8192 байта. Их нужно записывать в буфер, максимальный размер которого -- 200 КБ, т.е. в буфер может поместиться ровно 200 * 1024 / 8192 = 25 таких блоков данных. Так? Если да, то, может быть, сделать буфер фиксированного размера (200 КБ), и записывать приходящие данные в нужное место буфера?
← →
Mx © (2005-08-07 14:07) [3]Заведи статический буфер на 200Кб, запоминай в какую позицию "сувать" новые данные, перемещай их Move"ом. Примерно так:
const
MyBytesSize = 8192;
type
TMyBytes = array[1..MyBytesSize] of Char;
var
Buf: array[0..204799] of Char;
P: Cardinal = 0;
procedure WriteMyBytes(M: TMyBytes);
begin
Move(M, Pointer(Cardinal(@Buf) + P)^, MyBytesSize);
Inc(P, MyBytesSize);
end;
← →
begin...end © (2005-08-07 14:19) [4]> Senti
type
TDataBlock = array [1..8192] of Char;
var
Buffer: array [1..25] of TDataBlock;
I: Integer;
begin
I := 1;
while нужно_получать_данные do
begin
Запись_очередного_блока_данных_в_элемент_Buffer[I];
// Если I = 25 (т.е. заполнен уже весь буфер)...
if I = 25 then
begin
Запись_всего_массива_Buffer_на_диск;
// Сбрасываем I, чтобы следующий блок данных
// записывать в начало буфера
I := 1
end
// ...иначе просто увеличиваем I для подготовки
// записи в следующий элемент массива Buffer
else
Inc(I)
end
end.
← →
Senti © (2005-08-07 14:23) [5]Спасибо, понял... Я использую count, т.к. размер полученных данных может быть и меньше 8192. Каждый раз они считаются при получении.
А проверить на размер наверно можно такif P + Count > 204799 then
begin
fs.write(....) // запись на диск;
Buf:=nil;
P:=0;
Move(M, Pointer(Cardinal(@Buf) + P)^, Count);
Inc(P, Count);
end;
Кстати не быстрей использовать не Array of Char, а Array of byte ?
← →
Alexander Panov © (2005-08-07 14:24) [6]Для таких задач, если не ограничены условия, можно использовать TStream(TMemorySTream). Довольно удобно.
Применрно так:const
MaxLen=1024*200;
var
MS: TMemorySTream;
FS: TFileStream;
...
MS := TMemoryStream.CReate;
...
procedure GetBufer;
var
m: array[0..8191] of Char;
Counter: Integer;
Len: Integer;
begin
//Здесь заполняется m
//и запоминается длина данных
//
if MS.Size+Couner>=MaxLen then
begin
Len := MaxLen-MS.Size;
MS.Write(m[0],Len);
FS := TFileStream.Create("ИмяФайла",fmOpenReadWrite);
try
MS.Position := 0;
FS.CopyFrom(MS,MS.Size);
finally
FS.Free;
end;
MS.Size := 0;
MS.Write(m[0],Counter-Len);
end
else MS.Write(m[0],Counter);
end;
← →
Senti © (2005-08-07 14:27) [7]>begin...end, да спасибо... Можно и так решить проблему. Но какие операции быстрее всего совершаются
Move(M, Pointer(Cardinal(@Buf) + P)^, Count) намного быстрее чем работа со строкой.
← →
Senti © (2005-08-07 14:30) [8]Да я знаю что можно использовать MemoryStream, но это замедляет работу программы и получения данных. При использование буфера в виде строки или массива символов скорость возрастает в разы. Тестировал вчера и с MemoryStream, с последующей записью в FileStream и запись с буфера (string) в FileStream.
При аналогичном коде с MemoryStream время на получение одних и тех же данных возрастало в 1,5 раза.
← →
begin...end © (2005-08-07 14:31) [9]> Senti © (07.08.05 14:27) [7]
> Move(M, Pointer(Cardinal(@Buf) + P)^, Count) намного
> быстрее чем работа со строкой.
В приведённом мной коде нет работы со строкой.
← →
Senti © (2005-08-07 14:36) [10]А если не сложно поясните почему при записи в FileStream
используют вот такой синтаксис:
Есть строка с данными s : string;
а запись идет так fs.Write(s[1], Length(s));
Почему именно s[1] ?
и как можно записать буфер из array of char напрямую, без преобразования в строку ?
fs.Write(m[1], P) (Где M Array [1..204799] of char, и P размер буфера) ???? так или нет ?
← →
Senti © (2005-08-07 14:38) [11]Просите за не вежество....
← →
Mx © (2005-08-07 14:45) [12]
> Senti © (07.08.05 14:36) [10]
> и как можно записать буфер из array of char напрямую, без
> преобразования в строку ?
> Где M Array [1..204799] of char, и P размер буфера
fs.Write(M, P)
> а запись идет так fs.Write(s[1], Length(s));
Потому как сама строка - указатель, если просто S, то запишется указатель, а иначе данные на которые он указывает. Я лично пишу Pointer(S)^. Меня поправят, если это не одно и тоже.
← →
Alexander Panov © (2005-08-07 14:48) [13]Senti © (07.08.05 14:36) [10]
А если не сложно поясните почему при записи в FileStream
используют вот такой синтаксис:
Есть строка с данными s : string;
а запись идет так fs.Write(s[1], Length(s));
Почему именно s[1] ?
Потому что в параметрах многих процедур и функции необходим указатель на начало буфера.
s[1] указывает на певый символ в строкею
Senti © (07.08.05 14:36) [10]
и как можно записать буфер из array of char напрямую, без преобразования в строку ?
fs.Write(m[1], P) (Где M Array [1..204799] of char, и P размер буфера) ???? так или нет ?
Именно так.
если бы первый индекс массива был 0, то нужно было бы написать fs.Write(m[0], P)
← →
Senti © (2005-08-07 14:48) [14]Большое спасибо. Т.е. получается s[1] ссылка на сами данные ? А почему именно [1] ? :)
← →
Senti © (2005-08-07 14:49) [15]Alexander Panov > Спасибо за развернутый ответ... Когда писал предыдущий пост, вы уже ответили.
← →
Senti © (2005-08-07 14:51) [16]Наконец я со всем разобрался!
СПАСИБО ВСЕМ ЗА ПОМОЩЬ !!!
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2005.08.28;
Скачать: [xml.tar.bz2];
Память: 0.49 MB
Время: 0.039 c