2012-04-13 14 views
15

पर एक इनपुटस्ट्रीम लिखें मेरे पास एक इनपुटस्ट्रीम है जिसे मैं एक HttpServletResponse पर लिखना चाहता हूं। वहाँ बाइट के उपयोग के कारण इस दृष्टिकोण है, जो बहुत समय लगता है है []एक HttpServletResponse

InputStream is = getInputStream(); 
int contentLength = getContentLength(); 

byte[] data = new byte[contentLength]; 
is.read(data); 

//response here is the HttpServletResponse object 
response.setContentLength(contentLength); 
response.write(data); 

मैं सोच रहा था क्या संभवतः यह करने के लिए सबसे अच्छा तरीका हो सकता है की गति और दक्षता के मामले में,।

उत्तर

41

बस इसे पूरी तरह से जावा की स्मृति में कॉपी करने के बजाय ब्लॉक में लिखें। नीचे मूल उदाहरण इसे 10 केबी के ब्लॉक में लिखता है। इस तरह आप पूरी सामग्री लंबाई के बजाय केवल 10 केबी के लगातार स्मृति उपयोग के साथ समाप्त होते हैं। इसके अलावा एंडुसर सामग्री के कुछ हिस्सों को जल्द से जल्द शुरू कर देगा।

response.setContentLength(getContentLength()); 
byte[] buffer = new byte[10240]; 

try (
    InputStream input = getInputStream(); 
    OutputStream output = response.getOutputStream(); 
) { 
    for (int length = 0; (length = input.read(buffer)) > 0;) { 
     output.write(buffer, 0, length); 
    } 
} 

creme de la creme के रूप में प्रदर्शन के संबंध में, आप NIO Channels इस्तेमाल कर सकते हैं और एक सीधे ByteBuffer आवंटित। कुछ कस्टम उपयोगिता वर्ग में निम्न उपयोगिता/सहायक विधि बनाएं, उदा। Utils:

public static long stream(InputStream input, OutputStream output) throws IOException { 
    try (
     ReadableByteChannel inputChannel = Channels.newChannel(input); 
     WritableByteChannel outputChannel = Channels.newChannel(output); 
    ) { 
     ByteBuffer buffer = ByteBuffer.allocateDirect(10240); 
     long size = 0; 

     while (inputChannel.read(buffer) != -1) { 
      buffer.flip(); 
      size += outputChannel.write(buffer); 
      buffer.clear(); 
     } 

     return size; 
    } 
} 

जो तुम तो नीचे के रूप में उपयोग करें: मैं, बाइट [] के उपयोग से बचने के लिए वान

response.setContentLength(getContentLength()); 
Utils.stream(getInputStream(), response.getOutputStream()); 
+0

मुझे उम्मीद थी कि एक और तरीका हो सकता है, लेकिन फिर भी –

+0

धन्यवाद बहुत कुछ धन्यवाद BalusC, –

+2

बेशक कई उपयोगिता पैकेजों में यह विधि पहले ही परिभाषित है, इसलिए एक बार जब आप गुवा का उपयोग करना शुरू कर देते हैं ... http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/io /ByteStreams.html#copy(java.io.InputStream, java.io.OutputStream) –

1
BufferedInputStream in = null; 
BufferedOutputStream out = null; 
OutputStream os; 
os = new BufferedOutputStream(response.getOutputStream()); 
in = new BufferedInputStream(new FileInputStream(file)); 
out = new BufferedOutputStream(os); 
byte[] buffer = new byte[1024 * 8]; 
int j = -1; 
while ((j = in.read(buffer)) != -1) { 
    out.write(buffer, 0, j); 
} 
+0

संभव –

+0

कोई रास्ता नहीं InputStream पढ़ने के लिए डब्ल्यू/का उपयोग कर ओ वहाँ @MuhammadSabry यदि ' बाइट [] ' –

+0

बाइट [] के साथ क्या गलत है। आपको डेटा को कुछ स्टोर करने की आवश्यकता है:} – MTilsted

0

मुझे लगता है कि यह सबसे अच्छा तरीका है, लेकिन मैं निम्नलिखित परिवर्तन का सुझाव दूंगा। एक निश्चित आकार बफर का उपयोग करें (20K कहें) और फिर लूप में पढ़ने/लिखें। , आपका कार्यक्रम हमेशा उसी रूप में काम नहीं करेगा क्योंकि पढ़ने हमेशा पूरे सरणी आप इसे देने को भरने नहीं है:

पाश के लिए की तरह

Byte buffer[]=new byte[20*1024]; 
outputStream=response.getOutputStream(); 
while(true) { 
    int readSize=is.read(buffer); 
    if(readSize==-1) 
    break; 
    outputStream.write(buffer,0,readSize); 
} 

ps कुछ करना।

+0

पढ़ने से आपका क्या मतलब है, जो आप इसे पूरा सरणी भरते हैं? –

+1

पढ़ना हमेशा इनपुट सरणी को भरता नहीं है। तो आपको उस मूल्य को जांचना होगा जो रिटर्न पढ़ता है जो कि बाइट्स पढ़ने की संख्या है। (Http://docs.oracle.com/javase/6/docs/api/java/io/InputStream.html#read%28byte[ ]%29 देखें) – MTilsted

संबंधित मुद्दे