Ich schreibe eine Anwendung, die eine Datei über das Netzwerk senden muss. Ich habe bisher nur gelernt, wie man standard java.net und java.io Klassen benutzt (in meinem ersten Jahr am College), also habe ich keine Erfahrung mit java.nio und netty und all diesen netten Dingen. Ich habe eine funktionierende Server/Client bekam aufgebauter Sockel und ServerSocket- Klassen zusammen mit BufferedInput/OutputStreams und BufferedFile Ströme wie folgt:Wie kann ich meine Java Input/Output/File Streams richtig puffern?
Der Server:
public class FiletestServer {
static ServerSocket server;
static BufferedInputStream in;
static BufferedOutputStream out;
public static void main(String[] args) throws Exception {
server = new ServerSocket(12354);
System.out.println("Waiting for client...");
Socket s = server.accept();
in = new BufferedInputStream(s.getInputStream(), 8192);
out = new BufferedOutputStream(s.getOutputStream(), 8192);
File f = new File("test.avi");
BufferedInputStream fin = new BufferedInputStream(new FileInputStream(f), 8192);
System.out.println("Sending to client...");
byte[] b = new byte[8192];
while (fin.read(b) != -1) {
out.write(b);
}
fin.close();
out.close();
in.close();
s.close();
server.close();
System.out.println("done!");
}
}
Und der Kunde:
public class FiletestClient {
public static void main(String[] args) throws Exception {
System.out.println("Connecting to server...");
Socket s;
if (args.length < 1) {
s = new Socket("", 12354);
} else {
s = new Socket(args[0], 12354);
}
System.out.println("Connected.");
BufferedInputStream in = new BufferedInputStream(s.getInputStream(), 8192);
BufferedOutputStream out = new BufferedOutputStream(s.getOutputStream(), 8192);
File f = new File("test.avi");
System.out.println("Receiving...");
FileOutputStream fout = new FileOutputStream(f);
byte[] b = new byte[8192];
while (in.read(b) != -1) {
fout.write(b);
}
fout.close();
in.close();
out.close();
s.close();
System.out.println("Done!");
}
}
Zuerst verwendete ich keine Pufferung und schreibe jedes int von in.read(). Das hat mir ungefähr 200kb/s Übertragung gemäß meinem Netzwerkmonitor-Gadget auf Windows 7 gebracht. Ich änderte es dann wie oben, aber verwendete 4096 Byte Puffer und bekam die gleiche Geschwindigkeit, aber die empfangene Datei war normalerweise ein paar Kilobyte größer als die Quelldatei. und das ist mein Problem. Ich habe die Puffergröße auf 8192 geändert und erhalte jetzt eine Übertragung von 3,7-4,5 MB/Sek. Über WLAN auf meinen Laptop, was momentan ziemlich schnell genug ist, aber ich habe immer noch das Problem, dass die Datei etwas größer wird (was sie verursachen würde) einen md5/sha-Hash-Test fehlschlagen, wenn es empfangen wird.
Also meine Frage ist, was ist die richtige Art der Pufferung, um anständige Geschwindigkeiten zu erhalten und am Ende mit genau der gleichen Datei auf der anderen Seite? Es wäre auch schön, es ein bisschen schneller zu machen, aber ich bin jetzt mit der Geschwindigkeit zufrieden. Ich gehe davon aus, dass ein größerer Puffer bis zu einem gewissen Grad besser ist. Ich muss nur herausfinden, was dieser Punkt ist.
Ah, schlag mich dazu. – martijno
@martijno Ein Zeichen, das ich verlangsamen muss. ;) –
Ich verstehe das Ignorieren der Datengröße Teil verursacht das Problem, aber ich verstehe das nicht für Schleife. Es sieht irgendwie so aus, als würde es auf eine Art vorauslesen und schreibt nur Daten aus dem Puffer bis zu dem Punkt, an dem der eigentliche Inhalt endet - ist das korrekt? EDIT: Sie haben eine zu viele Klammern, "((len = ..." sollte sein "(len = ..." – Logan