Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2005.10.30;
Скачать: CL | DM;

Вниз

Помогите разбраться с TFileStream   Найти похожие ветки 

 
SergProger ©   (2005-10-01 02:11) [0]

Всем привет. Вот есть у мня две процедуры:

procedure CreateStream(Files: TString; OutputFile: String);
var
 InFile, OutFile: TFileStream;
 b, i: Byte;
 Name: String;
begin
 If Files.Count = 0 then begin
   Button1.Enabled:=True;
   Exit;
 end;
 OutFile:=TFileStream.Create(OutputFile,fmCreate);
 b:=Files.Count;
 OutFile.Write(b,SizeOf(Files.Count));
 For i:=0 to Files.Count-1 do begin
   Name:=ExtractFileName(Files[i]);
   OutFile.Write(Name,SizeOf(Name));
   InFile:=TFileStream.Create(Files[i],fmOpenRead);
   OutFile.CopyFrom(InFile,InFile.Size);
 end;
 InFile.Free;
 OutFile.Free;
end;

procedure CopyFromStream(InputFile, OutDirectory: String);
var
 InFile, OutFile: TFileStream;
 i, f: byte;
 Name, s: String;
begin
 InFile:=TFileStream.Create(InputFile,fmOpenRead);
 InFile.Read(f,SizeOf(f));
 For i:=1 to f do begin
   InFile.Read(Name,SizeOf(Name));
   s:=OutDirectory+Name;
   OutFile:=TFileStream.Create(s,fmCreate);
   OutFile.CopyFrom(InFile,f);
 end;
 InFile.Free;
 Outfile.Free;
end;

Первая из них работает, а вторая не хочет. В чём тут дело, объясните мне, пожалуйста.


 
Плохиш ©   (2005-10-01 02:22) [1]

Вообще-то
1. перед записью Name надо писать длину строки, а не размер указателя на неё.
2. где сохраняешь размер файла?
3. перед чтением Name необходимо распределить память для строки.


 
Spaller   (2005-10-01 03:35) [2]

Ну ты знаешь Плохишь прав, вообще говоря ф-ия sizeof должна возращать размер типа, но стринг же динамический плюс ты передаешь указатель, воспользоваться лучше ф-ией length(name), но опять таки же стринг тебе тут не поможет скорее всего, воспользуйся например ShortString - строка постоянной длины. скорее всего это самая основная ошибка. плюс
For i:=1 to f do begin
  InFile.Read(Name,SizeOf(Name));
  s:=OutDirectory+Name;
  OutFile:=TFileStream.Create(s,fmCreate);
  OutFile.CopyFrom(InFile,f);

в данном цикле я не могу понять чего ты хочешь сделать, на первый взгляд может показаться что в потоке InFile находится f одинаковых структур данных и ты их считываешь последовательно, тогда зачем каждый раз вызываешь    OutFile:=TFileStream.Create(s,fmCreate);, засоряя тем самым память, выделяя новую память, то есть ты f раз делаешь одно  и тоже, так что объясни что ты хотел сделать, хотя может просто я не понял :) Хатя сейчас присмотрелся и понял что OutFile ведь сразу же после цикла уничтожается, тогда зачем было считывать, если просто надо было перевести указатель на нужную позицую путем считывания можно было считать f*f байт...ну кароче не понимаю я смысла данной процедуры так что наверное чуши тут понаписал....InFile.Read(f,SizeOf(f)); - зачем писать sizeof? так конечно нагляднее но медленне :) это я так к слову... может много платформенная программа, хотя байт он и есть байт и не меняется в отличии от слов... ладно все...


 
SergProger ©   (2005-10-06 15:05) [3]

Большое спасибо за совет. Но вот доработал код, но всё равно программа не читает строки как надо. Вот конечный код:

procedure FilesInOne(ExpFileName, Dir: String; Files: TStrings);
var
 InFile, OutFile: TFileStream;
 Size: Int64;
 f, i, l: Word;
 s: String;
begin
 OutFile:=TFileStream.Create(ExpFileName,fmCreate);
 f:=Files.Count;
 OutFile.Write(f,SizeOf(f));
 For i:=0 to f-1 do begin
   s:=Files[i];
   l:=Length(s);
   OutFile.Write(l,SizeOf(l));
   OutFile.Write(s[l],l);
 end;
 For i:=0 to f-1 do begin
   s:=Files[i];
   InFile:=TFileStream.Create(Dir+s,fmOpenRead);
   Size:=InFile.Size;
   OutFile.Write(Size,SizeOf(Size));
   OutFile.CopyFrom(InFile,Size);
   InFile.Free;
 end;
 OutFile.Free;
end;

procedure OneInFiles(ImpFileName, Dir: String);
var
 InFile, OutFile: TFileStream;
 Files: TStringList;
 Size: Int64;
 f, i, l: Word;
 s: String;
begin
 InFile:=TFileStream.Create(ImpFileName,fmOpenRead);
 InFile.Read(f,SizeOf(f));
 Files:=TStringList.Create;
 For i:=1 to f do begin
   InFile.Read(l,SizeOf(l));
   SetLength(s,l);
   InFile.Read(s[l],l);
   Files.Add(s);
 end;
 For i:=0 to f-1 do begin
   InFile.Read(Size,SizeOf(Size));
   ForceDirectories(ExtractFileDir(Dir+Files[i]));
   OutFile:=TFileStream.Create(Dir+Files[i],fmCreate);
   OutFile.CopyFrom(InFile,Size);
   OutFile.Free;
 end;
 Files.Free;
 InFile.Free;
end;

  НУ ЧТО ОН ТЕПЕРЬ ОТ МЕНЯ ХОЧЕТ ???


 
umbra ©   (2005-10-06 15:15) [4]


> НУ ЧТО ОН ТЕПЕРЬ ОТ МЕНЯ ХОЧЕТ ???


ОН обычно говорит, что не так. Что не получается конкретно?


 
MBo ©   (2005-10-06 15:17) [5]

OutFile.Write(s[l],l);
что за индекс в квадратных скобках?


 
icWasya ©   (2005-10-06 17:51) [6]

и в догонку
var
i,f:word; // здесь описываются беззнаковые переменные
f:=Files.Count; // а если Count = 0
For i:=0 to f-1 do // то как будет работать этот оператор я не знаю


 
SergProger ©   (2005-10-06 21:29) [7]

Дело в том, что записанные имена файлов потом читаются некорректно: если например записана одна строка, то прочитает он её идеально, а если больше, то полная абракадабра.



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

Текущий архив: 2005.10.30;
Скачать: CL | DM;

Наверх




Память: 0.49 MB
Время: 0.036 c
3-1127279502
Каспер
2005-09-21 09:11
2005.10.30
AdoStoredProc вытащить возвращаемое значение


4-1125186966
graveyard
2005-08-28 03:56
2005.10.30
как снять атрибут с файла


2-1128819510
quadronik
2005-10-09 04:58
2005.10.30
Пример из дельфийского ХЕЛПа..не работает


2-1128600837
Sysanin
2005-10-06 16:13
2005.10.30
Переменные в функциях


3-1127212198
mrAld
2005-09-20 14:29
2005.10.30
Модификация полей в наборе данных ADO