[Delphi] Korektní uložení souboru
Řešim problém jak udělat aby při pokusu o uložení souboru proběhla kontrola zda již soubor neexistuje nebo není-li otevřen... Podle helpu jsem to sesmolil takto:
Kód:
procedure TForm1.UlozClick(Sender: TObject);
var JmenoSouboru:string;
index1,index2:byte;
Tabulka:TextFile;
begin
If SaveDialog1.Execute then
begin
JmenoSouboru:=SaveDialog1.FileName;
If FileExists(SaveDialog1.FileName) then
begin
If (FileOpen(SaveDialog1.FileName, fmOpenWrite or fmShareDenyNone )>0) then
begin
If (MessageDlg('Soubor již existuje, přepsat?',mtConfirmation, [mbYes, mbNo],0))=mrYes then
begin
index1:=1;
index2:=2;
AssignFile(Tabulka,SaveDialog1.FileName);
ReWrite(Tabulka);
ZapisDoSouboru(Tabulka,index1);
WriteLn(Tabulka);
WriteLn(Tabulka);
ZapisDoSouboru(Tabulka,index2);
CloseFile(Tabulka);
end
else
begin
MessageDlg('Soubor neuložen',mtInformation, [mbOk],0);
end;
end
else
begin
MessageDlg('Soubor je otevřen, zavřete jej nebo změnte název ukládaného souboru a opakujte akci',mtInformation, [mbOk],0);
end;
end
else
begin
index1:=1;
index2:=2;
AssignFile(Tabulka,SaveDialog1.FileName);
ReWrite(Tabulka);
ZapisDoSouboru(Tabulka,index1);
WriteLn(Tabulka);
WriteLn(Tabulka);
ZapisDoSouboru(Tabulka,index2);
CloseFile(Tabulka);
end;
end;
end;
Funguje to až na to, že když soubor existuje a chci ho přepsat tak to spadne na radku s ReWrite(Tabulka); a hodi to hlasku:
Kód:
Project Project1.exe raised exception class EInOutError with message 'I/O error 32'. Process stopped. Use Step or Run to continue.
Mám tedy ten soubor před uložením smazat? To by ho ale ReWrite měl přepsat sám ne?
Re: [Delphi] Korektní uložení souboru
Nemas ten soubor nahodnou nekde/necim otevrenej?
PS: doporucil bych ti vytvorit si proceduru uloz_data a nepouzivat copy&paste ;)
Re: [Delphi] Korektní uložení souboru
To jestli je otevrenej se zjistuje jeste pred tim nez se do nej vubec pokousi zapsat... Je to osetreny tady:
Kód:
If (FileOpen(SaveDialog1.FileName, fmOpenWrite or fmShareDenyNone)>0) then
.
.
A tim by to byt nemelo, kdyz to zkusim po restartu tak to dela taky a ten jsoubor jsem nicim neotviral...
PS: Tu proceduru jsem tam mel, jenze me to kvuli tomuhle problemu neslo tak jsem to hodil radsi zpatky... Aspon je to ted nazornejsi... Az to pujde tak ji udelam;)
EDIT: Zjisteni: Kdyz z
Kód:
If (FileOpen(SaveDialog1.FileName, fmOpenWrite or fmShareDenyNone)>0) then
vymazu fmOpenWrite tak to ulozit jde i kdyz ten soubor existuje, ale pak to zas spadne kdyz je ten soubor otevrenej protoze to nezjisti ze je otevrenej a povoli to prepis...
to fmOpenWrite a fmShareDenyNone jsem nasel v prikladu v helpu ale nejak jsem nepochopil na co to je... Je to asi neco co se tyce otevreni a sdileni, ale smysl mi unikl... kdyby mi to nekdo osvitil byl bych vdecny:)
Re: [Delphi] Korektní uložení souboru
Nemam tu help Delphi, ale predpokladam ze FileOpen soubor otevira.
Constatnty fmXY rika, jakym zpusobem chces pristoupit k souboru:
OpenWrite = otevrit pro zapis
fmShareDenyNone = zakaz sdileni otevreni souboru jinymy procesy?
Re: [Delphi] Korektní uložení souboru
Citace:
Původně odeslal
MEluZíNa
Nemam tu help Delphi, ale predpokladam ze FileOpen soubor otevira.
Constatnty fmXY rika, jakym zpusobem chces pristoupit k souboru:
OpenWrite = otevrit pro zapis
fmShareDenyNone = zakaz sdileni otevreni souboru jinymy procesy?
Aha tak uz jsem na to prisel... Ten FileOpen otevira soubor a vytvori handler,
takze kdyz chci provest zapis do souboru tak to hodi chybu protoze uz je otevrenej tim FileOpen... Jsem myslel, ze je to na testovani zdali je soubor otevren... Tak budu asi muset z programu tuto funkci vypustit protoze praci se soubory pomoci FileHandleru zatim neovladam... Kdyby nekdo vedel o nejakym srozumitelnym navodu tak sem s nim;)
Re: [Delphi] Korektní uložení souboru
Tak uz jsem to vyresil... Stacilo pred prikazy pro praci se souborem napsat FileClose(FileHandle); Tim se zavre ten soubor otevreny pomoci FileOpen...
Re: [Delphi] Korektní uložení souboru
Ano tim jsi to zdanlive vyresil :)
Co kdyz nekdo stihne otevrit ten soubor mezitim co kontrolujes zda neni otevreny a tim nez ho skutecne otevres pro cteni? :)
Ale to uz jsou slozitejsi otazky na dlouhe zimni vecery, pro zacatek to staci jak to mas...
Re: [Delphi] Korektní uložení souboru
Myslim ze sance ze se tak stane je nulova... Uzivatel bude zamestnan dialogovym oknem kde rozhodne zda prepsat soubor a bude-li souhlasit probehne toto
Kód:
FileClose(FileHandle);
UlozeniSouboru;
coz se stane v radu max. milisekund... A pravdepodobnost ze by nekdo v ten okamzik otviral soubor, treba po siti, neni daleko od nuly...
pripoustim, ze to reseni neni moc elegantni, ale jakmile zjistim jak se pomoci tech handleru zapisuji do souboru znaky tak to pretvorim:)
Re: [Delphi] Korektní uložení souboru
Ten kod je dost hrozny.
1) Je tam dvakrat ten isty kod
2) Nemozes sa spoliehat na to, ze je ta pravdepodobnost mala
3) Nie su tam osetrene chyby
Keby si zacal bodom 3), mozno nemusis riesit tie ostatne veci (v Delphi som uz dlho nerobil, preto "mozno").
Re: [Delphi] Korektní uložení souboru
Citace:
Původně odeslal
Rainbow
Ten kod je dost hrozny.
1) Je tam dvakrat ten isty kod
2) Nemozes sa spoliehat na to, ze je ta pravdepodobnost mala
3) Nie su tam osetrene chyby
Keby si zacal bodom 3), mozno nemusis riesit tie ostatne veci (v Delphi som uz dlho nerobil, preto "mozno").
add 1)
BTW: mozna jsem se spatne vyjadril ale nekde vys bylo psany ze je tam to zdvojeni kodu docastne, nez se vyresi ten problem...
ted to vypada takto
Kód:
procedure TForm1.UlozClick(Sender: TObject);
var FileHandle:integer;
begin
If SaveDialog1.Execute then
begin
If FileExists(SaveDialog1.FileName) then
begin
FileHandle := FileOpen(SaveDialog1.FileName, fmOpenWrite or fmShareDenyNone);
If FileHandle > 0 then
begin
If (MessageDlg('Soubor již existuje, přepsat?',mtConfirmation, [mbYes, mbNo],0))=mrYes then
begin
FileClose(FileHandle);
UlozeniSouboru;
end
else
begin
MessageDlg('Soubor neuložen',mtInformation, [mbOk],0);
end;
end
else
begin
MessageDlg('Soubor je otevřen, zavřete jej nebo změnte název souboru a opakujte akci',mtInformation, [mbOk],0);
end;
end
else
begin
UlozeniSouboru;
end;
end;
end;
add 3) Jaky chyby mas na mysli? Prave ty se snazim v ty procedure eliminovat...
Re: [Delphi] Korektní uložení souboru
Testuješ někdě, zda máš dostatek místa na disku? Možná se dá toho vymyslet ještě víc.
A ještě jedno takové pravidlo: "Pokud něco nastat může, tak to také nastane." Jinými slovy. Pokud někdo má čas, byť milisekundy, na otevření tvého souboru, tak to určitě stihne. Stejně tak jako když někde má být zadáno číslo, tak první uživatel tam napíše "PEPA" ;)
Zamysli se nad použitím "try ... catch ..."
Re: [Delphi] Korektní uložení souboru
K tomu disku: O tom jsem ani nepremyslel:) Ten program generuje tabulky do excelu ve formatu CSV... Ted jsem jeden zkusil udelat a ma 622 Bajtu na disku 1KB... Jeste o tom popremyslim a kouknu na try a catch, zatim diky