2012-09-03 20 views
5

मैं एक ऐसा एप्लिकेशन लिख रहा हूं जिसे नेटवर्क पर एक फाइल भेजने की आवश्यकता है। मुझे केवल सिखाया गया है कि अब तक मानक java.net और java.io कक्षाओं का उपयोग कैसे करें (कॉलेज के पहले वर्ष में) तो मुझे जावा.नियो और नेटटी और उन सभी अच्छी चीजों के साथ कोई अनुभव नहीं है। मैं इस प्रकार एक काम सर्वर/ग्राहक BufferedInput/OutputStreams और BufferedFile धाराओं के साथ-साथ सॉकेट और ServerSocket वर्गों का उपयोग सेट हो जाने पर,:मैं अपने जावा इनपुट/आउटपुट/फ़ाइल धाराओं को ठीक से कैसे बफर कर सकता हूं?

सर्वर:

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!"); 
    } 
} 

और ग्राहक:

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!"); 
    } 
} 

पहले मैं कोई बफरिंग नहीं कर रहा था, और प्रत्येक int को .read() से लिख रहा था। मुझे विंडोज 7 पर अपने नेटवर्क मॉनीटर गैजेट के अनुसार लगभग 200 केबी/एस हस्तांतरण मिला। मैंने इसे ऊपर के रूप में बदल दिया लेकिन 4096 बाइट बफर का इस्तेमाल किया और उसी गति को मिला, लेकिन फ़ाइल प्राप्त आमतौर पर स्रोत फ़ाइल की तुलना में कुछ किलोबाइट्स थी, और यही मेरी समस्या है। मैंने बफर आकार को 8192 में बदल दिया और अब मुझे अपने लैपटॉप पर वायरलेस पर लगभग 3.7-4.5 एमबी/सेकेंड ट्रांसफर मिलता है, जो अब काफी तेज़ है, लेकिन मुझे अभी भी फ़ाइल की समस्या थोड़ी बड़ी है (जो इसका कारण बनती है एक एमडी 5/शा हैश परीक्षण में विफल होने के लिए) जब यह प्राप्त होता है।

तो मेरा सवाल यह है कि सभ्य गति प्राप्त करने के लिए बफरिंग का सही तरीका क्या है और दूसरी तरफ एक ही फाइल के साथ समाप्त होता है? थोड़ा तेज़ी से जाने के लिए यह भी अच्छा होगा लेकिन अब मैं गति से खुश हूं। मुझे लगता है कि एक बड़ा बफर एक बिंदु तक बेहतर है, मुझे बस यह पता लगाने की जरूरत है कि वह बिंदु क्या है।

उत्तर

5

आप वास्तव में पढ़ने वाले डेटा के आकार को अनदेखा कर रहे हैं।

while (in.read(b) != -1) { 
    fout.write(b); 
} 

हमेशा 8 बाइट बाइट पढ़ेगा, भले ही केवल एक बाइट पढ़ा जाए। इसके बजाय मैं का उपयोग कर

for(int len; ((len = in.read(b)) > 0;) 
    fout.write(b, 0, len); 

आपका बफ़र्स अपने बाइट [] तो वे वास्तव में इस समय कुछ भी करने से नहीं कर रहे हैं के रूप में एक ही आकार के हैं सुझाव देते हैं।

अधिकांश नेटवर्क के लिए एमटीयू लगभग 1500 बाइट्स है और आपको 2 केबी तक धीमे नेटवर्क (1 जीबी तक) पर प्रदर्शन सुधार मिलता है। 8 केबी ठीक है। इससे बड़ा होने में मदद करने की संभावना नहीं है।

+0

आह, मुझे इसे हराया। – martijno

+0

@martijno एक संकेत मुझे धीमा करने की जरूरत है। ;) –

+0

मैं समस्या के कारण डेटा आकार के हिस्से को अनदेखा कर रहा हूं लेकिन मुझे समझ में नहीं आता कि लूप के लिए। ऐसा लगता है जैसे यह आगे बढ़ता है और केवल बफर से उस बिंदु तक डेटा लिखता है जहां वास्तविक सामग्री समाप्त होती है - क्या यह सही है? संपादित करें: आपके पास एक बहुत सारे ब्रैकेट हैं, "((len = ..." होना चाहिए "(len = ..." – Logan