Seite 1 von 1

Progressbar für QFile::copy

Verfasst: 11. Oktober 2009 13:13
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

Verfasst: 11. Oktober 2009 14:04
von upsala
Man kopiert auch nicht zeichenweise, sonder blockweise.

Verfasst: 11. Oktober 2009 15:20
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

Verfasst: 11. Oktober 2009 19:05
von upsala
Und wie groß sind jetzt deine Blöcke?

Verfasst: 11. Oktober 2009 19:10
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:

Verfasst: 11. Oktober 2009 19:22
von Linuxguru
Wie kann ich die Blockgrösse bestimmen??

MfG

Verfasst: 11. Oktober 2009 19:36
von upsala
In dem du entsprechende Blöcke vorgibst.

Also von einem Guru hätte ich mehr erwartet...

Verfasst: 12. Oktober 2009 00:12
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?

Verfasst: 12. Oktober 2009 03:08
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

Verfasst: 12. Oktober 2009 08:13
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.

Verfasst: 12. Oktober 2009 09:12
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

Verfasst: 12. Oktober 2009 17:09
von Linuxguru
ok, nun hab ichs.

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

Danke an alle