InputStream.available () का उपयोग करना
यह हमेशा 0 वापस करने के लिए System.in.available () के लिए स्वीकार्य है।
मैंने इसके विपरीत पाया है - यह हमेशा उपलब्ध बाइट्स की संख्या के लिए सर्वोत्तम मूल्य देता है। के लिए Javadoc InputStream.available()
:
Returns an estimate of the number of bytes that can be read (or skipped over)
from this input stream without blocking by the next invocation of a method for
this input stream.
समय / गतिहीनता के कारण एक अनुमान अपरिहार्य है। आंकड़ा एकबारगी कम हो सकता है क्योंकि नए डेटा लगातार आ रहे हैं। हालांकि यह हमेशा अगली कॉल पर "कैच अप" करता है - यह सभी आये हुए डेटा के लिए खाता होना चाहिए, बार जो कि नए कॉल के क्षण में आता है। स्थायी रूप से 0 लौटने पर जब डेटा ऊपर की स्थिति में विफल रहता है।
पहला कैविट: इनपुटस्ट्रीम के ठोस उपवर्ग उपलब्ध हैं () के लिए जिम्मेदार हैं
InputStream
एक अमूर्त वर्ग है। इसका कोई डेटा स्रोत नहीं है। यह उपलब्ध डेटा के लिए अर्थहीन है। इसलिए, javadoc available()
भी बताता है:
The available method for class InputStream always returns 0.
This method should be overridden by subclasses.
और वास्तव में, कंक्रीट इनपुट स्ट्रीम क्लासेस ओवरराइड करते हैं (), सार्थक मान प्रदान करते हुए, निरंतर 0s नहीं।
दूसरा कैविएट: सुनिश्चित करें कि आप विंडोज में इनपुट टाइप करते समय गाड़ी-वापसी का उपयोग करें।
यदि उपयोग करते हैं System.in
, तो आपका प्रोग्राम केवल इनपुट प्राप्त करता है जब आपका कमांड शेल इसे सौंप देता है। यदि आप फ़ाइल पुनर्निर्देशन / पाइप (जैसे somefile> java myJavaApp या somecommand। Java myJavaApp) का उपयोग कर रहे हैं, तो इनपुट डेटा आमतौर पर तुरंत सौंप दिया जाता है। हालांकि, यदि आप मैन्युअल रूप से इनपुट टाइप करते हैं, तो डेटा हैंडओवर में देरी हो सकती है। उदाहरण के लिए विंडोज़ cmd.exe शेल के साथ, डेटा cmd.exe शेल में बफ़र किए जाते हैं। डेटा केवल कैरिज-रिटर्न (नियंत्रण-एम या <enter>
) के बाद निष्पादित जावा प्रोग्राम को दिया जाता है । यह निष्पादन पर्यावरण की एक सीमा है। बेशक, InputStream.available () शेल बफ़र्स को डेटा के रूप में लंबे समय तक 0 लौटाएगा - यह सही व्यवहार है; उस बिंदु पर कोई उपलब्ध डेटा नहीं हैं। जैसे ही डेटा शेल से उपलब्ध होता है, विधि एक मान> 0. NB: Cygwin cmd का उपयोग करती है।
सबसे सरल समाधान (कोई अवरुद्ध नहीं है, इसलिए कोई समय समाप्ति की आवश्यकता नहीं है)
बस इस का उपयोग करें:
byte[] inputData = new byte[1024];
int result = is.read(inputData, 0, is.available());
// result will indicate number of bytes read; -1 for EOF with no data read.
या समकक्ष,
BufferedReader br = new BufferedReader(new InputStreamReader(System.in, Charset.forName("ISO-8859-1")),1024);
// ...
// inside some iteration / processing logic:
if (br.ready()) {
int readCount = br.read(inputData, bufferOffset, inputData.length-bufferOffset);
}
अमीर समाधान (अधिकतम समय-समय पर बफर भरता है)
इसे घोषित करें:
public static int readInputStreamWithTimeout(InputStream is, byte[] b, int timeoutMillis)
throws IOException {
int bufferOffset = 0;
long maxTimeMillis = System.currentTimeMillis() + timeoutMillis;
while (System.currentTimeMillis() < maxTimeMillis && bufferOffset < b.length) {
int readLength = java.lang.Math.min(is.available(),b.length-bufferOffset);
// can alternatively use bufferedReader, guarded by isReady():
int readResult = is.read(b, bufferOffset, readLength);
if (readResult == -1) break;
bufferOffset += readResult;
}
return bufferOffset;
}
तो इस का उपयोग करें:
byte[] inputData = new byte[1024];
int readCount = readInputStreamWithTimeout(System.in, inputData, 6000); // 6 second timeout
// readCount will indicate number of bytes read; -1 for EOF with no data read.
is.available() > 1024
यह सुझाव विफल हो जाएगा। निश्चित रूप से ऐसी धाराएँ हैं जो शून्य पर लौटती हैं। उदाहरण के लिए SSLSockets हाल ही में। आप इस पर भरोसा नहीं कर सकते।