Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > Работа с файлами


Автор: kindDevil 21.8.2006, 00:46
при чтении из типизированного файла, читается строковое поле записи.
при сохранении делается rewrite файла с именем соотв. этому строковому полю.
если редактор открывает уже сохраненный файл, а затем пытается его сохранить под тем же именем, то выдается ошибка Invalid file name.
в чем бага? 

Код


type STAT = record
  MAX,
  EXT:integer;
end;

type TWeapon = record
  Name:ShortString;
  Weight,
  Cost,
  Fire_Cost:longint;
  Damage:STAT;
  Clip:STAT; 
  Clip_Type,
  Range,
  Ache_Factor:longint;
  Comm:ShortString;
end;

var
  Form1: TForm1;
  Edits:array[1..12] of TEdit;
  Labels:array[1..12] of TLabel;
  k:TWeapon;




//процедура чтения:

Код

procedure TForm1.N4Click(Sender: TObject);
var f: file of TWeapon;
s:string;
begin
if opendialog1.Execute then
  begin
    assignfile (f,opendialog1.FileName);
    reset(f);
    read(f,k);
    closefile(f);
  end;
Edits[1].Text := k.Name;
edits[2].Text := inttostr (k.Weight);
edits[3].Text := inttostr (k.Cost);
edits[4].Text := inttostr (k.Damage.EXT);
edits[5].Text := inttostr (k.Damage.MAX);
edits[6].Text := inttostr (k.Clip.MAX);
edits[7].Text := inttostr (k.Clip.EXT);
edits[8].Text := inttostr (k.Clip_Type);
edits[9].Text := inttostr (k.Range);
edits[10].Text := inttostr (k.Ache_Factor);
edits[11].Text := inttostr (k.Fire_Cost);
edits[12].Text := k.Comm;
s:= k.Name;
end;


процедура записи, после которой выдается ошибка, если сохраняется в уже существующий файл.
Код

procedure TForm1.N5Click(Sender: TObject);
var f:file of TWeapon;
begin
  k.Name := edits[1].Text;
  k.Weight := strtoint (edits[2].Text);
  k.Cost := strtoint (edits[3].Text);
  k.Damage.EXT := strtoint (edits[4].Text);
  k.Damage.MAX := strtoint (edits[5].Text);
  k.Clip.MAX := strtoint (edits[6].Text);
  k.Clip.EXT := strtoint (edits[7].Text);
  k.Clip_Type := strtoint (edits[8].Text);
  k.Range := strtoint (edits[9].Text);
  k.Ache_Factor := strtoint (edits[10].Text);
  k.Fire_Cost := strtoint (edits[11].Text);
  k.Comm := edits[12].Text;
assignfile (f,'Weapon\'+k.Name+'.wpn');
rewrite (f);
write(f,k);
closefile(f);
end;

Автор: Fedia 21.8.2006, 01:01
Перед
Цитата(kindDevil @  21.8.2006,  00:46 Найти цитируемый пост)
assignfile (f,'Weapon\'+k.Name+'.wpn');

попробуй добавить:
Код

if FileExists('Weapon\'+k.Name+'.wpn') then
DeleteFile('Weapon\'+k.Name+'.wpn');

Автор: Alexeis 21.8.2006, 01:56
kindDevil, скорее всего файл просто занят другим процессом, потому как перезапись существуещего файла при помощи rewrite допустимая операция.

Автор: SlaUr 21.8.2006, 05:15
Потому что выдается  ошибка Invalid file name я бы посоветовал делать полный путь к файлу.
Если начальная директория это директория программы то это можно сделать так:

Код

var pathstarts:string
pathstarts:=ExtractFileDir(Paramstr(0));
if pathstarts[length(pathstarts)]<>'\' then pathstarts:=pathstarts+'\';
.....
assignfile (f,pathstarts+'Weapon\'+k.Name+'.wpn');
.....


можно еще глянуть что находится в k.name (showmessage(k.name))

Автор: Fedia 21.8.2006, 05:38
SlaUr, скорее всего ты прав, только тогда уж проще так:
Код

pathstarts:=ExtractFilePath(Paramstr(0));
assignfile (f,pathstarts+'Weapon\'+k.Name+'.wpn');

Смущает только, что ошибка появляется в случае, если файл с таким именем уже существует.

Автор: Alexeis 21.8.2006, 08:03
SlaUr, Fedia, но kindDevil, пишет
Цитата(kindDevil @  21.8.2006,  00:46 Найти цитируемый пост)
процедура записи, после которой выдается ошибка, если сохраняется в уже существующий файл.

Ошибка возникает после записи, а не чтения, а поскольку rewrite, всегда создает новый файл, то путь не играет значения (если он не сетевой или не указыват на CD-ROM)

Автор: Fedia 21.8.2006, 09:00
Цитата(alexeis1 @  21.8.2006,  08:03 Найти цитируемый пост)
Ошибка возникает после записи, а не чтения, а поскольку rewrite, всегда создает новый файл, то путь не играет значения (если он не сетевой или не указыват на CD-ROM)

У меня как-то были глюки с относительными путями, поэтому больше склоняюсь к варианту SlaUr. Просто в вопросе есть противоречия: с одной стороны не может записать в уже существующий файл, а с другой: ошибка "Invalid file name".
Правду скоро узнаем smile

Автор: Spectral 21.8.2006, 09:40
Я бы сделал вот так:
Код


//Чтение

procedure LoadWeaponInfo;
var
  f: TFileStream;
begin
  f := TFileStream.Create(GlobalPath + SavePath, fmOpenReadWrite);
  try
    f.Read(k, SizeOf(k));
  finally
    f.Free;
  end;
end;

//Запись

procedure SaveWeaponInfo;
var
  f: TFileStream;
begin
  f := TFileStream.Create(GlobalPath + SavePath, fmCreate or fmOpenWrite);
  try
    f.Write(k, SizeOf(k));
  finally
    f.Free;
  end;
end;



Или через паскалевские BlockRead/BlockWrite.

Автор: kindDevil 21.8.2006, 19:08
SlaUr
спасибо огромное. очень помог.

но действительно странно:
если я делаю новый файл, то сохраняется великолепно, даже без извлечения пути к директории с программой.  smile 
но дописал нахождение полного пути и все работает  smile 
спасибо всемм.

Автор: AugMaster 21.8.2006, 20:04
хе..я кажись понял багу....ты когда опендиалог делаешь то автоматом делаешь чейндждир...если ты просто сохраняешь файл(без открытия) то путь сохранения = ExeDir+Weapon\...а вот если ты опендиалог файла выполнил в папке Weapon то туда автоматом происходит ChDir и затем пытаясь сохранить файл, ты его уже сохраняешь не в ExeDir+Weapon а в ExeDir+Weapon+Weapon...а вообще действительно не пользуйся относительной адресацией а полной...сам над этим часа 3 помучался пока понял причину.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)