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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 26.06.2016, 17:08   #1
mahatmaQL
Пользователь
 
Регистрация: 02.04.2014
Сообщений: 18
По умолчанию считывание двумерного массива из потока данных

Добрый день!
Помогите разобраться со считыванием двумерного массива из потока данных. Построчно массив получается считать, а целиком нет. Что я делаю не так?

Код:
type
  TRad2 = array of array of word;
var
  Rad2: TRad2;
{....}
begin
  SetLength(Rad2,nrows,ncols);
  FS:= TFileStream.Create(fname, fmOpenRead, fmShareDenyWrite);
  try
    FS.Seek(offset,soFromBeginning);
    size:=ncols*nrows*2;
    // построчно получается считать массив
    for i:=Low(Rad2) to High(Rad2) do
    FS.Read(Pointer(Rad2[i])^, ncols*2);
   // целиком не получается
   //FS.Read(Pointer(Rad2)^, size);
   //FS.Read(Pointer(Rad2[0])^, size);
   //FS.Read(Pointer(Rad2[0,0])^, size);
  finally
    FreeAndNil(FS);
  end;
end;
mahatmaQL вне форума Ответить с цитированием
Старый 26.06.2016, 17:44   #2
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,238
По умолчанию

а если так?
Код:
type
  TRad2 = array of word;
...
  size:=ncols*nrows*2;
  SetLength(Rad2,size);
  FS:= TFileStream.Create(fname, fmOpenRead, fmShareDenyWrite);
  try
    FS.Seek(offset,soFromBeginning);
   // целиком 
   FS.Read(Rad2[0], size);
А чем Вас не устраивает чтение построчно, если не секрет?
Serge_Bliznykov вне форума Ответить с цитированием
Старый 26.06.2016, 18:47   #3
mahatmaQL
Пользователь
 
Регистрация: 02.04.2014
Сообщений: 18
По умолчанию

Serge_Bliznykov,
спасибо за совет!

Считывание по строкам меня устраивает, даже больше подходит. Просто хотелось разобраться почему не получается (или это нельзя сделать) считать двумерный массив.

Исходно двумерный массив описывался типом:
Код:
type
  TRows=record // строка
     F1: array [0..7890] word; // массив столбцов
  end;
  TRad=array of TRows; // массив строк
и этот массив у меня благополучно считывался из потока
Код:
var Rad:TRad;
{.....} 
FS.Read(Pointer(Rad)^, size)
Но потом я решил поле F1 задавать динамически. И после этого считать запись уже не получилось.

Код:
type
  TRows=record
     F1: array of word;
  end;
  TRad=array of TRows;
var
  Rad: TRad;
{.....} // nrows - число строк, ncols - число столбцов
  SetLength(Rad,nrows);
  for i:=0 to nrows-1 do
  SetLength(Rad[i].F1,ncols);
{...} // считывание из потока
  size:=ncols*nrows*2;
  // nnn:=FS.Read(Pointer(Rad)^, size); 
  //ShowMessage(IntToStr(nnn)); {дает nnn=0}
  // nnn:=FS.Read(Pointer(Rad[0])^, size); 
  //ShowMessage(IntToStr(nnn)); {дает nnn=0}
Подскажите, как правильно нужно было считывать в Rad: TRad
mahatmaQL вне форума Ответить с цитированием
Старый 26.06.2016, 20:21   #4
min@y™
Цифровой кот
Старожил
 
Аватар для min@y™
 
Регистрация: 29.08.2014
Сообщений: 7,656
По умолчанию

Цитата:
Просто хотелось разобраться почему не получается (или это нельзя сделать) считать двумерный массив.
Потому что двумерный дин. массив - это одномерный массив указателей! Поэтому данные, (строки двумерного массива):
а) могут быть разной длины;
б) разбросаны по памяти так, как это взбрело в голову менеджеру памяти в данный момент, но единым куском - никогда!
Именно поэтому сохранять и читать массивы такого типа надо только построчно, причём количество строк и длину каждой строки можно нужно хранить в том же файле.
Расскажу я вам, дружочки, как выращивать грибочки: нужно в поле утром рано сдвинуть два куска урана...
min@y™ вне форума Ответить с цитированием
Старый 26.06.2016, 20:50   #5
mahatmaQL
Пользователь
 
Регистрация: 02.04.2014
Сообщений: 18
По умолчанию

min@y™,
спасибо, я понял.

Значит в случае с записью считывание должно быть

Код:
for i:=Low(Rad) to High(Rad) do
FS.Read(Pointer(Rad[i].F1)^, ncols*2);
mahatmaQL вне форума Ответить с цитированием
Старый 26.06.2016, 20:55   #6
min@y™
Цифровой кот
Старожил
 
Аватар для min@y™
 
Регистрация: 29.08.2014
Сообщений: 7,656
По умолчанию

Я бы не так сделал.
Давно практикую такой подход: обернуть массив классом и написать методы/свойства доступа к данным массива, размерам, загрузки, сохранения и тыды...

чего и тебе советую. В твоём случае можно написать потомка от TList.
Расскажу я вам, дружочки, как выращивать грибочки: нужно в поле утром рано сдвинуть два куска урана...

Последний раз редактировалось min@y™; 26.06.2016 в 21:01.
min@y™ вне форума Ответить с цитированием
Ответ


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

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Считывание двумерного массива из textbox (C# WPF) Mmarc Помощь студентам 0 02.07.2013 13:21
Как обнулить элементы строки двумерного массива, содержащей наибольшее количество элементов одномерного массива griignat Помощь студентам 1 22.11.2011 20:04
Изменение двумерного массива с сохранением всех данных. Vova777 Общие вопросы Delphi 10 03.09.2011 20:39
Считывание данных из строкового массива exe NiKiToZZ- Помощь студентам 0 08.01.2011 18:21
Считывание данных массива в число monty "2" Общие вопросы Delphi 20 28.11.2009 18:53