Seite 1 von 1

Daten von QFile in QTcpSocket kopieren

Verfasst: 19. Mai 2008 21:26
von marco
Hallo!

Hab da mal eine kurze Frage, da ich nicht weiß wie QFile und QTcpSocket intern arbeiten.
Ich möchte Daten von einem QFile in ein QTcpSocket schreiben.

Was ist performanter, bzw. wie würdet ihr es machen?

Code: Alles auswählen

  #define BLOCKSIZE 8192
  char *data = new char[BLOCKSIZE];
  quint64 read = device->read(data, BLOCKSIZE);
  while (read > 0) {
    tcpSocket.write(data, read);
    read = device->read(data, BLOCKSIZE);
  }
  delete[] data;
oder schlicht

Code: Alles auswählen

tcpSocket.write(device->readAll());
Da die Dateien sehr groß sein können (durchaus mal 2GB), bereitet mir Letzteres auch noch bei heutigen RAM-Preisen Bauchschmerzen, falls es dabei kein Memory Mapping o.ä. gibt! Welche Rolle spielt evnt. das Betriebssystem?

Oder gibts vielleicht einen anderen, besseren Weg, Daten aus verschiedenen QIODevice-Objekten hin- und her zu kopieren?

1000 Dank!

Marco

Verfasst: 19. Mai 2008 21:31
von Christian81
Ich les immer in einen Puffer (QByteArray) und schreibe diesen dann weg. Allerdings solltest Du auch schauen ob write() alle Daten geschrieben hat.

Dein delete ist übrigens falsch - genau aus solchen Gründen würde ich QByteArray benutzen.

Verfasst: 19. Mai 2008 21:37
von upsala
Zum einen würde ein ein QByteArray verwenden und zum anderen QProgressDialog so daß man einen Status bekommt und der restliche Prozess noch weiterlaufen kann. Das mit dem Blockweise ist schon in Ordnung, auch die Blockgröße würde ich so wählen.

Verfasst: 19. Mai 2008 21:48
von marco
> Allerdings solltest Du auch schauen ob write() alle Daten geschrieben hat.

...schon klar, ich würds auch so wie oben nicht konkret implementieren.

Na gut, dann werd ich wohl ein QByteArray als Puffer bemühen... Vielen Dank!!

Nachtrag...

Verfasst: 20. Mai 2008 10:56
von marco
Hallo nochmal,

ich habs mit 1000 Dateien von meiner Festplatte (ext3) gemessen und um den Faktor 3,4 schneller gegenüber der Lösung QIODevice/QByteArray gings bei mir unter Linux 2.6.24 dank mmap in etwa so:

Code: Alles auswählen

  char* t_data = (char*)mmap(0, size, PROT_READ, MAP_SHARED, fd, 0);
  quint64 pos = 0;
  while (TRUE) {
    if (pos+BLOCKSIZE < size) {
      tcpSocket.write(t_data, BLOCKSIZE);
      t_data += BLOCKSIZE;
      pos += BLOCKSIZE;
    } else {
      tcpSocket.write(t_data, size-pos);
      break;
    }
  }

Verfasst: 20. Mai 2008 11:00
von Christian81
mmap() ist aber nicht portabel -> http://doc.trolltech.com/4.4/qfile.html#map

Aber danke für den Hinweis - ich wusste zwar dass es map() gibt aber das es so viel schneller ist hätte ich nicht gedacht.