Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi Datei kopieren (datei wird verwendet) (https://www.delphipraxis.net/121956-datei-kopieren-datei-wird-verwendet.html)

ghost007 7. Okt 2008 15:45


Datei kopieren (datei wird verwendet)
 
Kann man irgendwie eine datei, die gerade von einem anderen programm verwendet wird kopieren?

MfG - Ghost007

nahpets 7. Okt 2008 15:52

Re: Datei kopieren (datei wird verwendet)
 
Hallo,

ja :wink:

Was hast Du vor, willst Du selber kopieren oder per Batch oder per Explorer oder...

Meinst Du eventuell sowas?
Delphi-Quellcode:
iFileHandle := FileOpen('dateiname', fmShareDenyNone);
Damit lassen sich zumindest Dateien zum Lesen öffenen, in die der IIS gerade seine Protokolle schreibt, naja und lesen dürfte ja zum Kopieren reichen.

ghost007 7. Okt 2008 15:57

Re: Datei kopieren (datei wird verwendet)
 
hey,

ich will damit eine datei kopieren, eigentlich über das delphi interne CopyFile. Mal eine blöde frage :shock: wie kann ich dann über den filehandle die datei kopieren ? evtl auch mit tfilestream >.<

MfG - Ghost007

nahpets 7. Okt 2008 16:12

Re: Datei kopieren (datei wird verwendet)
 
Hallo,
Delphi-Quellcode:
iFileHandleIn := FileOpen(opendialog1.Files[l], fmShareDenyNone);
iFileLength := FileSeek(iFileHandleIn,0,2);
FileSeek(iFileHandleIn,0,0);
Buffer := PChar(AllocMem(iFileLength + 1));
iBytesRead := FileRead(iFileHandleIn, Buffer^, iFileLength);
FileClose(iFileHandle);
Jetzt ist die Datei in Buffer, und den dann mit FileWrite in eine andere Datei schreiben.
Delphi-Quellcode:
iFileHandleOut := FileCreate(SaveDialog1.FileName);
FileWrite(iFileHandleOut,Buffer,SizeOfBuffer));
FileClose(iFileHandleOut);
Das ist jetzt nur so "hingedaddelt", sollte aber vom Prinzip funktionieren. Wenn die Datei was größer ist, musst Du sie stückweise in Buffer lesen und dann schreiben.

ghost007 7. Okt 2008 16:29

Re: Datei kopieren (datei wird verwendet)
 
hm,
ich versuch gerade den fehler zu lokalisieren ... aber irgendwie erstelt er die dateien zwar alle, aber die haben 0KB und sind leer :D

EDIT:

hab mir folgende procedure draus gebastelt ...

Delphi-Quellcode:
procedure CopyEx(const FileName, NewFile: string);
 var
  iFileHandleIn,iFileLength,iBytesRead:integer;
  buffer:pointer;
  iFileHandleOut,sizeofbuffer:integer;
begin
 iFileHandleIn := FileOpen(filename, fmShareDenyNone);
 iFileLength := FileSeek(iFileHandleIn,0,2);
 FileSeek(iFileHandleIn,0,0);
 Buffer := PChar(AllocMem(iFileLength + 1));
 iBytesRead := FileRead(iFileHandleIn, Buffer^, iFileLength);
 FileClose(iFileHandleIn);
 iFileHandleOut := FileCreate(NewFile);
 FileWrite(iFileHandleOut,Buffer,SizeOfBuffer);
 FileClose(iFileHandleOut);
end;

Luckie 7. Okt 2008 16:53

Re: Datei kopieren (datei wird verwendet)
 
Etwas Fehlerbehandlung im Code hilft auch bei der Fehlersuche.

ghost007 7. Okt 2008 17:14

Re: Datei kopieren (datei wird verwendet)
 
Zitat:

Zitat von Luckie
Etwas Fehlerbehandlung im Code hilft auch bei der Fehlersuche.

Das problem ist wohl eher darin begründet, dass ich den code nichtmal verstehe :(

EDIT: hab das ganze mal so kommentiert wie ich denke, dass es abläuft ... bitte um korrektur
Delphi-Quellcode:
procedure TForm1.CopyEx(const FileName, NewFile: string);
 var
  iFileHandleIn,iFileLength,iBytesRead:integer;
  buffer:pointer;
  iFileHandleOut,sizeofbuffer:integer;
begin
 //holt sich das handle zum file
 iFileHandleIn := FileOpen(filename, fmShareDenyNone);
 //holt sich den pointer auf das ende des files
 iFileLength := FileSeek(iFileHandleIn,0,2);
 //setzt den pointer wieder auf den anfang des files
 FileSeek(iFileHandleIn,0,0);
 //reserviert speicher mit der größe des files
 Buffer := PChar(AllocMem(iFileLength + 1));
 //schreibt den inhalt der datei vom anfang bis zum pointer auf das ende in den buffer
 iBytesRead := FileRead(iFileHandleIn, Buffer^, iFileLength);
 //schliesst das file
 FileClose(iFileHandleIn);
 //erstellt ein neues file
 iFileHandleOut := FileCreate(NewFile);
 //schreibt den inhalt des buffers in das neue file
 FileWrite(iFileHandleOut,Buffer,SizeOfBuffer);
 //schliesst das neue file
 FileClose(iFileHandleOut);
end;

nahpets 8. Okt 2008 08:17

Re: Datei kopieren (datei wird verwendet)
 
Hallo,
Zitat:

Zitat von ghost007
Das problem ist wohl eher darin begründet, dass ich den code nichtmal verstehe :(

EDIT: hab das ganze mal so kommentiert wie ich denke, dass es abläuft ... bitte um korrektur
Delphi-Quellcode:
procedure TForm1.CopyEx(const FileName, NewFile: string);
 var
  iFileHandleIn,iFileLength,iBytesRead:integer;
  buffer:pointer;
  iFileHandleOut,sizeofbuffer:integer;
begin
 //holt sich das handle zum file
 iFileHandleIn := FileOpen(filename, fmShareDenyNone);
 //holt sich den pointer auf das ende des files
 iFileLength := FileSeek(iFileHandleIn,0,2);
 //setzt den pointer wieder auf den anfang des files
 FileSeek(iFileHandleIn,0,0);
 //reserviert speicher mit der größe des files
 Buffer := PChar(AllocMem(iFileLength + 1));
 //schreibt den inhalt der datei vom anfang bis zum pointer auf das ende in den buffer
 iBytesRead := FileRead(iFileHandleIn, Buffer^, iFileLength);
 //schliesst das file
 FileClose(iFileHandleIn);
 //erstellt ein neues file
 iFileHandleOut := FileCreate(NewFile);
 //schreibt den inhalt des buffers in das neue file
 FileWrite(iFileHandleOut,Buffer,SizeOfBuffer);
 //schliesst das neue file
 FileClose(iFileHandleOut);
end;

ich vermute, dass der Fehler hier liegt:
Delphi-Quellcode:
//schreibt den inhalt des buffers in das neue file
FileWrite(iFileHandleOut,Buffer,SizeOfBuffer);
müsste eher heißen:
Delphi-Quellcode:
//schreibt den inhalt des buffers in das neue file
FileWrite(iFileHandleOut,Buffer,iBytesRead);
SizeOfBuffer ist als Integer deklariert, bekommt aber keinen Wert zugewiesen und ist damit zufällig 0 und genausso groß ist auch die Datei. Mit iBytesRead sollten genauso viele Bytes geschrieben werden, wie vorher gelesen wurden.

Ansonsten schau mal unter http://www.delphicorner.f9.co.uk/articles/misc4.htm und dort unter Quick and Dirty Copying, da ist ein Beispiel, dass sicherlich besser ist als meines.

taaktaak 8. Okt 2008 09:03

Re: Datei kopieren (datei wird verwendet)
 
Es stellt sich aber grundasätzlich die Frage, ob es sinnvoll ist, eine Datei zu kopieren, die gerade in Benutzung eines anderen Programms ist. Das macht m.E. nur Sinn, wenn sichergestellt ist, dass die andere Anwendung nur lesenden Zugriff hat. Ist das in deinem speziellen Fall so?

nahpets 8. Okt 2008 09:08

Re: Datei kopieren (datei wird verwendet)
 
Hallo Ralf,
Zitat:

Zitat von taaktaak
Es stellt sich aber grundsätzlich die Frage, ob es sinnvoll ist, eine Datei zu kopieren, die gerade in Benutzung eines anderen Programms ist. Das macht m.E. nur Sinn, wenn sichergestellt ist, dass die andere Anwendung nur lesenden Zugriff hat. Ist das in deinem speziellen Fall so?

prinzipiell hast Du recht, für die Auswertung von Logfiles muss ich aber stündlich die Dateien auswerten, während die Software, die die Logfiles erstellt, diese nur alle 24 Stunden wechselt. Beim Kopieren von zum Schreiben geöffneten Dateien, habe ich nie den wirklich aktuellen Stand und ggfls. auch mal nicht verwertbare Dateiinhalte. Es ist also Vorsicht geboten.

ghost007 10. Okt 2008 07:23

Re: Datei kopieren (datei wird verwendet)
 
Zitat:

Zitat von nahpets
müsste eher heißen:
Delphi-Quellcode:
//schreibt den inhalt des buffers in das neue file
FileWrite(iFileHandleOut,Buffer,iBytesRead);
SizeOfBuffer ist als Integer deklariert, bekommt aber keinen Wert zugewiesen und ist damit zufällig 0 und genausso groß ist auch die Datei. Mit iBytesRead sollten genauso viele Bytes geschrieben werden, wie vorher gelesen wurden.

So gehts leider auch nicht :(

DeddyH 10. Okt 2008 08:27

Re: Datei kopieren (datei wird verwendet)
 
Ich habe die Prozedur mal "aufgebohrt".
Delphi-Quellcode:
procedure TForm1.CopyEx(const FileName, NewFile: string);
var
  iFileHandleIn,iFileLength,iBytesRead,iBytesWritten:integer;
  buffer:pointer;
  iFileHandleOut,sizeofbuffer:integer;
begin
  //holt sich das handle zum file
  iFileHandleIn := FileOpen(filename, fmShareDenyNone);
  if iFileHandleIn > -1 then
    begin
      //holt sich den pointer auf das ende des files
      iFileLength := FileSeek(iFileHandleIn,0,2);
      if iFileLength > -1 then
        begin
          //setzt den pointer wieder auf den anfang des files
          FileSeek(iFileHandleIn,0,0);
          //reserviert speicher mit der größe des files
          Buffer := PChar(AllocMem(iFileLength + 1));
          if Assigned(Buffer) then
            begin
              //schreibt den inhalt der datei vom anfang bis zum pointer auf das ende in den buffer
              iBytesRead := FileRead(iFileHandleIn, Buffer^, iFileLength);
              //erstellt ein neues file
              iFileHandleOut := FileCreate(NewFile);
              if iFileHandleOut > -1 then
                begin
                  //schreibt den inhalt des buffers in das neue file
                  iBytesWritten := FileWrite(iFileHandleOut,Buffer,SizeOfBuffer);
                  if iBytesWritten = -1 then
                    ShowMessage('Fehler bei FileWrite');
                  //schliesst das neue file
                  FileClose(iFileHandleOut);
                end
              else
                ShowMessage('Fehler bei CreateFile');
            end
          else
            ShowMessage('Buffer nicht zugewiesen');
        end
      else
        ShowMessage('Fehler bei FileSeek');
      //schliesst das file
      FileClose(iFileHandleIn);
    end
  else
    ShowMessage('Fehler bei Fileopen');
end;
Wenn ich nichts übersehen habe, solltest Du dem Fehler nun auf die Spur kommen können.

Kurt56 10. Okt 2008 09:13

Re: Datei kopieren (datei wird verwendet)
 
Zitat:

Zitat von DeddyH
Ich habe die Prozedur mal "aufgebohrt".
Delphi-Quellcode:
procedure TForm1.CopyEx(const FileName, NewFile: string);
var
  iFileHandleIn,iFileLength,iBytesRead,iBytesWritten:integer;
  buffer:pointer;
  iFileHandleOut,sizeofbuffer:integer;
begin
  //holt sich das handle zum file
  iFileHandleIn := FileOpen(filename, fmShareDenyNone);
  if iFileHandleIn > -1 then
    begin
      //holt sich den pointer auf das ende des files
      iFileLength := FileSeek(iFileHandleIn,0,2);
      if iFileLength > -1 then
        begin
          //setzt den pointer wieder auf den anfang des files
          FileSeek(iFileHandleIn,0,0);
          //reserviert speicher mit der größe des files
          Buffer := PChar(AllocMem(iFileLength + 1));
          sizeofbuffer:=iFileLength; //<<<--- die Bufferlänge gesetzt, fehlte noch

          if Assigned(Buffer) then
            begin
              //schreibt den inhalt der datei vom anfang bis zum pointer auf das ende in den buffer
              iBytesRead := FileRead(iFileHandleIn, Buffer^, iFileLength);
              //erstellt ein neues file
              iFileHandleOut := FileCreate(NewFile);
              if iFileHandleOut > -1 then
                begin
                  //schreibt den inhalt des buffers in das neue file
                  iBytesWritten := FileWrite(iFileHandleOut,Buffer^,SizeOfBuffer); //<<<---- das ^ bei Buffer eingefügt
//                                                         ----------
                  if iBytesWritten = -1 then
                    ShowMessage('Fehler bei FileWrite');
                  //schliesst das neue file
                  FileClose(iFileHandleOut);
                end
              else
                ShowMessage('Fehler bei CreateFile');
            end
          else
            ShowMessage('Buffer nicht zugewiesen');
        end
      else
        ShowMessage('Fehler bei FileSeek');
      //schliesst das file
      FileClose(iFileHandleIn);
    end
  else
    ShowMessage('Fehler bei Fileopen');
end;
Wenn ich nichts übersehen habe, solltest Du dem Fehler nun auf die Spur kommen können.

Zwei Kleinigkeiten hab ich noch geändert.
Damit geht es.

DeddyH 10. Okt 2008 09:16

Re: Datei kopieren (datei wird verwendet)
 
Thx, hatte eben nur C&P benutzt und nicht ausprobiert *g*

ghost007 10. Okt 2008 15:41

Re: Datei kopieren (datei wird verwendet)
 
also, der code von euch zwei schmeißt mir die meldung raus "fehler bei fileopen "


... :(

DeddyH 10. Okt 2008 15:48

Re: Datei kopieren (datei wird verwendet)
 
Also klappt schon der Anfang nicht. Hast Du mal so versucht?
Delphi-Quellcode:
iFileHandleIn := FileOpen(filename, fmOpenRead or fmShareDenyNone);

nahpets 10. Okt 2008 15:50

Re: Datei kopieren (datei wird verwendet)
 
Hallo,
Zitat:

Zitat von ghost007
also, der code von euch zwei schmeißt mir die meldung raus "fehler bei fileopen "


... :(

da gibt's nur zewi Möglichkeiten: Die Datei gibt's nicht, dass schließen wir aus oder das andere Programm hat sie exklusiv geöffnet.

Für das
Delphi-Quellcode:
iFileHandleIn := FileOpen(filename, fmShareDenyNone);
gibt es mehrere Möglichkeiten, eine weitere wäre
Delphi-Quellcode:
iFileHandleIn := FileOpen(filename, fmOpenRead or fmShareDenyNone);
In der Hilfe müsstest Du finden, welche Werte ausser fmShareDenyNone, fmOpenRead noch möglich sind. Such Dir diese bitte heraus und versuche es dann mit unterschiedlichen Kombinationen. Welche Kombination zu welchem Zeitpunkt richtig ist, kann ich Dir beim besten Willen nicht sagen.

[OT]und DeddyH ist schon wieder schneller als ich :x [/OT]

ghost007 11. Okt 2008 10:39

Re: Datei kopieren (datei wird verwendet)
 
könnte mir evtl jemand den auszug aus der hilfe hier posten? Unter vista kann ich die hilfe von Delphi 7 nicht mehr aufrufen -.- er sagt das format der hilfe-datei ist zu alt ....

Danke

jaenicke 11. Okt 2008 10:48

Re: Datei kopieren (datei wird verwendet)
 
Mit diesem Download von MS geht die alte Hilfe auch unter Vista ;-):
http://www.microsoft.com/downloads/d...0-334cd175d4bb

ghost007 11. Okt 2008 10:53

Re: Datei kopieren (datei wird verwendet)
 
Zitat:

Zitat von jaenicke
Mit diesem Download von MS geht die alte Hilfe auch unter Vista ;-):
http://www.microsoft.com/downloads/d...0-334cd175d4bb

muchas gracias

hamburcher 11. Okt 2008 13:14

Re: Datei kopieren (datei wird verwendet)
 
Was ist eigentlich aus "FileMode := 0" geworden?

Zitat:

Die Variable FileMode gibt den Zugriffsmodus für typisierte und nicht typisierte Dateien an, die mit Reset geöffnet werden.

Unit

System

Kategorie

Ein-/Ausgabe

var FileMode: Byte;

Beschreibung

FileMode legt den Zugriffsmodus fest, wenn typisierte und nicht typisierte Dateien (keine Textdateien) mit der Prozedur Reset geöffnet werden.

Der Standardwert von FileMode ist 2. Wenn Sie dieser Variablen einen anderen Wert zuweisen, wird der betreffende Modus bei allen folgenden Reset-Aufrufe verwendet.

FileMode kann folgende Werte annehmen:

0 Nur Lesen
1 Nur Schreiben
2 Lesen/Schreiben
Warnung: FileMode ist als Variable deklariert, nicht als threadvar. Deshalb ist diese Variabel nicht thread-sicher.

^ aus der Hilfe von D5.

DeddyH 11. Okt 2008 13:19

Re: Datei kopieren (datei wird verwendet)
 
Liest Du auch, was Du zitierst?
Zitat:

wenn typisierte und nicht typisierte Dateien (keine Textdateien) mit der Prozedur Reset geöffnet werden.
Ist ja hier nicht der Fall.


Alle Zeitangaben in WEZ +1. Es ist jetzt 04:18 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz