Download



  • Hallo. Was muss ich tun um alle möglichen Sachen runterzuladen? Also Bilder, Archive, videos, audios, etc. . Reicht es wenn ich da einfach so mir alle Bytes per, sagen wir mal dem BufferedInputStream, hole und so wie ich sie kriege einfach per FileWriter irgendwo hinschreibe? Oder muss ich da was beachten?

    Danke!



  • Also zumindest mit nem jpg Bild hat das eben FAST geklappt. Also da hat noch was unten gefehlt. Ich dachte mir das vielleicht mit einmal lesen nich alles da war und wollte deswegen das machen:

    BufferedInputStream in = new BufferedInputStream(socket.getInputStream());
                        int size = 0;
                        while ((size = in.available()) == 0);
                        Vector v = new Vector(1);
                        do {
                            byte[] buffer = new byte[size];
                            in.read(buffer, 0, size);
                            v.add(v);
                        } while((size = in.available()) != 0);
                        BufferedOutputStream os = new BufferedOutputStream(new FileOutputStream(outputFile, true));
                        for (int i = 0; i < v.size(); ++i) {
                            byte[] b = (byte[])v.get(i);
                            os.write(buffer, 0, buffer.length);
                        }
                        output = "File downloaded...";
    

    Das habe ich halt mal so probiert. Nun dann tritt ein Fehler beim casten in der Zeile "byte[] b = v.get(i)" auf. Nun ich weis ja nicht ob sowas überhaupt geht, aber ich GLAUBE schon. Also scheinbar gehts nicht, wie kann ich es sonst probieren?



  • Also bei einem nächsten Versuch ist dann doch alles angekommen. Und bei noch einem nächsten nur wieder die Hälfte. Woran liegt sowas, und kann man mit dem lustigen code da oben sowas "beheben"?

    Danke!



  • in .available() hilft dir nicht viel weiter.
    Du musst den Rückgabewert von in.read() auswerten.

    try {
            BufferedInputStream in = new BufferedInputStream(new java.net.URL("http://www.informatik.uni-freiburg.de/~asalm/cos.gif").openStream()); 
                        int size; 
                        Vector v = new Vector(1); 
                        do {
                            byte[] buffer = new byte[1000]; 
                            size=in.read(buffer, 0, 1000);
                            if(size<0) break;
                            if(size<1000) {
                                byte[] buffer2=new byte[size];
                                System.arraycopy(buffer, 0, buffer2, 0, size);
                                buffer=buffer2;
                            }
                            v.add(buffer); 
                        } while(true); 
                        BufferedOutputStream os = new BufferedOutputStream(new FileOutputStream("k:\\test2.gif"));
                        for (int i = 0; i < v.size(); ++i) { 
                            byte[] buffer = (byte[])v.get(i); 
                            os.write(buffer, 0, buffer.length); 
                        }
                        os.close();
                        System.out.println("File downloaded...");
    
            } catch (Exception e) {
                e.printStackTrace();
            }
    


  • Man sollte vielleicht nochmal erwähnen, dass hier das:

    os.close();
    

    auch eine seeeehr wichtige Rolle spielt.
    Da das .close() ein .flush() ausführt, bevor der Stream geschlossen wird.
    Das .flush() sorgt dafür, dass alle Daten, die noch im Stream vorhanden sind und noch nicht versendet wurden, versendet werden.

    😃 🤡
    Ist halt wie beim Pippi machen:
    es bleibt so lange ein Rest in der Schüßel, bis man die Spülung(flush) drückt
    Und mit close, wird der Deckel dann geschlossen...
    nur ist der Stream im Gegensatz zu einer Toilette nicht wiederverwendbar 😉
    😃 🤡



  • Danke für die Antowrten, ich werde das gleich mal ausprobieren! 🙂

    Aber noch ein paar Fragen. Warum soll mir available nichtzs bringen? Es kann doch aus irgendeinem Grund sein, dass ich gerade keine Bytes lesen kann. Da ist es doch besser kurz zu warten als gleich den Download unvollendet abzubrechen, oder? Und außerdem spart es Speicher wenn ich vorher mit available die Anzahl der ankommenden Bytes feststellen kann.

    } else {
                        BufferedInputStream in = new BufferedInputStream(socket.getInputStream());
                        int size = 0;
                        while ((size = in.available()) == 0);
                        LinkedList l = new LinkedList();
                        int f = 0;
                        do {
                            System.out.print("||");
                            byte[] buffer = new byte[size];
                            f = in.read(buffer, 0, size);
                            l.add(buffer);
                            while ((size = in.available()) == 0) {
                               // vielleicht nach ein paar ms aufhören zu warten und einen neuen Versuch starten, wenn oder da nicht alles angekommen ist? Was ja mit Überprüfen des Rückgabetyps von read mögl wäre?**
                            }
    
                        } while((size = in.available()) != 0 && f != -1);
    
                        BufferedOutputStream os = new BufferedOutputStream(new FileOutputStream(outputFile, true));
                        for (int i = 0; i < l.size(); i++) {
                            byte[] b = (byte[])l.get(i);
                            os.write(b, 0, b.length);
                        }
                        os.close();
                        in.close();
                        output = "File downloaded...\n";
                    }
    

    ** Ja, also wäre es Möglich einfach folgendes zu tun um zu überprüfen ob das letzte byte gesendet wurde:

    f = in.read(new byte[1], 0, 0);

    Das ist jetzt kein Gemecker, halte mich nicht für undankbar. Dein code funktion wenigstens. Der den ich hier erneut gepostet habe nicht wirklich. Wobei mir diese Variante in einer funktionierenden Version recht lieb wäre. Aber ansonsten würde ich gerne deinen Algorithmus nehmen. Aber könntest du mir bitte deinen code ein bisschen erklären? Ich seh nicht so recht durch. Mit den 2 buffern und der 1000 und wo du da das array kopierst.

    Danke für die Hilfestellung für einen Bedürftigen! 🙂



  • in.read() wartet automatisch solange bis er lesen kann oder aber bis das Ende des InputStream erreicht ist, also bis der Download beendet ist.
    Und ob der Download beendet ist oder nicht erkennt man daran das in.read() eine -1 zurückliefert. Das heisst man muss in.read() einfach nur solange wiederholen bis es -1 liefert. Dann ist der Download beendet.
    in.available() ist wirklich nicht nötig.

    In meinem Code lese ich einfach immer jeweils 1000 bytes ein und häng das an den Vector an.
    Es kann dabei aber vorkommen, dass in.read() mal weniger als 1000 bytes liest, z.B. am Ende des Downloads. Wenn die Datei 5034 bytes groß ist, dann ist das nicht glatt durch 1000 teilbar.
    in.read() liefert die Anzahl der gelesenen bytes zurück.
    Wenn er also weniger als 1000 bytes gelesen hat, z.B. nur 34, dann muss ich das array entsprechend verkleinern. Dafür erstelle ich ein 2. array in das ich dann den Inhalt des 1. arrays reinkopiere.



  • Ok, ich glaube jetzt hjabe ich´s!

    } else {
                        BufferedInputStream in = new BufferedInputStream(socket.getInputStream());
                        int size = 0;
                        while ((size = in.available()) == 0);
                        LinkedList l = new LinkedList();
                        do {
                            if (size < 0) break;
                            System.out.print("||");
                            byte[] buffer = new byte[size];
                            size = in.read(buffer, 0, size);
                            l.add(buffer);
                        } while(true);
                        System.out.println("size: " + size);
                        BufferedOutputStream os = new BufferedOutputStream(new FileOutputStream(outputFile, true));
                        for (int i = 0; i < l.size(); i++) {
                            byte[] b = (byte[])l.get(i);
                            os.write(b, 0, b.length);
                        }
                        os.close();
                        in.close();
                        output = "File downloaded...\n";
                    }
    

    😃

    Also Danke für alles!!!! 🙂



  • Dann nimmt er für die buffergrösse aber das size vom letzten mal. Das wird nicht gut gehen.
    Was ist, wenn size = 1000 ist und beim nächsten mal ist es 500?

    Dann liest er ein: size = in.read(buffer, 0, size);
    Da size erst 1000 war versucht er jetzt 1000 bytes einzulesen.
    Wenn er tatsächlich aber nur 500 bytes einliest was ist dann?
    Dann ist dein buffer zwar 1000 bytes groß aber nur die ersten 500 bytes von buffer sind mit sinnvollen Daten belegt.



  • Danke, verstehe! 🙂

    Also jetzt klappt´s perfekt, auch ohne verschwendung von Speicher auf RAM und HD! 😃


Anmelden zum Antworten