Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 27.03.2009, 02:13   #1
Sergey2
Форумчанин
 
Регистрация: 08.01.2008
Сообщений: 233
По умолчанию Как использовать команды FileRead, FileOpen

Есть динамический массив. И есть фукция которая читает в него данные из файла.

var Data: array of byte;
iSize: integer;
...
SetLength(Data,iSize);
...
FileRead(iFileHandle, Data, iSize);


Получается, в целом, фигня (сыпяться волюм аксешены). Подозреваю что это из-за того что массив динамический (на самом деле там указатель на структуру, одно из полей которой динамический массив), т.е. при изменени размера он "прерывается" и не идет сплошников в памяти. Так ли это? Можно как-нить сделать так что бы не читать из файла побайтно
и копировать в массив? Может можно как-нить создать другой массив, уже после того как размер нужный известен?
Еще заметил, что при больших размерах буфера (больше 100килобайт), FileRead возвращает -1, что это значит я так и не понял. Подозреваю что из-за ограничения какого-то внутреннего буфера чтения... можно это как-нить обойти? В хелпе прочел рекомендацию юзать BlockRead для дельфей, но почему так и не понял. Мне FileRead нужен из-за того что позволяет позиционироваться в файле.

И еще в догонку... Как создать файл командой FileOpen? В документации сказано что нужен параметр fmCreate, типа создастся и все нормально будет, но в реальности файл не создаеться, вместо хендла озвпращается -1 и хз из-за чего.
Sergey2 вне форума Ответить с цитированием
Старый 27.03.2009, 09:21   #2
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

крайне рекомендую разобраться с TFileStream
там есть всё, что Вам нужно. (и даже чуть больше

а по поводу чтения в динамический массив - так НЕ ЧИТАЙТЕ в динамический! На крайний случай:
Код:
procedure TForm1.Button1Click(Sender: TObject);
type
  MyArray = array[1..1000000] of byte;
  PMyArray = ^MyArray; 

var
   pArr : PMyArray;
   FS   : TFileStream;
   i, WhatSize : integer;
   s : string;
begin
  new(pArr);

    //   ... тут работа с массивом на миллион байт
    // код ниже просто как иллюстрация!

    FS := TFileStream.Create('C:\Delphi5\Projects\Project1.dpr', fmOpenRead );
    WhatSize := FS.Size;
    FS.ReadBuffer( pArr^,WhatSize);
    FS.Free;

    s := '';
    for i:=1 to 100 do
     s := s + chr(pArr^[i]);
    Application.MessageBox(PChar(s),'Отладка', MB_OK); 
  Dispose(pArr);
end;
хотя я лично глубоко убеждён, что Ваше желание работать именно с динамическим массивом оттого, что Вы не понимаете что и как Вы хотите сделать!
Меняйте алгоритм обработки данных!
Serge_Bliznykov вне форума Ответить с цитированием
Старый 27.03.2009, 09:32   #3
BOBAH13
Android Developer
Старожил Подтвердите свой е-майл
 
Аватар для BOBAH13
 
Регистрация: 19.02.2007
Сообщений: 3,708
По умолчанию

Эмм.. зачем же... вот

Код:
var Data: array of byte;
iSize: integer;
...
SetLength(Data,iSize);
...
FileRead(iFileHandle, Data[0], iSize);
или же
Код:
FileRead(iFileHandle, Pointer(Data)^, iSize);
BOBAH13 вне форума Ответить с цитированием
Старый 27.03.2009, 09:57   #4
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

Код:
Цитата:
FileRead(iFileHandle, Data[0], iSize);
BOBAH13, Вы, безусловно правы, коллега!!!
Это я просмотрел...

p.s. хотя я всё равно уверен, что динамические массивы — это зло, потеря производительности и потенциальная возможность всяких глюков...
хотя... если алгоритм этого требует...
Serge_Bliznykov вне форума Ответить с цитированием
Старый 31.03.2009, 00:35   #5
Sergey2
Форумчанин
 
Регистрация: 08.01.2008
Сообщений: 233
По умолчанию

Так это... сами то динамические масивы отличаются в работе от статических? Попрбовал сегодня посоздавать их и пробежаться по адресам элементов - вроде все подряд идут. Или это просто "так склалось", а вообще не факт?
Про скорость знаю, но она тут не главное. А как еще делать, когда неизвестен объем данных, которые предстоит "набрать" в массив?
Sergey2 вне форума Ответить с цитированием
Старый 31.03.2009, 01:43   #6
Ntlegend
Форумчанин
 
Аватар для Ntlegend
 
Регистрация: 12.05.2007
Сообщений: 373
По умолчанию

Динамические массивы отличаються тем что их размер можна изменить в любое время (что более удобно с точчки зрения высвобождения ресурсов)..
и еще их отличие в том что они занимають последние байты в оперативной памяти программы, в то время как статический массив может быть в любом месте..
Цитата:
А как еще делать, когда неизвестен объем данных, которые предстоит "набрать" в массив?
можна использовать ссылку на память (Pointer)..
узнаешь требуемое место, выделяешь память, помещаешь туда данные.. копируешь от туда данные, чистишь за собою..
Перемен! - требуют наши сердца. Перемен! - требуют наши глаза.
В нашем смехе и в наших слезах, И в пульсации вен:
"Перемен!Мы ждем перемен!"
Ntlegend вне форума Ответить с цитированием
Старый 31.03.2009, 01:51   #7
Sergey2
Форумчанин
 
Регистрация: 08.01.2008
Сообщений: 233
По умолчанию

Цитата:
Сообщение от Ntlegend Посмотреть сообщение
Динамические массивы отличаються тем что их размер можна изменить в любое время (что более удобно с точчки зрения высвобождения ресурсов)..
Это я знаю
Цитата:
и еще их отличие в том что они занимають последние байты в оперативной памяти программы, в то время как статический массив может быть в любом месте..
Хм... а в чем это отражается на кокретной работе с ними? Перелопатил весь инет на тему "статические и динамические массивы". Нашел как это все работает с точки зрения процессора, не нашел только одного - динамический масив всегда непрерывный или нет? Т.е. если я указатель тыкну на первый элемент, смогу я по массиву бегать инкрементируя указатель или можно "добегаться"?
Цитата:
можна использовать ссылку на память (Pointer)..
узнаешь требуемое место, выделяешь память, помещаешь туда данные.. копируешь от туда данные, чистишь за собою..
Да это понятно, но динамический массив, по сути, так и работает, т.е. я ничего не выигрываю по сравнению с динамическим массивом....
Sergey2 вне форума Ответить с цитированием
Старый 31.03.2009, 02:49   #8
Ntlegend
Форумчанин
 
Аватар для Ntlegend
 
Регистрация: 12.05.2007
Сообщений: 373
По умолчанию

Цитата:
динамический масив всегда непрерывный или нет?Т.е. если я указатель тыкну на первый элемент, смогу я по массиву бегать инкрементируя указатель или можно "добегаться"?
Да, он непрерывный, можешь спокойно передвигаться.. единственное за чем нада следить это чтобы не выйти за пределы массива, иначе в программе начнуться "сбои памяти"..

Цитата:
Цитата:
и еще их отличие в том что они занимають последние байты в оперативной памяти программы, в то время как статический массив может быть в любом месте..
Хм... а в чем это отражается на кокретной работе с ними?
это влияет лишь на то что динамический массив не коим образом не может "испортить" данные программы.. он находится в конце, и к нему легко "пристыковать" еще пару байт..
если бы динамический массив бил в середине программы или в начале то или бы он имел какието ограничения, или же портил данные программы (заголовки форм, надписи элементов и т.д.)
Перемен! - требуют наши сердца. Перемен! - требуют наши глаза.
В нашем смехе и в наших слезах, И в пульсации вен:
"Перемен!Мы ждем перемен!"
Ntlegend вне форума Ответить с цитированием
Старый 31.03.2009, 04:33   #9
Jeni
Форумчанин
 
Регистрация: 31.05.2007
Сообщений: 486
По умолчанию

Цитата:
Сообщение от Sergey2 Посмотреть сообщение
динамический масив всегда непрерывный или нет?
Если одномерный, то разницы со статическим нет никакой, а вот если многомерный, то понятие непрерывности применимо только к одному "измерению". Например, статический двумерный массив array[1..100, 1..100] of Integer будет целиком размещаться непрерывно и занимать 100х100х4=40000 байт (или 80000, в зависимости от параметров выравнивания) - по нему можно "ходить вручную" с помощью указателя. А вот динамический array of array of Integer не обязательно ляжет сплошным куском, это будет зависеть от того, как он создается, ведь такой массив не обязательно должен быть "прямоугольным". В любом случае непрерывно разместиться только первый "ряд" - его элементы будут содержать указатели на массивы "второго измерения", а уж где они разместятся...
В общем, можно пройтись по "первому измерению", можно - по "второму" (отдельно по каждой строке), но невозможно пройти от начала до конца, как при статическом массиве.

Цитата:
Сообщение от Ntlegend Посмотреть сообщение
...динамический массив не коим образом не может "испортить" данные программы.. он находится в конце, и к нему легко "пристыковать" еще пару байт... если бы динамический массив бил в середине программы или в начале то или бы он имел какието ограничения, или же портил данные программы (заголовки форм, надписи элементов и т.д.)
Да как динамический массив вообще может находиться "внутри" программы? Он размещается в куче! Как и где там что-то размещать, решает менеджер кучи, а место для самой кучи выделяется системным менеджером памяти.
Jeni вне форума Ответить с цитированием
Старый 31.03.2009, 13:52   #10
BOBAH13
Android Developer
Старожил Подтвердите свой е-майл
 
Аватар для BOBAH13
 
Регистрация: 19.02.2007
Сообщений: 3,708
По умолчанию

Боже мой... ребят, о чем вы ? Навыдумавали черт знает что
Вот вам динамический массив

Код:
var p: Pointer = NIL;

procedure SetLength(var p: Pointer; Len: Integer);
begin
  if (Len = 0) then
  begin
    if Assigned(p) then
    begin
      FreeMem(p);
      p := NIL;
    end;
  end else
    ReAllocMem(p, Len * SizeOf(Integer);
end;

function GetElement(p: Pointer; const Index: Integer): PInteger;
begin
  Result := Pointer(Integer(p) + Index * SizeOf(Integer));
end;

function GetElement(p: Pointer; const Width, X, Y: Integer): PInteger;
begin
  Result := Pointer(Integer(p) + (Y * Width + X) * SizeOf(Integer));
end;
Ну так на быструю руку... чтобы поняли в чем "фишка"
BOBAH13 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Как использовать скины SeRhy Компоненты Delphi 10 06.11.2010 00:23
как использовать указатель this z3rg Общие вопросы C/C++ 2 16.03.2009 23:28
Как сохранить файл чтобы пропали все команды, Rashanea Microsoft Office Excel 2 27.11.2008 22:43
Как использовать png Sanek777 Общие вопросы Delphi 1 25.09.2008 20:14