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

Вниз

Как преместить данные в буфер не с начала?   Найти похожие ветки 

 
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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.54 MB
Время: 0.031 c
1-1081261350
killer
2004-04-06 18:22
2004.04.25
TStrings


1-1081517534
Denis_Visma
2004-04-09 17:32
2004.04.25
есть ли кого модуль для перевода текста на транслит?


1-1081332908
Bond
2004-04-07 14:15
2004.04.25
Диаграммы


1-1081342555
Ozone
2004-04-07 16:55
2004.04.25
Потоки


1-1081158128
Infernal
2004-04-05 13:42
2004.04.25
TListView и поиск





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский