Kenobi van Gin
Brillenschlange
Hallo zusammen.
Ich melde mich mal wieder mit einer Frage zu C++ Nachdem in meinem Referenzbuch gerade das Thema lesen und schreiben in binären Dateien behandelt wurde, wollte ich gern eine eigene Konsolenanwendung im Stil von z.B. xcopy schreiben. Der Hintergrund ist, dass ich nach der Erstellung meines Backups (mit Personal Backup 5) als externes Programm immer eine Batch aufrufe, die via xcopy zwei TrueCrypt-Container kopiert. Da das unter bestimmten Umständen nicht reibungslos funktioniert (und ich ja auch noch etwas lernen will), habe ich mir nun also einen eigenen Code zum Kopieren von Dateien geschrieben.
Der auskommentierte Teil sollte eine einfach Progressbar anzeigen. Das hat auch im Prinzip funktioniert, war aber noch verbuggt und hat außerdem gefühlt einiges an Performance gefressen. Darum habe ich es vorerst durch eine einfach %-Anzeige ersetzt.
Erstmal meine eigenen Gedanken zum Code:
1.) Ist diese Art, Dateien zu kopieren, prinzipiell eine einigermaßen effiziente? Oder gibt es da Möglichkeiten, die wesentlich performanter oder weniger fehleranfällig sind?
2.) Der verwendete Lesepuffer ist hier, wie man sieht, nur 1 char (= 1 Byte?) groß. Ursprünglich wollte ich einen wesentlich größeren Puffer. Leider stellt sich da natürlich das Problem, dass bei Dateien, deren Größe kein Vielfaches der Puffergröße ist, jeweils die letzten Bytes nicht mehr kopiert werden. Nun könnte ich natürlich eine zusätzliche if-Abfrage einbauen, die dann für die letzten Bytes den Puffer wieder auf 1 setzt. Würdet ihr das so machen, oder gibt es da einen eleganteren Weg?
3.) Besonders bei großen Dateien fällt auf, dass meine Methode nicht die performanteste ist. Würde hier ein größerer Buffer (z.B. 128 oder sogar 256 Bytes) Abhilfe schaffen?
4.) Im Augenblick überprüft der Code noch nicht auf Fehler beim Öffnen der Ein- und Ausgabedatei. Das ist mir bewusst. Füge ich später noch hinzu
Ich bin gespannt auf eure Einschätzungen und vermute fast, dass ich es danach dann doch wieder komplett umschmeißen muss Aber ich bin ja hier, um zu lernen
Ich melde mich mal wieder mit einer Frage zu C++ Nachdem in meinem Referenzbuch gerade das Thema lesen und schreiben in binären Dateien behandelt wurde, wollte ich gern eine eigene Konsolenanwendung im Stil von z.B. xcopy schreiben. Der Hintergrund ist, dass ich nach der Erstellung meines Backups (mit Personal Backup 5) als externes Programm immer eine Batch aufrufe, die via xcopy zwei TrueCrypt-Container kopiert. Da das unter bestimmten Umständen nicht reibungslos funktioniert (und ich ja auch noch etwas lernen will), habe ich mir nun also einen eigenen Code zum Kopieren von Dateien geschrieben.
[src=cpp]void copyFile(string strSourcePath, string strDestinationPath)
{
ifstream readData;
ofstream writeData;
readData.open(strSourcePath, ios_base::binary | ios_base::in);
writeData.open(strDestinationPath, ios_base::binary | ios_base:ut);
unsigned long long lngSourceFileSize = getFileSize(strSourcePath);
unsigned long long lngBytesRead = 0;
int intCurrPercentage = 0;
int intLastPercentage = 0;
cout << " Copying file:" << endl << " 0 % done";
char Buffer;
while (readData.read(&Buffer, sizeof(Buffer)))
{
writeData.write(&Buffer, sizeof(Buffer));
lngBytesRead += sizeof(Buffer);
intCurrPercentage = round(100.0 / lngSourceFileSize * lngBytesRead);
if (intCurrPercentage > intLastPercentage)
{
cout << '\r';
cout << " " << intCurrPercentage << " % done";
intLastPercentage = intCurrPercentage;
}
/*
if (intCurrPercentage > intLastPercentage + 1)
{
cout << '\r';
cout << intCurrPercentage << " % |";
for (int i = 0; i <= intCurrPercentage; i++)
{
if (!(i % 2))
cout << '=';
}
cout << string(100 - intCurrPercentage, ' ') << "|";
intLastPercentage = intCurrPercentage;
}
*/
}
cout << endl << " Done!" << endl;
readData.close();
writeData.close();
}[/src]
{
ifstream readData;
ofstream writeData;
readData.open(strSourcePath, ios_base::binary | ios_base::in);
writeData.open(strDestinationPath, ios_base::binary | ios_base:ut);
unsigned long long lngSourceFileSize = getFileSize(strSourcePath);
unsigned long long lngBytesRead = 0;
int intCurrPercentage = 0;
int intLastPercentage = 0;
cout << " Copying file:" << endl << " 0 % done";
char Buffer;
while (readData.read(&Buffer, sizeof(Buffer)))
{
writeData.write(&Buffer, sizeof(Buffer));
lngBytesRead += sizeof(Buffer);
intCurrPercentage = round(100.0 / lngSourceFileSize * lngBytesRead);
if (intCurrPercentage > intLastPercentage)
{
cout << '\r';
cout << " " << intCurrPercentage << " % done";
intLastPercentage = intCurrPercentage;
}
/*
if (intCurrPercentage > intLastPercentage + 1)
{
cout << '\r';
cout << intCurrPercentage << " % |";
for (int i = 0; i <= intCurrPercentage; i++)
{
if (!(i % 2))
cout << '=';
}
cout << string(100 - intCurrPercentage, ' ') << "|";
intLastPercentage = intCurrPercentage;
}
*/
}
cout << endl << " Done!" << endl;
readData.close();
writeData.close();
}[/src]
Der auskommentierte Teil sollte eine einfach Progressbar anzeigen. Das hat auch im Prinzip funktioniert, war aber noch verbuggt und hat außerdem gefühlt einiges an Performance gefressen. Darum habe ich es vorerst durch eine einfach %-Anzeige ersetzt.
Erstmal meine eigenen Gedanken zum Code:
1.) Ist diese Art, Dateien zu kopieren, prinzipiell eine einigermaßen effiziente? Oder gibt es da Möglichkeiten, die wesentlich performanter oder weniger fehleranfällig sind?
2.) Der verwendete Lesepuffer ist hier, wie man sieht, nur 1 char (= 1 Byte?) groß. Ursprünglich wollte ich einen wesentlich größeren Puffer. Leider stellt sich da natürlich das Problem, dass bei Dateien, deren Größe kein Vielfaches der Puffergröße ist, jeweils die letzten Bytes nicht mehr kopiert werden. Nun könnte ich natürlich eine zusätzliche if-Abfrage einbauen, die dann für die letzten Bytes den Puffer wieder auf 1 setzt. Würdet ihr das so machen, oder gibt es da einen eleganteren Weg?
3.) Besonders bei großen Dateien fällt auf, dass meine Methode nicht die performanteste ist. Würde hier ein größerer Buffer (z.B. 128 oder sogar 256 Bytes) Abhilfe schaffen?
4.) Im Augenblick überprüft der Code noch nicht auf Fehler beim Öffnen der Ein- und Ausgabedatei. Das ist mir bewusst. Füge ich später noch hinzu
Ich bin gespannt auf eure Einschätzungen und vermute fast, dass ich es danach dann doch wieder komplett umschmeißen muss Aber ich bin ja hier, um zu lernen