Downloadfortschritt von Datei über Google Drive API v3

DanielFeiger

Mitglied
Hallo,

ich nutze folgenden Code um eine Datei (ca. 10 MB) über mein Google Drive herunterzuladen.

Java:
Drive.Files.Get get = SERVICE.files().get(file.getId());

get.getMediaHttpDownloader().setProgressListener(new ProgressListener());
get.getMediaHttpDownloader().setDirectDownloadEnabled(false);

get.getMediaHttpDownloader().setChunkSize(1000000);

Das Herunterladen von der Datei funktioniert, jedoch bekomme ich den aktuellen Downloadfortschritt nicht, obwohl ich einen MediaHttpDownloaderProgressListener übergeben habe, der mir bei jedem Update, den aktuellen Fortschritt ausgibt. Ich bekomme ungefähr alle 10 Sekunden die Nachricht "0.0" (Fortschritt bei 0%) und dann wenn die Datei fertig ist bekomme ich die Nachricht "1.0" (Fortschritt bei 100%)
Mein Listener sieht wie folgt aus:
Java:
public class ProgressListener implements MediaHttpDownloaderProgressListener {

public void progressChanged(MediaHttpDownloader downloader) {
    switch (downloader.getDownloadState()) {
        case MEDIA_IN_PROGRESS:
            System.out.println(downloader.getProgress());
            break;
        case MEDIA_COMPLETE:
            System.out.println("Download is complete!");
    }
}

Im Internet steht auch viel darüber, dass die ChunkSize geändert werden soll. Wenn ich sie jedoch ändere, dann wird die Datei unvollständig heruntergeladen.

Danke im Voraus!
 
Im Internet steht auch viel darüber, dass die ChunkSize geändert werden soll.
Das scheint mir auch der korrekte Weg zu sein. Die Chunk Size gibt an, wie viele Bytes mit einem Request max. abgerufen werden. Davon abhängig ist auch, wie oft der Listener informiert wird (ich würde mal davon ausgehen, dass das nach jedem Request passiert). Standardmäßig liegt die Chunk Size lt. Doku bei 32 MB.

Wenn ich sie jedoch ändere, dann wird die Datei unvollständig heruntergeladen.
Das sollte m. E. nicht passieren. Gibts Exceptions?
 
Bei 10 KB hättest Du 1000 Requests und mit jedem Request würden ca. 0,1 % der Daten abgerufen. Andersrum: 1 % von 10 MB sind 100 KB. Eine kleinere ChunkSize macht bzgl. des Fortschritts in Prozent keinen Sinn.
 
Bei 10 KB hättest Du 1000 Requests und mit jedem Request würden ca. 0,1 % der Daten abgerufen. Andersrum: 1 % von 10 MB sind 100 KB. Eine kleinere ChunkSize macht bzgl. des Fortschritts in Prozent keinen Sinn.
Da hast du vollkommen Recht... Ich habe jetzt mal die ChunkSize auf 100 KB (100 * 1024) gesetzt.
Ausgabe:

Progress: 0.014415605568759694
MS: 11769
Progress: 0.028831211137519387
MS: 12464
Progress: 0.04324681670627908
MS: 10024
Progress: 0.057662422275038774
MS: 12266
Progress: 0.07207802784379846
MS: 14896

"Progress": Zeigt den Fortschritt in Prozent an
"MS": Gibt die Zeitspanne an, wie lange es gedauert hat

Ich denke, dass mit der ChunkSize habe ich jetzt verstanden. Der Listener wird, warum auch immer, nur alle 10 - 15 Sekunden getriggert??

Eine andere Möglichkeit wäre, anhand den heruntergeladenen Bytes und der Dateigröße den Fortschritt zu berechnen.
Dazu habe mal folgenden Code probiert:

Java:
Drive.Files.Get get = SERVICE.files().get(file.getId());
get.getMediaHttpDownloader().setProgressListener(new DownloadProgressListener(progressBar)).setChunkSize(100 * 1024);
get.getMediaHttpDownloader().setDirectDownloadEnabled(false);

Timer t = new Timer();
t.scheduleAtFixedRate(new TimerTask() {
    @Override
    public void run() {
        long bytes = get.getMediaHttpDownloader().getNumBytesDownloaded();
        System.out.println(bytes);
    }
}, 0, 100);

Ausgabe:

0
0
0
0
0
Progress: 0.014415605568759694
MS: 15586
102400
102400
102400
102400
102400

Anscheinend dauert es wirklich solange bis ein Chunk heruntergeladen ist. Korrekt?
 
Anscheinend dauert es wirklich solange bis ein Chunk heruntergeladen ist.
Es sieht zumindest so aus, fände ich irgendwo aber strange: 15 Sekunden für 100 KiB? Tippt die Bytes jemand ab oder hast Du 'nen Akustikkoppler dran?!? (Dann aber bitte nicht sprechen, Husten ist ganz schlecht) 🙂

Wie ändert sich denn die Zeit, wenn Du ein Vielfaches n*100 KB als ChunkSize verwendest? Das sollte dann ja knapp das n-Fache sein.
 
Also wenn man sich die Implementierung von MediaHttpDownloader ansieht, stellt man fest dass fuer jeden Chunk eine HTTP-Anfrage an den Server gesendet wird. Das bedeutet je kleiner die Chunk-Size, desto mehr Anfragen, desto langsamer das Ganze. Der Stream wird in 8kB Bloecken gelesen und kopiert, da waere vielleicht 16k oder 32k besser gewesen, macht aber wahrscheinlich keinen richtigen Unterschied.

Ich vermute mal dass deine Leitung hier der Falschenhals ist, also dass die Anfrage selbst relativ lange braucht, das uebertragen der Daten selbst vermutlich aber relativ schnell.
 
Also wenn man sich die Implementierung von MediaHttpDownloader ansieht, stellt man fest dass fuer jeden Chunk eine HTTP-Anfrage an den Server gesendet wird. Das bedeutet je kleiner die Chunk-Size, desto mehr Anfragen, desto langsamer das Ganze. Der Stream wird in 8kB Bloecken gelesen und kopiert, da waere vielleicht 16k oder 32k besser gewesen, macht aber wahrscheinlich keinen richtigen Unterschied.

Ich vermute mal dass deine Leitung hier der Falschenhals ist, also dass die Anfrage selbst relativ lange braucht, das uebertragen der Daten selbst vermutlich aber relativ schnell.
Meine Leitung kann es eigentlich auch nicht sein. Ca. 60 Mbit Down und 85 Mbit Upload...

Habe jetzt mal 32.000 als ChunkSize genommen (320 * (100 * 1024)). Leider ohne Erfolg.
Ausgabe

0
0
0
0
Download is complete!

Bedeutetet, dass dieser Teil
Java:
case MEDIA_IN_PROGRESS:
    System.out.println(downloader.getProgress());
    break;

hier gar nicht ausgeführt wird.. Dementsprechend gibt er mir auch keinen Progress aus...
 
stellt man fest dass fuer jeden Chunk eine HTTP-Anfrage an den Server gesendet wird.
S. #2, das erklärt aber nicht, warum für 100 KB Chunk Size ~ 15 s und für 500 KB Chunk Size 21 s benötigt werden.

Ich vermute mal dass deine Leitung hier der Falschenhals ist, also dass die Anfrage selbst relativ lange braucht, das uebertragen der Daten selbst vermutlich aber relativ schnell.
Das kann ich mir wiederum kaum vorstellen: ein Overhead für einen HTTP-Request von über 10 s... da säße man ja einen ganzen Tag vor dem Rechner, um sich eine einzige Website anzuschauen 🙂

Aber ich kann hier nur noch spekulieren. Man könnte mal den Profiler anwerfen oder mit dem Debugger durchgehen bzw. die Requests per Hand (postman) durchführen und messen.
 

Zurück
Oben