Текущий архив: 2004.04.25;
Скачать: CL | DM;
Вниз
Как преместить данные в буфер не с начала? Найти похожие ветки
← →
MegaVolt © (2004-04-05 12:40) [0]функция Read класса ТFileStream определена так TFileStream.Read(var Buffer; Count: Integer): Longint;
Хотя на самом деле Buffer это скорее указатель и зачем так сделано мне не совсем понятно :(
Я пишу наследника от TFileStream и перекрываю Read своей функцией с тем же определением.
У себя в функции я заполняю Buffer значениями самостоятельно некоторыми порциями меньшими чем сам Buffer. Получается что мне нужно скопировать некоторые данные в середину Buffer. Как это можно сделать?
Я делал так:
var
m:integer; //Содержит указатель на новое место в Buffer
Cach: array[0..1023]of byte;
.............
m:=integer(pointer(Buffer))+BufPos;
move(Cach[0],m,SizeOf(Cach));
почему то не работает. Где я ошибся?
Заранее благодарен :)
← →
PVOzerski © (2004-04-05 12:51) [1]При таком использовании move содержимое массива cash будет записано не туда, куда указывает m, а туда, где эта переменная m находится, в итоге будет и она потеряна, и всё, что дальше в памяти на 1022 байта.
move(Cach[0],pointer(m)^,SizeOf(Cach));
← →
MBo © (2004-04-05 12:54) [2]ИЗ потока - read
В поток - write ;)
В хелпе еще зачем-то про Position и Seek написано.
>и зачем так сделано мне не совсем понятно
Собственно, в этом непременно нужно разобраться, для того чтобы продолжать программировать на Паскале/Дельфи.
← →
MegaVolt © (2004-04-05 13:04) [3]PVOzerski:
Выдаёт AccessViolation во время записи по тому адресу который вычислен. Даже если смещение равно 0 :(
MBo: как работать с потоком я знаю. Но если из файла вычитывать по одному байту резко падает скорость :( Поэтому я решил написать класс наследник от TFileStream который реально читает из файла по 32К а я с ним работаю как с обычным TFileStream. Если знаешь как это сделать проще напиши :)
← →
MBo © (2004-04-05 13:14) [4]>Если знаешь как это сделать проще напиши
Я не понял задачи пока
← →
Fay © (2004-04-05 13:18) [5]Блин! Вы чё всне издеваетесь!?!? Сегодня уже 5-е число!
У одних TStringList.SaveToFile У других TFileStream.Read...
А CreateFile/ReadFile/WriteFile/CloseHandle и т.д. уже отменили?
>> Если знаешь как это сделать проще напиши :)
Читать файл по 32К можно так. Под виндой - только так 8)const
BUF_SZ = 32768;
var
h : THandle;
n : Cardinal;
b : array[0..BUF_SZ-1] of Byte;
begin
h := CreateFile(PChar(MyFileName), GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, 0, 0);
ReadFile(h, b, BUF_SZ, n, nil);
if n > 0 then
repeat
.....
ReadFile(h, b, BUF_SZ, n, nil);
until n = 0;
CloseHandle(h);
end;
← →
MegaVolt © (2004-04-05 13:19) [6]Задача очень проста:
Стандартный TFileStream читает данные с максимальной скоростью если куски вычитываемых данных равны 32К почему так я не знаю :( Если вычитывать данные побайтно скорость резко падает. Можно конечно читать 32К а из него потом побайтно но как то неудобно. Поэтому я решил этот механизм запихнуть в класс и снаружи иметь всё тот же FileStream но который реально читает по 32К.
Для этого нужно заменить Read а так же Position и Seek родительского класса. Так вот я столкнулся с проблемой: в функцию Read указатель на буфер передаётся почему то как Integer. И я не могу копировать данные в буфер не с начала. А нужно копировать с некоторой позиции. Как это сделать???
← →
Verg © (2004-04-05 13:21) [7]
> Так вот я столкнулся с проблемой: в функцию Read указатель
> на буфер передаётся почему то как Integer.
Че-гоо?!
Где такое снится?
← →
MegaVolt © (2004-04-05 13:25) [8]Verg: вот цитата из D5:
TFileStream.Read(var Buffer; Count: Integer): Longint;
← →
Fay © (2004-04-05 13:28) [9]8))
← →
MBo © (2004-04-05 13:29) [10]var Buffer; Объявление закончено.
Нетипизированный параметр, при использовании вместо него ставится любая переменная, элемент массива, если указатель - то обычно РАЗЫМЕНОВАННЫЙ .
← →
Verg © (2004-04-05 13:29) [11]
> MegaVolt © (05.04.04 13:25) [8]
> Verg: вот цитата из D5:
>
> TFileStream.Read(var Buffer; Count: Integer): Longint;
Ну и? Что мы видим?
Два параметра:
1. Buffer - нетипизированная ссылка. Т.е. ссылка на что угодно
2. Count - число типа integer;
← →
Digitman © (2004-04-05 13:29) [12]
> MegaVolt © (05.04.04 13:25) [8]
запятую и точку с запятой различаешь ? после Buffer ? о чем, по-твоему говорит точка с запятой в этом месте ?
← →
MegaVolt © (2004-04-05 13:30) [13]Согласен тормознул :(
Но вопрос остался как в этот Buffer скопировать данные не с начала а с некоторой позиции?
← →
pasha_golub © (2004-04-05 13:31) [14]Nut?
← →
Fay © (2004-04-05 13:31) [15]Позиции чего???? В середину буфера, что-ли?
← →
MegaVolt © (2004-04-05 13:32) [16]Ага в середину с N-ой позиции
← →
Verg © (2004-04-05 13:33) [17]вот смотри:
procedure Proc(var B);
чтобы получить адрес того, на что ссылается B нужно сказать @B
продолжать?
← →
Fay © (2004-04-05 13:34) [18]Read(PByte(Integer(@Buf)+N)^, M);
← →
han_malign © (2004-04-05 13:35) [19]- самое простое (начиная с TP 5.0, если не раньше)
function TFileStream.Read(var Buffer; Count: Integer): Longint;
var Cach: array[0..1023]of byte absolute Buffer;
begin
...Cach[i]...
← →
MegaVolt © (2004-04-05 13:38) [20]Ага продолжай. Дальше по идее нужно адрес инкрементировать но как :( Просто добавить не даёт :(
← →
MBo © (2004-04-05 13:39) [21]>- самое простое (начиная с TP 5.0, если не раньше)
Ну уж нет - самое простое -
Stream.Read(Cach[50],DataSize)
← →
Fay © (2004-04-05 13:39) [22]Чё, прямо Inc(N) не даёт сделать?! Ай, нехорошо!
← →
Fay © (2004-04-05 13:40) [23]2MBo
Что упростилось от han_malign ?
← →
MegaVolt © (2004-04-05 13:42) [24]Заработало. :):) Действительно перевести в integer а потом сложить и обратно :):) Всем большущее спасибо :):):)
← →
Verg © (2004-04-05 13:45) [25]
> MegaVolt © (05.04.04 13:38) [20]
Ага. Значит мы должны увеличит на сколько-то указатель (адрес) на то, на что ссылается B, но мы не знаем на что оно ссылается. Поэтому мы должны определить для себя - пусть будет это некоторый массив символов или просто байт.
procedure proc(var B);
var
pB : pchar;
begin
pB := @B;
C какого байта по порядку тебе нужно прочитать? С N-ого?
Read(pB[N], Count);
или Read((pB+N)^, Count);
инкрементируем - Inc(pB, N);
.................
← →
MegaVolt © (2004-04-05 14:13) [26]Или так :)
Может за одно объяснишь почему можно исспользовать PChar для определения массивов байт т.к. если в массиве вдруг встретится 0 то PChar по идее должен понять это как окончание переменной. Почему мы это игнорируем?
← →
Fay © (2004-04-05 14:18) [27]Ничего он не должен. Это указатель.
← →
Verg © (2004-04-05 14:19) [28]
> PChar
- это тип такой. Указатель, на котором в делфи официально разрешена арифметика и индексирование.
Он сам по себе ничего "не понимает".
Можете пинать меня ногами, но преобразования указателей к integer и наоборот - порочная практика, привычка к которой вам обязательно когда-нибудь стрельнет и очень больно.
← →
Fay © (2004-04-05 14:20) [29]С какого перепугу?
← →
MegaVolt © (2004-04-05 14:21) [30]Указатель на длинную строку оканчивающуюсю нулём. А мы вдруг стали считать что это указатель на массив байт. И работать исспользую функции заточенные под PChar но с байтами. Почему же вдруг 0 перестал быть концом длинной строки?
← →
Verg © (2004-04-05 14:22) [31]
> Почему же вдруг 0 перестал быть концом длинной строки?
Потому, что мы с ним работаем не как со строкой символов, заканчивающихся нулем.
← →
Fay © (2004-04-05 14:22) [32]2MegaVolt ©
Просто поверьте. Так легче поймёте.
← →
MegaVolt © (2004-04-05 14:32) [33]Я верю и во многих местах встречал просто не совсем понимал почему такое возможно. Т.е. в одном случае 0 это конец переменной а в другом вдруг уже не конец. Получается что мы исспользуем функции которые этот 0 не анализируют? А как узнать анализирует ли функция 0 или нет? Вот например AnsiStrPos скорее всего уже нельзя будет исспользовать для поиска в массиве байт потому что он остановится на первом попавшемся нуле.
И почему принято исспользовать PChar а не array of byte? Ведь почти то же самое?
← →
Fay © (2004-04-05 14:41) [34]Блин! "Конец переменной"! Чё за порнуха?! Использовать можно хоть PApplication (хочешь - заведи себе такой). Но компилятир делфовый умеет (тупо для удобства) делать всякие штуки :
1) PChar(String) - совсем не то же , что PChar(@String)
2) String := PChar : в строке будет то же, что в лежит по адресу PChar^ вплоть до #0.
3) прочее 8)
А AnsiStrPos "думает", что ты ещё не совсем с катущек слетел (не подведи её!) и оганичивается тем, что до #0.
ЯСНО?!
← →
Verg © (2004-04-05 14:46) [35]
> Я верю и во многих местах встречал просто не совсем понимал
> почему такое возможно. Т.е. в одном случае 0 это конец переменной
> а в другом вдруг уже не конец.
Выражение "конец переменной" - это ты забудь.
Есть масса функций, которые интерпретируют область памяти, на которую указывает переменная типа pchar как массив символов, который заканчивается #0. Сама же переменная ничем не заканчивается - у нее есть размер. Т.к. это указатель, то и размер ее = sizeof(pointer).
Так же делфи интерпретирует присваивания переменной строчного типа (string) переменной типа pchar как копирование той самой области памяти вплоть до первого же #0 в ту строку с автоматическим определением ее размера.
← →
MegaVolt © (2004-04-05 15:42) [36]Спасибо :)
← →
Fay © (2004-04-05 15:43) [37]Одумался окаянный 8)
Страницы: 1 вся ветка
Текущий архив: 2004.04.25;
Скачать: CL | DM;
Память: 0.54 MB
Время: 0.024 c