![]() |
Datei kann nicht geschrieben werden - Warum und wie ändern?
Hallo Wissende,
ich habe ein Freeware-Tool geschrieben, welches aus TextDateien automatisiert HTML-Dateien macht. Bei mir lief auf meinen Testsystemen und auf der Entwicklungsumgebung alles super. Nun habe ich aber von einem User eine EMail erhalten, die besagt, dass bei ihm sehr oft die Meldung kommt, dass die Datei nicht geschrieben werden kann. Wie kann ich das Abfangen, bzw. das Speichern der Datei/en doch IMMER sicherstellen? Diese Routine ist eine von beiden, die macht was ich will:
Delphi-Quellcode:
Danke für Tipps. Ich will nicht nur die Fehlermeldung unterdrücken, sondern auch sicherstellen, dass das Speichern wirklich klappt. SaveToFile gibt leider keinen Wert zurück. Hat jemand einen Vorschlag?
procedure TForm1.GenerateFile(Filename:String;LoadatWeb:boolean;ArtikelNumber:integer);
var myList,HtmlList,list:TStringlist; i:integer; str_head,str_content:string; begin myList:=TStringlist.Create; myList.LoadFromFile(Filename); ed_head.Text:=myList.Strings[0]; str_head:=myList.Strings[0]; myList.Delete(0); mem_txt.Lines.Assign(myList); list:=TStringList.Create; list.Assign(myList); for i:=0 to list.count-1 do begin if i<list.Count-1 then list.Strings[i]:=list.Strings[i]+ ' ' end; str_content:=List.Text; HtmlList:=TStringlist.Create; HtmlList.Add('<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">'); HtmlList.Add('<html>'); HtmlList.Add('<head>'); HtmlList.Add('<link rel="stylesheet" href="../css/'+cmb_css_file.Text+'" type="text/css" />'); HtmlList.Add('</head>'); HtmlList.Add('<body>'); HtmlList.Add(''); HtmlList.Add('<h3>'+str_head+'</h3>'); HtmlList.Add(''); HtmlList.Add(' '+str_content+'</p>'); HtmlList.Add(''); if (LoadatWeb=false) and (complete.chk_hist_back.Checked) then HtmlList.Add(' [url="javascript:history.back()"]Zurück[/url]</p>'); HtmlList.Add(''); HtmlList.Add('</body>'); HtmlList.Add('</html>'); HtmlList.SaveToFile(Pvw_Path + 'artikel_id_'+inttostr(ArtikelNumber)+'.html'); if LoadatWeb then web.Navigate(Pvw_Path + 'artikel_id_'+inttostr(ArtikelNumber)+'.html'); myList.Free; HtmlList.Free; end; |
Re: Datei kann nicht geschrieben werden - Warum und wie ände
Hi,
erstmal würde ich Dir empfehlen, Resourcen-Schutzblöcke (try...finally) und Einrückung zu verwenden. Dann siehst Du, ob ggf. eine Liste nicht freigeben wurde die evtl. eine Datei sperrt. Diese Schema verwende ich:
Delphi-Quellcode:
Zu Deinem Problem: Hat der Benutzer vielleicht keine Schreibberechtung auf den Ordner, in dem er die Datei speichern möchte? Ist die Datei evtl durch ein anderes / dein Programm gesperrt?
MyList := TStringList.Create;
MySecondList := TStringList.Create; try // Viel Code finally MyList.Free; MySecondList.Free; end; mfG mirage228 |
Re: Datei kann nicht geschrieben werden - Warum und wie ände
Danke für Deine Antwort. Die Datei dürfte nicht durch ein anderes Programm gesperrt sein, zumindest nicht durch eines von mir. Was aber der Fall ist, ist das die Datei dann zumeist im TWebbrowser geladen wird. Aber der blockiert doch nicht das überschreiben einer schon vorhandenen Datei...
Und das mit den Schreibrechten kann nicht sein, dass es ja manchmal geht und manchmal eben nicht. Komisch, oder? |
Re: Datei kann nicht geschrieben werden - Warum und wie ände
Zitat:
Ich weiss jetzt nicht in wie fern der WebBrowser die Datei sperrt, während er sie liest. Vielleicht ist da ja der Hund begraben. Vielleicht kannst Du ja die Funktion schnell hintereinander mit der selben Datei testen, um das reproduzieren zu können. mfG mirage228 |
Re: Datei kann nicht geschrieben werden - Warum und wie ände
Also das Erstellen passiert, wenn man einen Doppelklick auf eine Listbox macht. Ich habe soeben mal 20 mal ganz schnell und oft drauf geklickt. Irgendwann zum Ende hin stieg der Compiler ein...
Folgender Fhlercode: --------------------------- Benachrichtigung über Debugger-Exception --------------------------- Im Projekt TxtFilesToHtml.exe ist eine Exception der Klasse EFCreateError aufgetreten. Meldung: 'Datei C:\Programme\Borland\Delphi6\Projects\TxtFilesToHt ml\preview\artikel_id_1.html kann nicht erstellt werden'. Prozeß wurde angehalten. Mit Einzelne Anweisung oder Start fortsetzen. --------------------------- OK Hilfe --------------------------- |
Re: Datei kann nicht geschrieben werden - Warum und wie ände
wie wäre es denn damit?
Delphi-Quellcode:
sFileName := Pvw_Path + 'artikel_id_'+inttostr(ArtikelNumber)+'.html';
if fileexists(sFileName) then DeleteFile(sFileName); HtmlList.SaveToFile(sFileName); myList.Free; HtmlList.Free; if LoadatWeb then web.Navigate(sFileName); |
Re: Datei kann nicht geschrieben werden - Warum und wie ände
und noch etwas: du hast 3 stringlisten, wovon du nur 2 wieder freigibst?
|
Re: Datei kann nicht geschrieben werden - Warum und wie ände
Ok, ich werde es mal so wie von Dir beschrieben versuchen! Ich bin mir aber nicht sicher, ob der Webbrowser die geladene Datei nicht doch für belegt erklärt und das Löschen verbietet. Aber ich werde es ja sehen.
Das mit den Stringlisten ist natürlich schlampig! Auch das werde ich ändern. Danke für diesen Hinweis. Darf ich Fragen, was Dich glauben macht, dass dieser Weg ohne die Fehlermeldung auskommt? |
Re: Datei kann nicht geschrieben werden - Warum und wie ände
also ich wüsste nicht an welcher stelle der webbrowser die datei blockieren sollte?!
|
Re: Datei kann nicht geschrieben werden - Warum und wie ände
Also den Code habe ich nun angepasst. Hier kommt bisher keine Fehlermeldung mehr. Ich habe mich dann auch daran gemacht den Code für die IndexPage anzupassen. Dieser sieht wie folgt aus. Ich hätte davon sicher die Masse weglassen können, aber wer weiss wozu es gut ist. Manchmal steckt der Teufel eben im Detail.
Dieser Code wird ausgeführt nach Druck auf einen Button. Es reichten mir 4 Versuche bis die Meldung kam, dass die Datei nicht erzeugt werden kann.
Delphi-Quellcode:
---------------------------
procedure Tcomplete.btn_generateClick(Sender: TObject);
var HtmlList,ContentList,FileList:TStringlist; str_head,str_content,sFileName:string; i,k,z,j,int_Count,int_cols,int_rows,int_filecounter_th,int_filecounter_td:integer; begin int_Count:=0; int_cols:=0; int_rows:=0; int_filecounter_th:=0; int_filecounter_td:=0; int_cols:=ed_cols.Value; ContentList:=TStringlist.Create; HtmlList:=TStringlist.Create; FileList:=TStringlist.Create; HtmlList.Add('<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">'); HtmlList.Add('<html>'); HtmlList.Add('<head>'); HtmlList.Add('<link rel="stylesheet" href="../css/'+cmb_css_file.Text+'" type="text/css" />'); HtmlList.Add('</head>'); HtmlList.Add('<body>'); for i:=0 to form1.list_files.Count-1 do if form1.list_files.Checked[i] then begin inc(int_Count); FileList.Add(form1.ed_dir.Text + form1.list_files.items[i]) end; case rad_artikel_style.ItemIndex of 0 : begin for i:=0 to form1.list_files.Count-1 do begin if form1.list_files.Checked[i] then begin ContentList.LoadFromFile(form1.ed_dir.Text + form1.list_files.Items.Strings[i]); str_head:=ContentList.Strings[0]; ContentList.Delete(0); str_content:=ContentList.Text; form1.GenerateFile(form1.ed_dir.Text + form1.list_files.Items[i],false,i); SetLength(str_content,strtoint(ed_sign_count.text)); //hier wird das layout zusammengebaut HtmlList.Add(''); HtmlList.Add('<h3>'+str_head+'</h3>'); HtmlList.Add(''); if chk_br_linktext.Checked then HtmlList.Add(' '+str_content+' [url="artikel_id_'+inttostr(i)+'.html"]'+ed_linktext.Text+'[/url]</p>') else HtmlList.Add(' '+str_content+' [url="artikel_id_'+inttostr(i)+'.html"]'+ed_linktext.Text+'[/url]</p>'); HtmlList.Add(''); end; end; end; 1 : begin HtmlList.Add('<table cellpadding="3">'); int_rows:=((int_Count div int_cols) + (int_Count mod int_cols)); //arbeitet alle zeilen ab for k:=0 to int_rows-1 do begin //arbeitet die th-spalten ab HtmlList.Add(' <tr valign="top">'); for z:= 1 to int_cols do begin ContentList.Clear; if int_filecounter_th<int_Count then begin ContentList.LoadFromFile(FileList.Strings[int_filecounter_th]); str_head:=ContentList.Strings[0]; HtmlList.Add(' <th>'+str_head+'</th>'); end else HtmlList.Add(' <th></th>'); inc(int_filecounter_th); end; HtmlList.Add(' </tr>'); //arbeitet die td-spalten ab HtmlList.Add(' <tr valign="top">'); for z:= 1 to int_cols do begin ContentList.Clear; if int_filecounter_td<int_Count then begin ContentList.LoadFromFile(FileList.Strings[int_filecounter_td]); ContentList.Delete(0); str_content:=ContentList.Text; form1.GenerateFile(FileList.Strings[int_filecounter_td],false,int_filecounter_td); SetLength(str_content,strtoint(ed_sign_count.text)); HtmlList.Add(' <td>' +str_content+' [url="artikel_id_'+inttostr(int_filecounter_td)+'.html"]'+ed_linktext.Text+'[/url]</td>'); end else HtmlList.Add(' <td></td>'); inc(int_filecounter_td); end; HtmlList.Add(' </tr>'); end; end; end; HtmlList.Add('</body>'); HtmlList.Add('</html>'); sFileName := Pvw_Path + 'index.html'; if fileexists(sFileName) then DeleteFile(sFileName); sleep(60); try HtmlList.SaveToFile(sFileName); web.Navigate(sFileName); finally FileList.Free; HtmlList.Free; ContentList.Free; end; end; Benachrichtigung über Debugger-Exception --------------------------- Im Projekt TxtFilesToHtml.exe ist eine Exception der Klasse EFCreateError aufgetreten. Meldung: 'Datei C:\Programme\Borland\Delphi6\Projects\TxtFilesToHt ml\preview\index.html kann nicht erstellt werden'. Prozeß wurde angehalten. Mit Einzelne Anweisung oder Start fortsetzen. --------------------------- OK Hilfe --------------------------- |
Re: Datei kann nicht geschrieben werden - Warum und wie ände
lass den ganzen "schnotter" doch mal weg. erstell dir deine stringliste.
füge eine zeile hinzu und dann führe nur mal den folgenden code aus:
Delphi-Quellcode:
Anmerkung:
sFileName := Pvw_Path + 'index.html';
if fileexists(sFileName) then DeleteFile(sFileName); try HtmlList.SaveToFile(sFileName); HtmlList.Clear; HtmlList.Free; except on e: exception do begin ShowMessage('error = ' + e.Message); end; end; web.Navigate(sFileName); sleep bringt dir nix, das lässt dein programm pausieren, dann nimm lieber ein Application.ProcessMessages gib mal feedback wie das nun ausgegangen ist. |
Re: Datei kann nicht geschrieben werden - Warum und wie ände
keine versserung!
--------------------------- Txt 2 Html --------------------------- error = Datei C:\Programme\Borland\Delphi6\Projects\TxtFilesToHt ml\preview\index.html kann nicht erstellt werden --------------------------- OK --------------------------- |
Re: Datei kann nicht geschrieben werden - Warum und wie ände
wie ist "Pvw_Path" definiert? Welchen Wert hat die Variable? Bist du dir ganz sicher das du auf jedem System in dem Ordner Schreibrechte hast? Schreibst du eventuell in den Programmordner?
|
Re: Datei kann nicht geschrieben werden - Warum und wie ände
Hier mal der Code der FormCreate:
Delphi-Quellcode:
Wie ich schon sagte, wenn es ein Problem mit den Benutzerrechten wäre, dürfte es doch nie klappen und nicht nur manchmal wie bei mir. Beim ersten mal klappt es komischerweise und wenn ich dem Tool genug Zeit gebe, bleibt auch alles schön. Habe ich aber nen nervösen Finger und drück den Button 2 oder 3 mal direkt hintereinander, dann kommt es zu dieser Fehlermeldung. Komisch, oder!?
procedure TForm1.FormCreate(Sender: TObject);
begin web.navigate('about:blank'); App_Path:=ExtractFileDir(Application.ExeName); If not (AnsiLastChar(App_Path)='\') then App_Path := App_Path + '\'; Txt_Path := App_Path + 'txt\'; Css_Path := App_Path + 'css\'; Pvw_Path := App_Path + 'preview\'; ed_dir.Text:=Txt_Path; {usw.} end; |
Re: Datei kann nicht geschrieben werden - Warum und wie ände
sowas fange ich immer wie folgt ab:
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
begin if bAktionLaeuftNoch then Exit; bAktionLaeuftNoch := True; // dein code hier.... bAktionLaeuftNoch := False; end; |
Re: Datei kann nicht geschrieben werden - Warum und wie ände
Ja ich hatte auch schon überlegt, ob ich das mit ner boolschen Variable abfange. Nur ist dabei das Problem, dass es im dümmsten Fall zu keinem Reset dieser kommt...
Aber ich werde es wohl so lösen... Nachtrag: Es funzt trotzdem nicht! Ein einfacher Doppelklick reichte völlig aus. |
Re: Datei kann nicht geschrieben werden - Warum und wie ände
wie würde dieser dümmste fall aussehen?
per try finally - block sollten da keine probleme auftreten?! |
Re: Datei kann nicht geschrieben werden - Warum und wie ände
Hier nochmal mein kompletter Code, mit dem es immer noch nicht geht. Was mache ich nur falsch?
Delphi-Quellcode:
procedure Tcomplete.btn_generateClick(Sender: TObject);
var HtmlList,ContentList,FileList:TStringlist; str_head,str_content,sFileName:string; i,k,z,j,int_Count,int_cols,int_rows,int_filecounter_th,int_filecounter_td:integer; begin if CreateIsRunning then Exit; CreateIsRunning := True; int_Count:=0; int_cols:=0; int_rows:=0; int_filecounter_th:=0; int_filecounter_td:=0; int_cols:=ed_cols.Value; ContentList:=TStringlist.Create; HtmlList:=TStringlist.Create; FileList:=TStringlist.Create; HtmlList.Add('<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">'); HtmlList.Add('<html>'); HtmlList.Add('<head>'); HtmlList.Add('<link rel="stylesheet" href="../css/'+cmb_css_file.Text+'" type="text/css" />'); HtmlList.Add('</head>'); HtmlList.Add('<body>'); for i:=0 to form1.list_files.Count-1 do if form1.list_files.Checked[i] then begin inc(int_Count); FileList.Add(form1.ed_dir.Text + form1.list_files.items[i]) end; case rad_artikel_style.ItemIndex of 0 : begin for i:=0 to form1.list_files.Count-1 do begin if form1.list_files.Checked[i] then begin ContentList.LoadFromFile(form1.ed_dir.Text + form1.list_files.Items.Strings[i]); str_head:=ContentList.Strings[0]; ContentList.Delete(0); str_content:=ContentList.Text; form1.GenerateFile(form1.ed_dir.Text + form1.list_files.Items[i],false,i); SetLength(str_content,strtoint(ed_sign_count.text)); //hier wird das layout zusammengebaut HtmlList.Add(''); HtmlList.Add('<h3>'+str_head+'</h3>'); HtmlList.Add(''); if chk_br_linktext.Checked then HtmlList.Add(' '+str_content+' [url="artikel_id_'+inttostr(i)+'.html"]'+ed_linktext.Text+'[/url]</p>') else HtmlList.Add(' '+str_content+' [url="artikel_id_'+inttostr(i)+'.html"]'+ed_linktext.Text+'[/url]</p>'); HtmlList.Add(''); end; end; end; 1 : begin HtmlList.Add('<table cellpadding="3">'); int_rows:=((int_Count div int_cols) + (int_Count mod int_cols)); //arbeitet alle zeilen ab for k:=0 to int_rows-1 do begin //arbeitet die th-spalten ab HtmlList.Add(' <tr valign="top">'); for z:= 1 to int_cols do begin ContentList.Clear; if int_filecounter_th<int_Count then begin ContentList.LoadFromFile(FileList.Strings[int_filecounter_th]); str_head:=ContentList.Strings[0]; HtmlList.Add(' <th>'+str_head+'</th>'); end else HtmlList.Add(' <th></th>'); inc(int_filecounter_th); end; HtmlList.Add(' </tr>'); //arbeitet die td-spalten ab HtmlList.Add(' <tr valign="top">'); for z:= 1 to int_cols do begin ContentList.Clear; if int_filecounter_td<int_Count then begin ContentList.LoadFromFile(FileList.Strings[int_filecounter_td]); ContentList.Delete(0); str_content:=ContentList.Text; form1.GenerateFile(FileList.Strings[int_filecounter_td],false,int_filecounter_td); SetLength(str_content,strtoint(ed_sign_count.text)); HtmlList.Add(' <td>' +str_content+' [url="artikel_id_'+inttostr(int_filecounter_td)+'.html"]'+ed_linktext.Text+'[/url]</td>'); end else HtmlList.Add(' <td></td>'); inc(int_filecounter_td); end; HtmlList.Add(' </tr>'); end; end; end; HtmlList.Add('</body>'); HtmlList.Add('</html>'); sFileName := Pvw_Path + 'index.html'; if fileexists(sFileName) then DeleteFile(sFileName); sleep(60); try HtmlList.SaveToFile(sFileName); HtmlList.Clear; HtmlList.Free; except on e: exception do begin ShowMessage('error = ' + e.Message); end; end; web.Navigate(sFileName); {try HtmlList.SaveToFile(sFileName); web.Navigate(sFileName); finally} FileList.Free; //HtmlList.Free; ContentList.Free; CreateIsRunning:=False; // end; end; |
Re: Datei kann nicht geschrieben werden - Warum und wie ände
Hallo,
ich möchte nochmal kurz darauf aufmerksam machen, was das Problem bei mir ist:
Delphi-Quellcode:
Der Compiler geht direkt in die Zeile HtmlList.Clear;, was meistens der Fall ist, wenn er eine Zeile höher ein Problem hat. Die Meldung lautet wie immer. Die Datei kann nicht geschrieben werden. Gibt es noch irgendeine Möglichkeit das weg zu bekommen?
try
HtmlList.SaveToFile(sFileName); HtmlList.Clear; HtmlList.Free; except on e: exception do begin ShowMessage('error = ' + e.Message); end; end; |
Re: Datei kann nicht geschrieben werden - Warum und wie ände
Hallo Tom,
im event handler für OnClick() von btn_generate würde ich nur Code zur Manipulation der Benutzerschnittstelle unterbringen, den Rest würde ich in mehrere Prozeduren auslagern. Einfach geht das indem du Actions verwendest:
Delphi-Quellcode:
Du musst keine Datei vorher löschen, die du später mit SaveToFile() überschreibst. Erstellst du die Datei nur, damit sie im Browser angezeigt werden kann?
procedure Tcomplete.cmd_GenerateExecute(Sender: TObject);
begin with Sender as TAction do begin Enabled := False; GeneratePage(FileName); Enabled := True; end; end; Freundliche Grüße vom marabu |
Re: Datei kann nicht geschrieben werden - Warum und wie ände
Ja ich erstelle die Datei nur, um sie danach im TWebBrowser anzeigen zu können. Ich weiss worauf Du hinaus willst, aber ich nutze auch CSS, was bei der direkten Inhaltsübergabe nicht berücksichtigt wird.
Ich hatte schon vor Deinem Post den Button zu Beginn der Routine auf Visible := False gesetzt und ihn nach dem Erzeugen wieder sichtbar gemacht. Ich denke aber, dass da Enable wohl richtiger ist und werde wie von Dir vorgeschlagen auch noch die Routine auslagern. |
Re: Datei kann nicht geschrieben werden - Warum und wie ände
Deinen nervösen Finger kannst du überlisten,
indem du für die Dauer der Funktion den Button deaktivierst.
Delphi-Quellcode:
Heiko
Button.Enabled:= False;
try TuWas; finally Button.Enabled:= True; end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 16:13 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz