Progressbar für QFile::copy

Alles rund um die Programmierung mit Qt
Antworten
Linuxguru
Beiträge: 96
Registriert: 14. Januar 2007 02:09

Progressbar für QFile::copy

Beitrag von Linuxguru »

Hallo,

ich möchte beim Dateienkopieren gern eine Progressbar als Fortschrittsanzeige für die jeweilige Datei mit einbinden. Ich hab ein wenig experimentiert, allerdings kopieren die Dateien bei dieser Methode sehr langsam. Bei grossen Dateien (700MB) bekomme ich kein Fortschritt mehr angezeigt.

Hier mal mein Ansatz

Code: Alles auswählen

QFile src(curPath);
QFile dst(otherCurPath);
if(!src.open(QFile::ReadOnly) || !dst.open(QFile::WriteOnly)) return;
qint64 len = src.bytesAvailable();
ui->progressBar->setRange(0,len);
char ch;
while(!src.atEnd()){
    src.getChar(&ch);
    dst.putChar(ch);
    ui->progressBar->setValue(ui->progressBar->value()+1);
    qApp->processEvents();
}

Gibt es eine Möglichkeit, das auch mit dem wesentlich schnelleren QFile::copy umzusetzen?

Danke im Voraus
upsala
Beiträge: 3946
Registriert: 5. Februar 2006 20:52
Wohnort: Landshut
Kontaktdaten:

Beitrag von upsala »

Man kopiert auch nicht zeichenweise, sonder blockweise.
Linuxguru
Beiträge: 96
Registriert: 14. Januar 2007 02:09

Beitrag von Linuxguru »

Hab das ganze nun noch ein wenig umgebaut. Die Geschwindigkeit hat nun schon erheblich zugenommen. Für 700Mb brauche ich dennoch 2Min bei einer Sata 2 Platte. Mit QFile::copy geht das wesentlich schneller.

Code: Alles auswählen

QFile src(curPath);
QFile dst(otherCurPath);
if(!src.open(QFile::ReadOnly) || !dst.open(QFile::WriteOnly)) return;
qint64 len = src.size();
ui->progressBar->setRange(0,len);
while(!src.atEnd()){
	QByteArray line = src.readLine();
	QTextStream out(&dst);
	out << line << "\n";
	ui->progressBar->setValue(dst.size());
	qApp->processEvents();
}
Für weitere Ratschläge wäre ich dankbar.

MfG
upsala
Beiträge: 3946
Registriert: 5. Februar 2006 20:52
Wohnort: Landshut
Kontaktdaten:

Beitrag von upsala »

Und wie groß sind jetzt deine Blöcke?
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

upsala hat geschrieben:Und wie groß sind jetzt deine Blöcke?
Ich würde sagen - wesentlich zu klein, außer er hat ewig lange Zeile :lol:
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
Linuxguru
Beiträge: 96
Registriert: 14. Januar 2007 02:09

Beitrag von Linuxguru »

Wie kann ich die Blockgrösse bestimmen??

MfG
upsala
Beiträge: 3946
Registriert: 5. Februar 2006 20:52
Wohnort: Landshut
Kontaktdaten:

Beitrag von upsala »

In dem du entsprechende Blöcke vorgibst.

Also von einem Guru hätte ich mehr erwartet...
Linuxguru
Beiträge: 96
Registriert: 14. Januar 2007 02:09

Beitrag von Linuxguru »

@upsala, ich hab nie behauptet, das ich perfekt programmieren kann. Jeder hat seine Stärken woanders. Sonst bräuchte ich auch nicht ins Forum zu schreiben, wenn mir alles klar wäre.

Aber vielleicht hast du ja noch ein Tip für mich.

Ich hab nun mit QDataStream folgendes erarbeitet

Code: Alles auswählen

QFile src(curPath);
QFile dst(otherCurPath);

QDataStream in(&src);
QDataStream out(&dst);

if (!src.open(QIODevice::ReadOnly))
	return;
if (!dst.open(QIODevice::WriteOnly))
	return;

int bytes = 1024;
char* data = new char[bytes];

qint64 len = src.size();
ui->progressBar->setRange(0,len);

while(!in.atEnd());
{
	out.writeRawData(data, bytes);
	ui->progressBar->setValue(dst.size());
	qApp->processEvents();
}
src.close();
dst.close();
Der kopiert soweit auch, die Progressbar macht auch ihren Dienst. Allerdings habe ich dann unterschiedliche Grössen in den Dateien.

Meine Quelldatei ist 700MB und meine Zieldatei hab ich bei 2,5gb abgebrochen.

Wo könnte das Problem liegen?
-=Freaky=-
Beiträge: 503
Registriert: 29. Dezember 2006 22:54
Wohnort: HL

Beitrag von -=Freaky=- »

ueberseh ich da was, oder schreibst du dieselben 1024 bytes immer wieder in out (dst), ohne einmal aus in (src) zu lesen?

mfg,
julian
pfid
Beiträge: 535
Registriert: 22. Februar 2008 16:59

Beitrag von pfid »

Du könntest auch QFile::copy nehmen und die Dateigröße der Ausgabedatei pollen, bspw. mit QFileSystemWatcher. Wie genau/erträglich das für kleine Dateien ist, weiß ich jedoch nicht.
upsala
Beiträge: 3946
Registriert: 5. Februar 2006 20:52
Wohnort: Landshut
Kontaktdaten:

Beitrag von upsala »

Man könnte auch mal die Streams weglassen, mit QIODevice::read()/write() arbeiten und mal vernünftige Blockgrößen von mehreren 100kByte verwenden
Linuxguru
Beiträge: 96
Registriert: 14. Januar 2007 02:09

Beitrag von Linuxguru »

ok, nun hab ichs.

Hab heute morgen den Code nochmal komplett neu geschrieben. Hatte da einiges verdreht.

Danke an alle
Antworten