Tôi đang viết một ứng dụng cần gửi tệp qua mạng. Tôi chỉ được dạy cách sử dụng các lớp java.net và java.io tiêu chuẩn cho đến nay (trong năm đầu tiên của đại học) vì vậy tôi không có kinh nghiệm với java.nio và netty và tất cả những điều tốt đẹp đó. Tôi đã có một máy chủ làm việc/khách hàng thiết lập bằng lớp Socket và ServerSocket cùng với BufferedInput/OutputStreams và BufferedFile suối, như sau:Làm cách nào để đệm luồng đầu vào/đầu ra/tệp Java của tôi đúng cách?
Máy chủ:
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!");
}
}
Và khách hàng:
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!");
}
}
Lúc đầu, tôi đã không sử dụng bộ đệm và viết từng int từ in.read(). Điều đó đã cho tôi về 200kb/s chuyển theo tiện ích màn hình mạng của tôi trên windows 7. Sau đó tôi thay đổi nó như trên nhưng đã sử dụng bộ đệm 4096 byte và có cùng tốc độ, nhưng tệp nhận được thường lớn hơn vài kilobyte so với tệp nguồn, và đó là vấn đề của tôi. Tôi đã thay đổi kích thước bộ đệm thành 8192 và bây giờ tôi nhận được khoảng 3,7-4,5mb/giây chuyển qua mạng không dây đến máy tính xách tay của mình, hiện tại đủ nhanh, nhưng tôi vẫn gặp vấn đề về tệp lớn hơn một chút (điều này sẽ gây ra để thất bại một thử nghiệm băm md5/sha) khi nó được nhận.
Vì vậy, câu hỏi của tôi là cách thích hợp để đệm để có tốc độ tốt và kết thúc với chính xác cùng một tệp ở phía bên kia? Bắt nó đi nhanh hơn một chút cũng sẽ tốt hơn nhưng tôi rất vui với tốc độ hiện tại. Tôi giả sử một bộ đệm lớn hơn là tốt hơn đến một điểm, tôi chỉ cần tìm ra điểm đó là gì.
Ah, đánh tôi với nó. – martijno
@martijno Một dấu hiệu tôi cần phải làm chậm lại. ;) –
Tôi hiểu việc bỏ qua phần kích thước dữ liệu gây ra sự cố nhưng tôi không hiểu điều đó đối với vòng lặp. Nó trông giống như nó đọc trước một cách và chỉ ghi dữ liệu từ bộ đệm đến điểm mà nội dung thực tế kết thúc - đúng không? EDIT: bạn có một quá nhiều dấu ngoặc, "((len = ..." nên được "(len = ..." – Logan