Форум: "Основная";
Текущий архив: 2003.03.27;
Скачать: [xml.tar.bz2];
ВнизПроблема с TMemoryStream!!! Найти похожие ветки
← →
Сергей (2003-03-14 16:25) [0]При записи в поток TMemoryStream методом writeBufer возникает ошибка "Out of memory while expanding memory stream". Запись в поток осуществляется в цикле
For i:=1 to N do
begin
TMemoryStream.writebuffer(x,Sizeof(x));
end;
Число N равно 150-200 тыс.
Данных где-то около 40-50Мб.
Что можно сделать, чтобы ошибки не возникало. Заранее спасибо.
← →
Smithson (2003-03-14 16:31) [1]Что значит Out of memory?
← →
Anatoly Podgoretsky (2003-03-14 16:38) [2]А что значит Sizeof(x)
← →
Сергей (2003-03-14 16:42) [3]re: Что значит Out of memory?
Это типа не хватает памяти, а вообще в тексте приведен текст ошибки.
← →
theodor_iv (2003-03-14 16:52) [4]Тебе изначально зачем две копии одних и тех же данных в оперативной памяти, да еще по 50 мегабайт каждая?
← →
Digitman (2003-03-14 16:54) [5]зачем реально может понадобиться в памяти поток такого большого размера - ума не приложу
← →
Сергей (2003-03-14 16:55) [6]theodor_iv © : Данные пишутся из массива в поток, а затем записываюся в файл.
← →
Anatoly Podgoretsky (2003-03-14 16:56) [7]Ну так все таки, чего молчишь про Sizeof(x)
← →
theodor_iv (2003-03-14 16:57) [8]Я так и думал... А почему нельзя их сразу записать в TFileStream?
← →
Сергей (2003-03-14 16:59) [9]Digitman ©: Сначала данные из текстового файла пишуться в динамический массив, а далее, чтобы каждый раз не загружать эти данные из текстового файла (потому что очень долго), я хочу их записывать в своем формате, в двоичном файле. Загрузка такого файла осуществляется гораздо быстрее. Вот.
← →
Anatoly Podgoretsky (2003-03-14 17:01) [10]Пока ты не скажешь про Sizeof(x) тебе никто не сможет ответить, но есть подозрение что это много.
← →
Сергей (2003-03-14 17:02) [11]Sizeof(x) Вычисляет размер буфера для одного элемента массива, ну правильнее будет Sizeof(x[i])
← →
kDenis (2003-03-14 17:03) [12]
> Сергей
Ну напиши ты просто:
TMemoryStream.writebuffer(x,Sizeof(x));
Без всяких цыклов...
> Anatoly Podgoretsky ©
> theodor_iv ©
Хватит издиватся над человеком!
← →
Digitman (2003-03-14 17:05) [13]
> Сергей
ну и что ?
что мешает выполнить в цикле "прямую" цепочку :
InFileStream (текст) -> нужное преобразование фрагмента -> OutFileStream(бинарный формат)
?
← →
Anatoly Podgoretsky (2003-03-14 17:07) [14]Сергей (14.03.03 17:02)
Да не что он вычитает, а сколько возвращает в твоем случае
← →
Сергей (2003-03-14 17:10) [15]Без всяких цыклов...
Не получиться, потому, что размер динамического массива функцией sizeOF не вычисляется.
← →
Anatoly Podgoretsky (2003-03-14 17:10) [16]Сергей (14.03.03 17:02)
Да и раз ты уже изменил показания, то давай новый правильный код со всеми данными
kDenis © (14.03.03 17:03)
Я очень сожалею по поводу твоего негодования, но ничем не могу помочь, только автор вопроса может ответить о размере X удобным ему способом. Мы же в отличии от тебя не телепаты
← →
theodor_iv (2003-03-14 17:10) [17]
> kDenis ©
Кто здесь издЕвается -- так это ты... А мы помочь пытаемся, хотя и разными методами :)
> Сергей
Моя мысль вполне здравая -- зачем записывать динамический массив из оперативной памяти в оперативную память, а потом в файл, если можно записать сразу в файл и сэкономить 50 мег оперативки?
← →
Anatoly Podgoretsky (2003-03-14 17:11) [18]theodor_iv © (14.03.03 17:10)
Если твое предположение насчет 50 иб верное, то встает вопрос, а где взять 10 терабайт
← →
theodor_iv (2003-03-14 17:14) [19]
> Anatoly Podgoretsky ©
Я так понял, что под фразой
> Данных где-то около 40-50Мб.
понимался суммарный объем, а не объем одного Х.
← →
Сергей (2003-03-14 17:14) [20]Anatoly Podgoretsky © (14.03.03 17:07):
Дело в том, что я написал немного упрощенно. x[i] - динамический массив записей. Каждая запись в свою очередь содержит динамические структуры.
Ну короче у меня получается загрузка и запись данных для объемов
5-10 мБ. Когда я использую входные текстовые данные больших размеров возникает эта ошибка.
← →
Сергей (2003-03-14 17:15) [21]theodor_iv © (14.03.03 17:14): Все правильно понимаете
← →
Anatoly Podgoretsky (2003-03-14 17:18) [22]Давай правильный код и размеры, иначе не ответить, но если у тебя 10иб, то посчитай сам 200 000 * 10 000 000, то это 10 терабайт, а виндоус поддерживает жля пользователя только 2 гигабайта виртуальной памяти в одном процессе.
← →
theodor_iv (2003-03-14 17:23) [23]
> Сергей (14.03.03 17:15)
> theodor_iv © (14.03.03 17:14): Все правильно понимаете
Для того, чтобы создать такой поток, операционке нужно выделить более 50 мегабайт оперативной памяти одним непрерывным блоком, что является для нее нетривиальной задачей. :)
На мой взгляд, единственный выход -- писать сразу в TFileStream, можно еще в сочетании с TCompressionStream.
← →
Сергей (2003-03-14 17:25) [24]Anatoly Podgoretsky © (14.03.03 17:18): Какие 10иб, кто это сказал? привожу код.
//Сохранение полигона в файл
procedure SavePolygon(Stream : TMemoryStream;Pol: TPolygon);
var SizePol: integer;
begin
SizePol:= Length(POl);
Stream.WriteBuffer(SizePol,SizeOf(Integer));//Пишем длину
Stream.WriteBuffer(PChar(POl)^,SizePol*SizeOf(TPoints));
end;
end;
//Сохранение свойств полигона
procedure TProjection.SavePolygonProp1(Stream : TMemoryStream;Prop: TPropPolygon);
var SizePol: LongInt;
begin
SizePol:= SizeOf(Prop);
Stream.WriteBuffer(Prop,SizePol);
end;
//Сохранение слоя в файл
procedure TProjection.SaveLayer1(Stream:TMemoryStream;L: TLayer);
var amPolygon: dword; //Число полигонов в слое
i: integer;
begin
amPolygon:=length(L.DataP);
Stream.WriteBuffer(amPolygon,SizeOf(amPolyGon));
for i:=1 to amPolygon do
begin
SavePolygon1(stream,L.DataP[i-1]);
SavePolygonProp1(stream,l.PolProp[i-1]);
end;
Stream.WriteBuffer(L.names,SizeOf(L.names));
Stream.WriteBuffer(L.vis,SizeOf(L.Vis));
end;
strm.SaveToFile(SaveDialog1.FileName);
← →
Anatoly Podgoretsky (2003-03-14 17:37) [25]Абсолютно другой код, чем в 16:25
Но точно также неясно насчет размеров записываемых элементов
Говорите точно сколько вам вешать, в байтах, память все таки.
Если не знаешь точно, то поступи так,
заведи переменную X
перед каждым Stream.WriteBuffer делай
X := X + размер;
Label1.Caption := IntToStr(X);
//Label2.Caption := IntToStr(I);
Application.ProcessMessages;
И узнаешь правду, до этого убедись, что на диске со своп файлом есть по крайней мере свободных 2 гб
← →
Digitman (2003-03-14 17:45) [26]вот ты ответь на простой вопрос - нахрена (!!) писать данные в память, когда в результате они тут же пишутся строчкой strm.SaveToFile(SaveDialog1.FileName); в файл ?? безо всякой промежуточной обработки ?? почему сразу не писать в FileStream ??
← →
theodor_iv (2003-03-14 17:49) [27]
> Digitman © (14.03.03 17:45)
нахрена (!!) писать данные в память
Видимо, какую-то тайную цель преследует. Я тут уже об этом четыре раза сказал, но ответа не получил.
← →
Anatoly Podgoretsky (2003-03-14 17:55) [28]А я не получил ответа о размере данных, в тоже время жалоба на нехватку оной. Но может если проведет отладку по указанному сценарию то все таки сообщит.
← →
Serginio (2003-03-14 20:35) [29]У меня при размере > 80 000*4 байт поэтому для записи больших данных создал свой стрим основанный на массиве больших блоков памяти. А вообще то проблема с реалоками во всех объектах которые используют непрерывную память (TList,TStringList..) если хочешь вышлю.
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2003.03.27;
Скачать: [xml.tar.bz2];
Память: 0.51 MB
Время: 0.007 c