2012-02-14 5 views
3

이것은 매우 간단해야하며 Google을 검색했지만 주목 한 문제를 언급 한 사람이 없습니다. 내가 본 모든 것은 똑같은 일을합니다. 내가 EOF에 도달하면 -1 반환하지만 파일이 버퍼 또는 같은 크기보다 작은 경우) (읽기 알고InputStream에서 읽고 OutputStream에 쓰기

byte [] buffer = new byte[256]; 
int bytesRead = 0; 
while((bytesRead = input.read(buffer)) != -1) 
{ 
    output.write(buffer, 0, bytesRead); 
} 

:이처럼? 폭스 예를 들어, 200 바이트 파일을 읽고있다. 나는 그것을 200 바이트 읽은 것으로 가정하지만 -1 반환합니다. 이는 javadocs와 일치하지만 write()가 호출되지 않는다는 것을 의미합니다. 실제로 200 바이트를 읽고 나면 다음 반복에서 -1을 반환한다고 말할 것입니다.

어떻게이 "문제"를 해결할 수 있습니까?

+0

'input'이 어떻게 생성되고'read()'를 호출하기 전에 어떻게되는지 보여줍니다. – erickson

+0

약자로,이 질문은 "불완전합니다." – erickson

+0

가능한 복제본 [Java InputStream의 내용을 OutputStream에 쓰는 쉬운 방법] (http://stackoverflow.com/questions/43157/easy-way-to-write-contents-of-a-java-inputstream-to) - 출력 스트림) – rds

답변

12

FYI GuavaByteStreams.copy(InputStream, OutputStream)입니다. 직접 사용하거나이 문제를 어떻게 해결할 수 있는지 확인하십시오.

+0

구아바, 나는 이것에 대해 들어 보지 못했다. 나는 많은 구글 자바 라이브러리가 매우 유용하다는 것을 알았다. copy() 코드를 살펴본 결과, 필자가하는 일을 본질적으로 수행하고 있지만 write()는 필자의 경우 결코 호출되지 않는다. 나는 나의 코드를 다시 한번 살펴볼 것이다. 이것이 내가 기대했던 방식입니다. 댓글을 달았던 모든 사람들이 말하는 것처럼. – Amac

1

비어 있지 않은 스트림의 끝을 감지하려면 최소한 read()을 두 번 호출해야합니다. 하나는 내용을 읽은 다음 다른 하나는 EOF를 반환합니다.

예를 들어, 버퍼가 256 바이트이고 파일이 200 바이트 인 경우 read(byte[])에 대한 호출은 200을 반환합니다 (또는 호출 결과 시퀀스가 ​​200으로 합계 됨). 이후 호출은 -1을 반환합니다. 신호 EOF.

그것은 당신이 InputStream을위한 자바 독을 해석 한 방법 완전히 명확하지 않다, 그러나 그것은 바이트 수를 읽어 반환 분명히 말한다, 반환 -1 읽기 전용으로 데이터가 더 이상 없었다.

b의 길이가 0이면 바이트가 읽히지 않고 0이 반환됩니다. 그렇지 않으면 적어도 하나의 바이트를 읽으려고합니다. 스트림이 파일의 끝에 있기 때문에 바이트 을 사용할 수없는 경우 -1 값이 반환됩니다. 그렇지 않으면 적어도 하나의 바이트를 읽고 b에 저장합니다. 또한

:

결과 : 총 버퍼에 판독 된 바이트 수 또는 -1이 더 이상 데이터는 스트림의 끝에 도달 [된다] 때문에 [경우].

+0

2 번 읽습니까? 이것은 내가 예상했던 것입니다.하지만 그렇지 않습니다. 내 파일이 내가 사용하는 버퍼보다 ​​작 으면 raad()에 대한 첫 번째 호출에서 -1을 반환합니다. 기술적으로 EOF에 도달했기 때문에 javadoc이 말한 것을 수행하고 있습니다. 그러나 읽은 200 바이트에 대해서는 아무 말도하지 않습니다. 내가 게시 한 while 루프를 사용하면 write()가 호출되지 않습니다. – Amac

+0

@ user1209868 그러면 코드의 다른 부분에 버그가 있습니다. (당신의 게시물은 파일을 열 때부터 -1이 반환하는 지점까지의 스트림의 전체 히스토리를 보여주지 않습니다.) 위에 인용 된 것처럼, 문서는 바이트를 읽을 수 있는지, 음수가 아닌지를 반환하는지 ; Javadoc는, ** 일부의 바이트를 읽어 들이면 (자), -1이 리턴된다고는하지 않습니다. 스트림이 비어 있거나 시작된 일부 조작이 보유한 데이터를 소비했습니다. – erickson

0

read()는 전체 파일을 읽을 때까지 읽은 바이트 수를 반환합니다. 더 이상 읽을 수 없으면 -1을 반환합니다. 스트림 파일의 끝에 바이트가없는 경우 the java documentation (1.4)

가입일

, 값 -1이 반환된다; 그렇지 않으면 적어도 하나의 바이트를 읽고 b에 저장합니다.

실제로 원하는대로합니다. 200 바이트 (또는 파일에 남아 있고 사용자가 제공 한 버퍼보다 ​​작음)를 읽고 다음 반복에서 -1을 리턴합니다.

+0

javadoc에서 말하는 내용을 이해합니다. read()를 호출하면 EOF에 도달 할 때까지 버퍼를 채 웁니다 (내 버퍼가 파일보다 큽니다). 그리고 문서에 나와 있듯이 -1을 반환합니다. 이 작업을 수행하고 있지만 처음에는 200 바이트를 읽은 다음 read()를 호출하면 -1을 반환한다고 알려 주면 안됩니다. – Amac

+0

@ user1209868 EOF 만 읽었을 때 -1을 반환하고 그 전에는 -1을 반환합니다. 뭔가를 읽으면 읽기 횟수를 반환합니다. – EJP

7

에 코드를 작동 확인

byte [] buffer = new byte[256]; 
int bytesRead = 0; 
while((bytesRead = input.read(buffer)) != -1) { 
    output.write(buffer, 0, bytesRead); 
} 
.예를 들어

는 문자 (300) (600 바이트)를 가진 파일이 상상 1. 버퍼는 256 바이트를 읽어 출력에 재기록한다

단계; 344는 EOF로 왼쪽

단계 2. 버퍼는 256 바이트를 읽고 출력으로 다시 씁니다. 88 왼쪽으로 EOF

단계 3. 버퍼는 88 바이트 (byteRead == 88)를 읽고 출력으로 다시 씁니다. EOF는 단계 위

이론없는 편집 ...

4 단계 EOF (input.read(buffer) 반환 -1)

을 떠났다. 이 코드를 사용하여 실제 파일 내용을 다시 쓰면 다음과 같이 표시됩니다.

static void rewrite() throws IOException { 
    InputStream input = new FileInputStream("file1.txt"); 
    OutputStream output = new FileOutputStream("file2.txt"); 
    byte[] buffer = new byte[256]; 
    int bytesRead = 0; 
    while ((bytesRead = input.read(buffer)) != -1) { 
     System.out.println(bytesRead); 
     output.write(buffer, 0, bytesRead); 
    } 
} 

어쩌면 설정에 다른 문제가있을 수 있습니다.

+0

이것은 내가 기대할 수있는 것이지만, 3 단계에서 -1로 돌아 간다. 내 코드를 다시 한 번 살펴 보겠다.하지만 이미 같은 결과로 몇 번 해봤 다. – Amac

+0

@ user1209868 편집보기 – msi

0

나는 그것이 200 바이트를 읽을 생각하지만, -1을 반환

번호 그것은 200 바이트를 읽고 이것은 자바 독에서 완벽하게 분명하다 (200) 반환, 당신은 그것을 시도 할 수 쉽게 충분히.

관련 문제