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

Вниз

Глюки с записями   Найти похожие ветки 

 
Ramzes   (2004-04-10 23:50) [0]

У меня есть база, чтобы меньше занимала памяти я определяю размер записи, пишу в файл smallint а потом саму запись. Таким образом я забиваю файл нужными мне записями.
Дальше я другой прогой открываю файлик, читаю smallint с размером, читаю прочитанное количество байтов в запись и тут облом!
Запись не фурычит! Может данные на нее передались, но у меня там access violation! Что мне делать? А вдруг smallint динамическая переменная, из-за этого происходит сдвиг? Скажите в чем может быть проблема, очень нуждаюсь в вашей помощи...


 
DrPass ©   (2004-04-11 00:01) [1]

Раз ты хочешь, чтобы мы телепатически угадывали, что ты там написал, придется угадывать...
1. Ты используешь blockread/blockwrite
2. Ты открываешь файл reset(f), rewrite(f)
3. Ты не знаешь, что по умолчанию blockread/blockwrite пишут 128-байтными блоками
4. И ты не знаешь, что для побайтной записи нужно открывать файл reset(f,1), rewrite(f,1)
Но это всего лишь гипотеза, так себе...


 
Ramzes   (2004-04-11 00:09) [2]

Нет, я пишу через TFileStream.


 
Jack128 ©   (2004-04-11 00:18) [3]

код давай..Телепаты в отпуске


 
Ramzes   (2004-04-11 00:22) [4]

 TFileRec = packed Record
   Path:string;
   Filename:string;
   Attr:integer;
   size:integer;
   ChTime:integer;
 end;

procedure read;
var
f:tfilestream;
sz:smallint;
rec:tfilerec;
begin
f:=tfilestream.Create("test.idb",fmOpenRead,fmShareDenyWrite);
while f.Position < f.Size do
 begin
 f.Read(sz,sizeof(sz));
 f.Read(rec,sz);
 if rec.Filename = edit1.Text then memo1.Lines.Add(rec.Path+rec.Filename);
 Progressbar1.Position:= round(f.Position * 100 / f.Size);
 end;
end;

procedure save;
var
sz:smallint;
i:integer;
f:tfilestream;
begin
f:=tfilestream.Create(form1.Edit3.Text+".idb",fmCreate,fmShareExclusive);
for i:= 0 to flz.Count-1 do
 begin
 sz:=sizeof(tfilerec(flz[i]^)); // flz - TList записей TFileRec
 f.Write(sz,sizeof(sz));
 f.Write(tfilerec(flz[i]^),sz);
 end;
f.Free;
end;


 
Jack128 ©   (2004-04-11 00:33) [5]

Ну вот, все сразу понятно стало..
var
 f: TFileStream;
 FileRec: TFileRec;
begin
 ...
 f.Write(FileRec, SizeOf(FileRec)); // Так как в TFileRec есть длинные строки, которые есть суть указатели(!!!!!), то в файл будут записаны эти самые указатели.. Естественно при загрузке будет AV
end;

Записывать _длинные_ строки нужно примерно так
procedure SaveString(Stream: TStream; const s: string);
begin
 Stream.WriteBuffer(Length(s), SizeOf(Integer));
 Stream.WriteBuffer(PChar(s)^, Length(s));
end;


 
Ramzes   (2004-04-11 00:40) [6]

А как мне через запись(record) это реализовать? т.е. Может можно написать чтоб string он воспринимал как не указатель, а как сами данные? Может PChar использовать?


 
Fay ©   (2004-04-11 05:26) [7]

А PChar, случайно, не указатель? 8)
Попробуй фиксированный размер строки. Типа string[100], или типа array[0..888] of Char.


 
Jack128 ©   (2004-04-11 11:33) [8]

type
TFileRec = packed Record
  Path:string;
  Filename:string;
  Attr:integer;
  size:integer;
  ChTime:integer;
end;

procedure WriteString(Stream: TStream; const s: string);
begin
Stream.WriteBuffer(Length(s), SizeOf(Integer));
Stream.WriteBuffer(PChar(s)^, Length(s));
end;

procedure WriteFileRec(Stream: TStream; const FileRec: TFileRec);
begin
 WriteString(Stream, FileRec.Path);
 WriteString(Stream, FileRec.Filename);
 Stream.WriteBuffer(Filerec.Attr, SizeOf(Integer));
 Stream.WriteBuffer(Filerec.Size, SizeOf(Integer));
 Stream.WriteBuffer(Filerec.ChTime, SizeOf(Integer));
end;

function ReadString(Stream: TStream): string;
var
 len: Integer;
begin
 Stream.ReadBuffer(len, SizeOf(Integer));
 SetLength(Result, len);
 Stream.ReadBuffer(PChar(Result)^, len);
end;

function ReadFileRec(Stream: TStream): TFileRec;
begin
 Result.Path := ReadString(Stream);
 Result.Filename := ReadString(Stream);
 Stream.ReadBuffer(Result.Attr, SizeOf(Integer));
 Stream.ReadBuffer(Result.Size, SizeOf(Integer));
 Stream.ReadBuffer(Result.ChTime, SizeOf(Integer));
end;


 
DrPass ©   (2004-04-11 12:13) [9]

А можно не извращаться, а использовать shortstring:
TFileRec = packed Record
  Path:string;
  Filename:string[250];//этой длины вполне хватит для имени файла
  Attr:integer;
  size:integer;
  ChTime:integer;
end;


 
Jack128 ©   (2004-04-11 12:19) [10]


> У меня есть база, чтобы меньше занимала памяти я определяю

;-)



Страницы: 1 вся ветка

Форум: "Основная";
Текущий архив: 2004.04.25;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.47 MB
Время: 0.034 c
4-1077181811
-=наблюдатель=-
2004-02-19 12:10
2004.04.25
InputQuery


1-1081655025
Aramis
2004-04-11 07:43
2004.04.25
Нестандартные курсоры


3-1080535531
Леван
2004-03-29 08:45
2004.04.25
как подавить обработку CTRL+DEL для DBGRID


3-1080720115
DimDim
2004-03-31 12:01
2004.04.25
DBISAM и Win95 несовместимы ??????


7-1078223382
stewart
2004-03-02 13:29
2004.04.25
Работа с модемом





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