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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 29.12.2014, 14:30   #1
Daemvil
Пользователь
 
Регистрация: 23.12.2009
Сообщений: 56
По умолчанию Сохранение двумерных массивов в TFileStream

Доброго времени суток! Помогите, пожалуйста, разобраться, столкнулся с такой проблемой:
при записи в файл через FileStream с помощью Write одним блоком всего массива, пишется белеберда. При записи колонками - пишется нормально.
Вот так не работает:
Код:
FS.Write(DataTable[0,0],RowC*ColC*SizeOf(TDataCell));
Вот так работает:
Код:
for I := Low(DataTable) to High(DataTable) do
    FS.Write(Self.DataTable[i][0],RowC*SizeOf(TDataCell));
RowC - кол-во строк,
ColC - кол-во колонок
Код:
Type
 TDataCell = Real;
 TDataArray = array of TDataCell;
 TDataTable = array of TDataArray;
var DataTable:TDataTable;
Есть подозрение, что колонки в памяти разбросаны, либо в каждой колонке указывается размер массива.
Можно ли как-то создать динамический двумерный массив, чтобы данные были "единым целым", как это сделано в одномерном массиве?
Nostra Sunt
Daemvil вне форума Ответить с цитированием
Старый 29.12.2014, 14:44   #2
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

А почему запись двойным циклом не хочешь делать?
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 29.12.2014, 15:30   #3
Daemvil
Пользователь
 
Регистрация: 23.12.2009
Сообщений: 56
По умолчанию

Цитата:
Сообщение от Stilet Посмотреть сообщение
А почему запись двойным циклом не хочешь делать?
Потому что работает не достаточно быстро, надо записывать миллионы/десятки миллионов точек
Nostra Sunt
Daemvil вне форума Ответить с цитированием
Старый 29.12.2014, 15:58   #4
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

Это массив массивов и кроме данных в нем еще метаданные о каждом из подмассивов. Так что прямо в лоб так не получится и в результату Write пишет не весь массив. И читает соответственно не правильно
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Старый 29.12.2014, 16:11   #5
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

разве что обернуть одномерный массив в "двумерный" с манипуляцией индексами.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 29.12.2014, 16:54   #6
Человек_Борща
Старожил
 
Аватар для Человек_Борща
 
Регистрация: 30.12.2009
Сообщений: 11,426
По умолчанию

Цитата:
Type
TDataCell = Real;
TDataArray = array of TDataCell;
TDataTable = array of TDataArray;
var DataTable:TDataTable;
как-то так:
Код:
function SaveTable(sFile:string; oTable:TDataTable):boolean;
var
 ss:TStringList;
 iRow,iCol,iMaxRows,iMaxCols:Integer;
 sRow:string;
begin
 ss:=TStringList.Create;
 iMaxRows := Length(oTable);
 for iRows := 0 to iMaxRows do
 begin  
   iMaxCols := Length(oTable[iRow,0]);
  for iCol := 1 to iMaxCols do
  begin
   sRow := sRow + FloatToStr(oTable[iRow,iCol]) + ',';

..
ss.add(sRow);
  end; 
 end;
 ss.SaveToFile(sFile);
 ss.Free;
end;
Думаю суть вы поняли.

По скольку TDataArray может иметь иную длину в отличии от TDataTable , то в 0-й ячейке массива TDataArray будем хранить длину TDataArray. Чтобы при переборе строк таблицы, 100% знать действительную длину строки таблицы.
Человек_Борща вне форума Ответить с цитированием
Старый 29.12.2014, 17:49   #7
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

Цитата:
разве что обернуть одномерный массив в "двумерный" с манипуляцией индексами
Код:
var DataTable: array of Real;
    RowC,ColC,i,j: Integer;
    FS: TMemoryStream;
begin
  RowC:=3; ColC:=4;
  SetLength(DataTable,RowC*ColC);
  for i:=0 to RowC-1 do
    for j:=0 to ColC-1 do
      DataTable[i*ColC+j]:=100*(i+1)+j;
  FS:=TMemoryStream.Create;
  FS.Write(DataTable[0],RowC*ColC*SizeOf(Real));

  FS.Position:=0;
  FS.Read(DataTable[0],RowC*ColC*SizeOf(Real));
  FS.Free;
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Старый 12.01.2015, 15:05   #8
Daemvil
Пользователь
 
Регистрация: 23.12.2009
Сообщений: 56
По умолчанию

Ура! Нашел способ записи такого двумерного массива!
Данные в памяти в случае массива 5х5 располагаются так:
[1 колонка: 1,2,3,4,5 строки][15 байт служебных/непонятных мне данных(СД)][2колонка:1..5 строки][15 байт СД][3колонка:1..5 строки][15 байт СД][4колонка:1..5 строки][15 байт СД][5колонка:1..5 строки]
Достаточно взять адрес последней ячейки+размер ячейки в байтах, взять адрес первой ячейки, вычислить длину данных, ну и дальше FS.Write(DataTable[0,0],...);
Кому будет интересно/полезно - сделал тестовый исследовательский пример, который заполняет массив данными типа byte, записывает массив в файл, считывает из файла.

Проект:
Arrays_2x.zip

З.Ы. Кто-нибудь знает, что это за (мета)данные между колонками? объём выделенной памяти,кол-во ссылок на массив, количество элементов в массиве, и 3 пустых байта? они иногда меняются от запуска к запуску программы при неизменных адресах ячеек.
Nostra Sunt

Последний раз редактировалось Daemvil; 12.01.2015 в 15:40.
Daemvil вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Обработка двумерных массивов C++ 803 Помощь студентам 9 18.02.2012 20:15
TStringList и TFileStream сохранение в файл MalCer Общие вопросы Delphi 2 27.12.2010 14:24
обработка двумерных массивов... Mizantrop Помощь студентам 2 25.03.2010 09:11
сохранение изображения с TFileStream andrey4623 Общие вопросы Delphi 10 20.10.2007 20:28