Autor Beitrag
sintec
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 133



BeitragVerfasst: Di 24.04.07 13:51 
Hallo Leutz,

Ich habe ein kleines Programm geschrieben, mit dem ich Sicherungen durchführen möchte. Beim sichern zeigt es mir mit der Zeit den Fehler 'Ungültiges Argument zum Codieren des Datums'.
Ich weiß aber nicht woher er kommt und wie ich es beseitigen kann.
Das was ich sichere sind meisten große Ordner mit vielen Dateien, manchmal auch große Dateien,um die 1000 Dateien und insgesamt alles ca 50 GB.

Code von dem ganzem Programm:
ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
157:
158:
159:
160:
161:
162:
163:
164:
165:
166:
167:
168:
169:
170:
171:
172:
173:
174:
175:
176:
177:
178:
179:
180:
181:
182:
183:
184:
185:
186:
187:
188:
189:
190:
191:
192:
193:
194:
195:
196:
197:
198:
199:
200:
201:
202:
203:
204:
205:
206:
207:
208:
209:
210:
211:
212:
213:
214:
215:
216:
217:
218:
219:
220:
221:
222:
223:
224:
225:
226:
227:
228:
229:
230:
231:
232:
233:
234:
235:
236:
237:
238:
239:
240:
241:
242:
243:
244:
245:
246:
247:
248:
249:
250:
251:
252:
253:
254:
255:
256:
257:
258:
259:
260:
261:
262:
263:
264:
265:
266:
267:
268:
269:
270:
271:
272:
273:
274:
275:
276:
277:
278:
279:
280:
281:
282:
283:
284:
285:
286:
287:
288:
289:
290:
291:
292:
293:
294:
295:
296:
297:
298:
299:
300:
301:
302:
303:
304:
unit EWFileSave;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Menus, StdCtrls, shlobj, ComCtrls;

type
  TFileSave = class(TForm)
    MainMenu1: TMainMenu;
    Datei1: TMenuItem;
    N1: TMenuItem;
    Label1: TLabel;
    btn_dateipfad: TButton;
    Label2: TLabel;
    edt_sicherungspfad: TEdit;
    btn_sicherungspfad: TButton;
    btn_sichern: TButton;
    lsb_sicherung: TListBox;
    prb_status: TProgressBar;
    Neu1: TMenuItem;
    Beenden1: TMenuItem;
    procedure btn_dateipfadClick(Sender: TObject);
    procedure btn_sicherungspfadClick(Sender: TObject);
    procedure btn_sichernClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure Beenden1Click(Sender: TObject);
    procedure Neu1Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
    function OpenFolder(root: Integer; Caption: string): string;
    var dateipfad, sicherungspfad: string;
    var dateien, sicherung: TStringList;
  end;

var
  FileSave: TFileSave;

implementation

{$R *.dfm}

function MyGetFileSize(const FileName: String): Int64;
var
  hFile: THandle;
  Data: WIN32_FIND_DATA;
  Size: LARGE_INTEGER;
begin
  Result := -1;
  hFile := FindFirstFile(PChar(FileName), Data);
  try
    if hFile <> INVALID_HANDLE_VALUE then begin
      Size.LowPart := Data.nFileSizeLow;
      Size.HighPart := Data.nFileSizeHigh;
      Result := Size.QuadPart;
    end;
  finally
    Windows.FindClose(hFile);
  end;
end;

function ZeichenPosition(Eingabe, zeichen: String; anzahl: integer): Integer;
var i: integer;
    counter: integer;
    err: boolean;
begin;
  err := false;
  if zeichen = '' then
  begin
    Application.MessageBox(PChar('Bitte ein Trennzeichen angeben!'),
      'Fehler', MB_ICONERROR or MB_OK);
    err := true;
  end;

  i := 0;

  if not err then
  begin
    counter:= 0;

    //Schleife, die jedes einzelne Zeichen durchgeht
    for i:= 1 to length(Eingabe) do
    begin
      if Eingabe[i] = zeichen then //Wenn Zeichen = meinem Sonderzeichen
      inc(counter);

      if counter = anzahl then
        break
    end;
  end;  
    //Rückgabe setzen
    zeichenPosition := i;
end;

function zaehleZeichen(Eingabe, Zeichen: String): Integer;
var i: integer;
    counter: integer;
begin;

 counter:= 0;

 //Schleife, die jedes einzelne Zeichen durchgeht
 for i:= 1 to length(Eingabe) do
 begin
  if Eingabe[i] = zeichen then //Wenn Zeichen = meinem Sonderzeichen
   inc(counter);
 end;

 //Rückgabe setzen
 zaehleZeichen:= counter;

end;

function GetFileModifyDate(FileName: string): TDateTime;
var
  h: THandle;
  Struct: TOFSTRUCT;
  lastwrite: Integer;
  //t: TDateTime;
begin
  h := OpenFile(PChar(FileName), Struct, OF_SHARE_DENY_NONE);
  try
    if h <> HFILE_ERROR then
    begin
      lastwrite := FileGetDate(h);
    end;
  finally
    CloseHandle(h);
  end;
  Result := FileDateToDateTime(lastwrite);
end;


procedure GetAllFilesEM(Path, ExtMask: String; List: TStrings;
  SubFolder: Boolean);
var
  Attrib, k: Integer;
  Search: TSearchRec;
begin
  Attrib := faArchive + faReadOnly + faHidden;

  if Path[Length(Path)] <> '\' then Path := Path + '\';

  with TStringList.Create do
  try
    CommaText := ExtMask;

    for k := 0 to Count - 1 do
    if FindFirst(Path + '*.' + Strings[k], Attrib, Search) = 0 then
      repeat
        List.Add(AnsiUpperCase(Path + Search.Name));
      until FindNext(Search) <> 0;

    FindClose(Search);
  finally Free end;

  if SubFolder then
  begin
    if FindFirst(Path + '*.*', faDirectory, Search) = 0 then
    begin
      repeat
        if ((Search.Attr and faDirectory) = faDirectory) and
          (Search.Name[1] <> '.'then
          GetAllFilesEM(Path + Search.Name, ExtMask, List, SubFolder);
      until FindNext(Search) <> 0;

      FindClose(Search);
    end;
  end;
end{Popov}

function TFileSave.OpenFolder(root: Integer; Caption: string): string//Verzeichnis-Öffnen-Dialog-Funktion
var
  bi: TBrowseInfo;
  lpBuffer: PChar;
  pidlPrograms, pidlBrowse: PItemIDList;
begin
  if (not SUCCEEDED(SHGetSpecialFolderLocation(GetActiveWindow, root,
    pidlPrograms))) then
    exit;
  lpBuffer := StrAlloc(MAX_PATH);
  bi.hwndOwner := GetActiveWindow;
  bi.pidlRoot := pidlPrograms;
  bi.pszDisplayName := lpBuffer;
  bi.lpszTitle := PChar(Caption);
  bi.ulFlags := BIF_NEWDIALOGSTYLE;
  bi.lpfn := nil;
  bi.lParam := 0;

  pidlBrowse := SHBrowseForFolder(bi);
  if (pidlBrowse <> nilthen
    if SHGetPathFromIDList(pidlBrowse, lpBuffer) then
      Result := lpBuffer;
  StrDispose(lpBuffer);
end;

procedure TFileSave.Beenden1Click(Sender: TObject);
begin
close;
end;

procedure TFileSave.btn_dateipfadClick(Sender: TObject);
begin
  dateipfad := OpenFolder(CSIDL_DESKTOP, 'Verzeichnis wählen');
  lsb_sicherung.Items.Add(dateipfad);
end;

procedure TFileSave.btn_sichernClick(Sender: TObject);
var i,e,k,s,j,o, stepzaehler: integer;
var dateitmp, ordner: string;
var filesize: int64;
var err: boolean;
var drive: Char;
begin
  err := false;
  filesize := 0;
  for j := 0 to lsb_sicherung.Count -1 do
    GetAllFilesEM(lsb_sicherung.Items[j], '*', dateien, True);
    for o := 0 to dateien.Count - 1 do
    begin
      filesize := filesize + MyGetFileSize(dateien[o]);
      //application.MessageBox(PChar(inttostr(filesize)),'info',MB_OK);
    end;
  drive := edt_sicherungspfad.Text[1];
  if diskfree(ord(drive)-64) < filesize then
  begin
    err := true;
    application.MessageBox(PChar('Der Speicherplatz auf dem Sicherungdatenträger reicht für die sicherung nicht aus!'),'Speicherplatzmangel',MB_OK);
  end;
  application.MessageBox(PChar('Freispeicherplatz: ' + floattostrf(diskfree(ord(drive)-64) / 1073741824,fffixed,10,2) + ' GB'
    + #13 + 'Filesize: ' + floattostrf(filesize/1048576,fffixed,10,2) + ' MB'), 'info', MB_OK);
    

  if not err then
  begin
    e:=0;
    k:=0;
    prb_status.Visible := true;
    for s := 0 to lsb_sicherung.Count - 1 do
    begin
      ordner := copy(lsb_sicherung.Items[s],zeichenposition(lsb_sicherung.Items[s],
      '\',zaehleZeichen(lsb_sicherung.Items[s],'\'))+1,
      length(lsb_sicherung.Items[s]));
      GetAllFilesEM(lsb_sicherung.Items[s], '*', dateien, True);

      prb_status.Step := 0;
      stepzaehler := round(100 / dateien.Count);
      GetAllFilesEM(sicherungspfad, '*', sicherung, True);
      for i := 0 to dateien.Count - 1 do
      begin
        dateitmp := StringReplace(dateien[i], lsb_sicherung.Items[s], sicherungspfad + '/' + ordner,[rfReplaceAll,rfIgnoreCase]);
        if FileExists(dateitmp) then
        begin
         // application.MessageBox(PChar('Original: ' + DateTimeToStr(GetFileModifyDate(dateien[i]))
           //                    + #13 + 'Kopie:    ' + DateTimeToStr(GetFileModifyDate(dateitmp))),'info',MB_OK);
          if GetFileModifyDate(dateien[i]) <> GetFileModifyDate(dateitmp) then
          begin
            CopyFile(pchar(dateien[i]), pchar(dateitmp), false);
            inc(e);
          end;
        end
        else
        begin
          if not directoryexists(ExtractFilePath(dateitmp)) then
          if not ForceDirectories(ExtractFilePath(dateitmp)) then
          application.MessageBox(PChar(ExtractFilePath(dateien[i]) + ' konte nicht erstellt werden!'),Pchar('Info'),MB_ICONINFORMATION);
          CopyFile(pchar(dateien[i]), pchar(dateitmp), true);
          inc(k);
        end;
        prb_status.StepBy(stepzaehler);
      end;
    end;
    application.MessageBox(PChar('Die Sicherung wurde erfolgreich abgeschloßen'
      + #13 + 'neue Dateien: ' + inttostr(k)
      + #13 + 'ersetzte Dateien: ' + inttostr(e)),'Isch habe Fertisch',MB_ICONINFORMATION);
    prb_status.Visible := false;
  end;
end;

procedure TFileSave.btn_sicherungspfadClick(Sender: TObject);
begin
  sicherungspfad := OpenFolder(CSIDL_DESKTOP, 'Verzeichnis wählen');
  edt_sicherungspfad.text := sicherungspfad;

end;

procedure TFileSave.FormCreate(Sender: TObject);
begin
  dateien := TStringlist.Create;
  sicherung := TStringlist.Create;
  prb_status.Visible := false;
end;

procedure TFileSave.Neu1Click(Sender: TObject);
begin
dateien.Clear;
edt_sicherungspfad.Text := '';
lsb_sicherung.Clear;
end;

end.


Kann mir mal bitte einer helfen??

EDIT:
Nach ein paar großen Testdurchläufen habe ich festgestellt, dass er immer kurz vom Ende die Fehlermeldung ausgibt und dann fehlen 4 Dateien.


Zuletzt bearbeitet von sintec am Di 24.04.07 14:46, insgesamt 1-mal bearbeitet
noidic
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 851

Win 2000 Win XP Vista
D7 Ent, SharpDevelop 2.2
BeitragVerfasst: Di 24.04.07 14:46 
Such doch mal mit dem Debugger die genaue Stelle, wo der Fehler auftritt.

_________________
Bravery calls my name in the sound of the wind in the night...
Tastaro
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 414
Erhaltene Danke: 23



BeitragVerfasst: Di 24.04.07 15:29 
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
function GetFileModifyDate(FileName: string): TDateTime;  
var  
  h: THandle;  
  Struct: TOFSTRUCT;  
  lastwrite: Integer;  
  //t: TDateTime;  
begin  
  h := OpenFile(PChar(FileName), Struct, OF_SHARE_DENY_NONE);  
  try  
    if h <> HFILE_ERROR then  
    begin  
      lastwrite := FileGetDate(h);  
    end;  
  finally  
    CloseHandle(h);  
  end;  
  Result := FileDateToDateTime(lastwrite);  
end;


Ich tippe mal darauf, dass das Problem in dieser Funktion liegt.
Wenn die Datei nicht geöffnet werden kann, ist lastwrite beim Aufruf von FileDateToDateTime nämlich nicht initialisiert.

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
function GetFileModifyDate(FileName: string): TDateTime;  
var  
  h: THandle;  
  Struct: TOFSTRUCT;  
  lastwrite: Integer;  
  //t: TDateTime;  
begin  
  h := OpenFile(PChar(FileName), Struct, OF_SHARE_DENY_NONE);  
  if h <> HFILE_ERROR then  
  begin  
     lastwrite := FileGetDate(h);
     Result := FileDateToDateTime(lastwrite);
     CloseHandle(h);
   end
   else
      Result := 0;
end;


Merke: Achte auf die Warnungen deines Compilers und beseitige sie.

Beste Grüße
Tastaro
sintec Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 133



BeitragVerfasst: Mi 25.04.07 09:03 
Das stimmt Tastaro.

Die 4 Dateien sind neu dazu gekommen in der Zeit wo die Sicherung lief. Das Problem löse ich jetzt in dem er sich vorher merk, welche Dateien am Start da sind und nur die sichert er.

Viele Dank für den Tipp.
sintec Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 133



BeitragVerfasst: Mi 02.05.07 09:32 
Moin wieder,

Nach langem rum testen habe ich herausgefunden, dass es nur bei großen Datenmengen ist, wenn die Ordner klein sind, macht er es ohne Probleme.

Mir ist auch eingefallen, dass er beim umspringen auf den nächsten Ordner aus der Listenbox (lsb_sicherung) den Fehler ausgibt.

schritt für schritt ist er schwer bei solch großen Datenmengen zu kontrollieren.

Hat einer vielleicht ne andere Idee wie ich das kontrollieren oder sogar beseitigen kann?
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19312
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Mi 02.05.07 13:19 
Funktioniert der korrigierte Quelltext von user profile iconTastaro nicht? Geht der in das if rein und dann tritt dennoch der Fehler auf?
Wenn du es genau wissen willst und der Fehler zum Debuggen zu unregelmäßig Auftritt oder es zu viele Dateien sind, dann schreib einfach eine Logdatei.
Direkt nach dem Eintritt ins if eine Meldung in die Datei, dann nach dem GetFileDate den Wert von IntToStr(lastwrite), und dann nach dem FileDateToDateTime noch ne Meldung. Ist der Fehler dann aufgetreten, musst du nur ans Ende der Log-Datei gehen, dann siehst du wo der Fehler liegt...
Mach dir einfach ne Funktion WriteLog oder so und öffne und schließe dort auch einfach jedes mal die Datei, das ist am einfachsten, und für diesen Zweck hier ist die Performance ja egal.

Vielleicht bekommt lastwrite ja einen ungültigen Wert. So siehst du auch gleich welchen.