bool TSearchThread::FileCopy( AnsiString sSourceFile,
AnsiString sDestFile )
{
bool bRetVal = false; // Rückgabewert
DWORD liBytesReadTotal = 0; // Anz. der bereits kopierten Bytes
int iBytesLastWrite = 0; // Anz. der im aktuellen
// Schleifendurchlauf kopierten Bytes
int iBytesLastRead = 0; // Anz. der in Lesepuffer eingelesenen
// Bytes
// Falls Namen der Ziel- und Quelldatei identisch, abbrechen:
if( !sDestFile.AnsiCompareIC( sSourceFile ) ) return false;
// Falls ein Verzeichnis als Name der Zieldatei übergeben wurde, Namen der
// Quelldatei an den Verzeichnisnamen anhängen:
int iAttr = FileGetAttr( sDestFile );
if( iAttr == -1 && (iAttr & faDirectory) == iAttr )
{
sDestFile = sDestFile + ExtractFileName( sSourceFile );
}
// Unterverzeichnis im Zielverzeichnis anlegen, falls das geforderte
// Verzeichnis nicht existiert
AnsiString sDir = ExtractFileDir( sDestFile );
if(!Jvvcl5utils::DirectoryExists( sDir ) )
{
Jvvcl5utils::ForceDirectories( sDir );
}
// Quelldatei öffnen:
iSourceHandle = FileOpen( sSourceFile.c_str(),
fmOpenRead | fmShareDenyWrite );
if( iSourceHandle > 1 )
{
// Die Dateigrösse ermitteln:
ulFileSize = FileSeek( iSourceHandle, 0, 2 );
FileSeek( iSourceHandle, 0, 0 );
if( ulFileSize != -1 )
{
// Anzeige zurücksetzen:
iCopyStatus = 0;
Synchronize( Status );
Application->ProcessMessages();
// Zieldatei öffnen:
iTargetHandle = FileCreate( sDestFile.c_str() );
if( iTargetHandle >= 0 )
{
// Schreib- / Lesepuffer erzeugen:
char *cpBuffer = new char[ iBufferSize ];
if( cpBuffer )
{
bRetVal = true;
while( liBytesReadTotal < ulFileSize )
{
// Daten aus der Quelldatei in den Puffer lesen:
iBytesLastRead = FileRead( iSourceHandle, cpBuffer, iBufferSize );
// Fehler aufgetreten:
if( iBytesLastRead == -1 )
{
bRetVal = false;
}
// Falls Daten eingelesen:
else if( iBytesLastRead != 0 )
{
// Daten aus dem Puffer in die Zieldatei schreiben:
iBytesLastWrite = FileWrite( iTargetHandle, cpBuffer, iBytesLastRead );
// Falls Anzahl der gelesenen Bytes != der Anzahl der geschriebenen...
if( iBytesLastRead != iBytesLastWrite ) bRetVal = false;
liBytesReadTotal += iBytesLastWrite;
}
// Fortschritt anzeigen:
// Hier wird vermutlich der Fehlerteufel gewütet haben :|
if( ( ( liBytesReadTotal * 100 / ulFileSize ) >= ( iCopyStatus + 1 )
|| iBytesLastRead != iBytesLastWrite
|| liBytesReadTotal == ulFileSize ) )
{
iCopyStatus = liBytesReadTotal * 100 / ulFileSize;
Synchronize(Status);
}
Application->ProcessMessages();
if( !bRetVal ) break;
}
delete [] cpBuffer;
}
// Dateien schliessen:
FileClose( iSourceHandle );
FileClose( iTargetHandle );
//
WinAPI
// Falls keine Fehler aufgetreten
// Zeitstempel übernehmen
if( bRetVal )
{
FILETIME ftCreate, ftAccess, ftWrite;
// Quelldatei zum lesen des Dateidatums öffnen
hSource = CreateFile( sSourceFile.c_str(),
GENERIC_READ,
FILE_SHARE_READ,
0,
OPEN_EXISTING,
0,
0);
//
Handle der Quelldatei überprüfen
if( hSource )
{
// Zieldatei zum schreiben des Dateidatums öffnen
hTarget = CreateFile( sDestFile.c_str(),
GENERIC_WRITE,
FILE_SHARE_READ,
0,
OPEN_EXISTING,
0,
0);
//
Handle der Zieldatei überprüfen
if( hTarget )
{
GetFileTime( hSource, &ftCreate, &ftAccess, &ftWrite );
bRetVal = SetFileTime( hTarget, &ftCreate, &ftAccess, &ftWrite );
// Datei wieder schliessen
CloseHandle( hTarget );
}
else
{
bRetVal = false;
}
// Datei wieder schliessen
CloseHandle( hSource );
}
else
{
bRetVal = false;
}
}
if( !bRetVal )
{
// Erstellte Dateiteile bei aufgetretenem Fehler
// entfernen
DeleteFile( sDestFile );
}
}
}
else
{
FileClose( iSourceHandle );
}
}
return bRetVal;
}
void __fastcall TSearchThread::Status( void )
{
// ProgressBar aktualisieren
// -> prüfen, ob Aktualisierung notwendig
// => nur notwendig, wenn sich die Position geändert hat
if( formStatus->progressbarStatus->Position != iStatus )
{
formStatus->progressbarStatus->Position = iStatus;
formStatus->progressbarStatus->Update();
}
// ProgressBar aktualisieren
// -> prüfen, ob Aktualisierung notwendig
// => nur notwendig, wenn sich die Position geändert hat
if( formStatus->progressbarCopyStatus->Position != iCopyStatus )
{
formStatus->progressbarCopyStatus->Position = iCopyStatus;
formStatus->progressbarCopyStatus->Update();
}
// Status Bar aktualisieren
// -> prüfen, ob Aktualisierung notwendig
// => nur notwendig, wenn sich der Text geändert hat
if( formStatus->statusbarStatus->SimpleText != sStatus )
{
formStatus->statusbarStatus->SimpleText = sStatus;
formStatus->statusbarStatus->Update();
}
// Dateianzahl anzeigen
// -> prüfen, ob Aktualisierung notwendig
// => nur notwendig, wenn sich der Text geändert hat
if( formStatus->labelStatusMax->Caption !=
AnsiString( slFileNames->Count ) )
{
formStatus->labelStatusMax->Caption = AnsiString( slFileNames->Count );
formStatus->labelStatusMax->Update();
}
// Dateigröße anzeigen
// -> prüfen, ob Aktualisierung notwendig
// => nur notwendig, wenn sich der Text geändert hat
if( formStatus->labelCopyStatusMax->Caption != AnsiString( ulFileSize ) )
{
formStatus->labelCopyStatusMax->Caption = AnsiString( ulFileSize );
formStatus->labelCopyStatusMax->Update();
}
Application->ProcessMessages();
}