|
Dunedain
(Gast)
n/a Beiträge |
#1
Hallo,
brauche mal wieder eure Hilfe. Hab mir ein Programm geschrieben, dass zwei Verzeichnisse synchronsiert. Während dem Synchronisierungsvorgang, welcher in einem einzelnen Thread abläuft, möchte ich den Gesamtstatus des Synchronisierens, sowie den Kopierstatus der aktuellen Datei mit einer ProgressBar (JVCL v3.2 TJvXPProgressBar) anzeigen. Dafür habe ich mich an einem Code Snippet von ![]() Das Kopieren funzt tadelos, jedoch wird die ProgressBar nicht richtig(?), bzw. zu unregelmäßig(?) aktualisiert. ( Bei nem 1.4 GB Image wird die ProgressBar nur einmal aktualisiert, bei nem 700 MB Image is nach ca 50% schluss) Nachfolgend mal der Code für den Kopiervorgang, sowie die über Synchronize aufgerufene Funktion, welche das Statusfenster bedient.
Code:
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(); } Auch hier am Ende nochmal der Hinweis, dass Programmieren NUR ein Hobby von mir ist, daher bin ich nicht nur für Rat und Tat zum Fehler, sondern auch für Anregungen zum Programmierstiel dankbar (sofern so etwas bei mir erkennbar ist). ![]() Btw, Schönes Wochenende ![]() |
![]() |
Ansicht |
![]() |
![]() |
![]() |
ForumregelnEs ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.
BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus. Trackbacks are an
Pingbacks are an
Refbacks are aus
|
|
Nützliche Links |
Heutige Beiträge |
Sitemap |
Suchen |
Code-Library |
Wer ist online |
Alle Foren als gelesen markieren |
Gehe zu... |
LinkBack |
![]() |
![]() |