inputStream.available () 사용
System.in.available ()이 항상 0을 반환하는 것은 허용됩니다.
나는 그 반대를 찾았습니다-항상 사용 가능한 바이트 수에 가장 적합한 값을 반환합니다. 에 대한 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의 구체적인 하위 클래스는 available ()을 담당합니다.
InputStream
추상 클래스입니다. 데이터 소스가 없습니다. 사용 가능한 데이터를 갖는 것은 의미가 없습니다. 따라서 javadoc available()
도 상태를 나타냅니다.
The available method for class InputStream always returns 0.
This method should be overridden by subclasses.
실제로 구체적인 입력 스트림 클래스는 available 0을 재정 의하여 상수 0이 아닌 의미있는 값을 제공합니다.
두 번째주의 사항 : Windows에서 입력을 입력 할 때 캐리지 리턴을 사용하십시오.
를 사용하는 경우 System.in
명령 쉘이 넘겨 줄 때만 프로그램이 입력을받습니다. 파일 리디렉션 / 파이프를 사용하는 경우 (예 : somefile> java myJavaApp 또는 somecommand | java myJavaApp) 입력 데이터는 일반적으로 즉시 전달됩니다. 그러나 입력을 수동으로 입력하면 데이터 핸드 오버가 지연 될 수 있습니다. 예를 들어 Windows cmd.exe 셸을 사용하면 cmd.exe 셸 내에 데이터가 버퍼링됩니다. 캐리지 리턴 (control-m 또는 <enter>
) 다음에 실행중인 Java 프로그램으로 만 데이터가 전달됩니다 . 그것은 실행 환경의 한계입니다. 물론, 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
이 제안은 실패합니다. 0을 반환하는 스트림이 있습니다. 예를 들어 최근까지 SSLSockets. 당신은 이것에 의존 할 수 없습니다.