2014-02-13 2 views
1

사용하지 않는 readLine() 기능이 필요하고 입력 파일의 정확한 파일 형식을 알 수 없으므로 DataInputStream을 사용해야합니다 (즉, 어떤 줄 끝이 사용되는지). 바이너리 인코딩 된 프리미티브를 읽는다.DataInputStream readLine() 더 이상 사용되지 않음

이이 질문에 유사합니다

Is there a class that exposes an unbuffered readLine method in Java?

나의 제안이

public class SaveDataInputStream extends DataInputStream { 
    public SaveDataInputStream(InputStream in) {super(in);} 
    public String readLineSave() throws IOException { 
    // ??? 
    } 
} 

같은 것을 사용하고에서 찾을 수 있습니다 내의 readLine() 메소드의 콘텐츠를 사용하는 것입니다 DataInputStream 클래스 (이것은 참조 된 질문에서 허용되는 대답과 유사합니다). 그러나 나는 왜 메소드가 사용되지 않는지 완전히 이해하지 못하고 그것이 내 코드와 관련이 있는지를 알고 싶어한다.

javadoc의 말 : 이 메서드는 바이트를 문자로 올바르게 변환하지 않습니다.

하지만 그 의미는 무엇입니까? 그 점에 대해 걱정해야하며 최악의 경우 어떻게 될 수 있습니까? 문제를 해결하는 자체 메서드를 작성하는 것이 가능합니까 (효율성은 실제로 문제가되지 않습니다)?

힌트 : 새로운 BufferedReader (new InputStreamReader (..)); 정답이 아닙니다 ...

+1

파일을 작성하는 데 사용 된 코드를 보여 주면 파일을 읽는 방법을 더 쉽게 알 수 있습니다. –

답변

2

100 % 확신 할 수는 없지만, BufferedReader.readLine()과 비교하여 제대로 작동하지 않는 메서드를 발견했습니다. 여기에 코드입니다 : 기본적으로

import java.io.*; 

public class HelloWorld { 
    public static void main(String[] args) throws Exception { 
    String s = "喜\n"; 
    InputStream in = new ByteArrayInputStream(s.getBytes()); 
    DataInputStream d = new DataInputStream(in); 
    System.out.println(d.readLine()); // prints å 

    in = new ByteArrayInputStream(s.getBytes()); 
    BufferedReader br = new BufferedReader(new InputStreamReader(in)); 
    System.out.println(br.readLine()); // prints 喜 
    } 
} 

,()의 DataInputStream는 전혀 기본적으로 문자 다음에 = (문자)를 수행하기 때문에 멀티 바이트 문자를 처리하는 in.read 표시되지 않습니다 각 문자.

기본적으로 멀티 바이트 문자를 올바르게 읽으려면 최소한 아주 작은 버퍼가 필요하다고 생각합니다. 즉, 멀티 바이트 문자를 제대로 처리 할 수 ​​있으므로 BufferedReader 대신 직접 InputStreamReader 위에 사용자 정의 메서드를 작성할 수 있습니다. 또는 항상 ascii를 다루려고한다는 것을 알고 있다면 사용되지 않는 메소드를 사용하면 안전 할 수 있습니다.

EDIT : 라인 엔딩을 적절하게 처리하기 위해 DataInputStream도 내부적으로 버퍼링한다는 점도 주목할 가치가 있습니다. jdk7에서 적어도 \ r에 대한 처리는 다음

  case '\r': 
      int c2 = in.read(); 
      if ((c2 != '\n') && (c2 != -1)) { 
       if (!(in instanceof PushbackInputStream)) { 
        in = new PushbackInputStream(in); 
       } 
       ((PushbackInputStream)in).unread(c2); 
      } 
      break loop; 

따라서, 우리는 \ 가시 같은에서, A는 다시 읽지 바이트의 내부 버퍼를 유지하는 푸시 백 입력 스트림 상 읽지이다 발생할 경우.

+0

readLine() 메서드가 실패한 예제를 제공하므로이 대답을 수락하십시오. 변환 문제를 해결하는 방법에 대해 확신 할 수는 없지만 입력 한 내용이 ASCII 일 뿐이므로 실제로 나에게 관심사는 아닙니다. – vincent

4

readLine()이 문자를 제대로 변환하지 못하기 때문에 더 이상 사용되지 않는다는 것은 문자 인코딩을 지정할 수 없다는 것입니다 (예 : UTF-8 vs. CP1252). 즉, 한 문자 인코딩을 사용하여 작성된 데이터는 다른 문자 인코딩을 기본값으로 사용하는 시스템을 읽으면 실패 할 가능성이 높습니다.

그래서 걱정할 필요가 있습니까? 확실한. 메소드가 향후에 사라질 가능성이있는 것을 개발자에게 경고하기 위해서, 메소드는 추천되지 않습니다. JavaDoc에 따르면 readLine()은 JDK 1.1에서 더 이상 사용되지 않을 예정이었습니다.

버퍼링 때문에 BufferedReader을 원하지 않는 점에 관해서는 사용하지 말라고 말하고 싶습니다. Reader을 확장하는 다른 클래스 중 하나를 사용하거나, 극단적 인 것으로 원한다면 자신의 롤을 사용하십시오. DataInputReader라는 클래스를 직접 만들지 말고, 원시 코드를 읽는 방법을 고수하고, 필요에 따라 적절한 readLine() 구현을 제공 할 수 있습니다.

그러나 바이너리 인코딩 된 데이터를 읽는 중이라면 초를 읽고 직접 변환을 처리 할 수 ​​있도록 판독기를 사용하지 말고 InputStream을 사용하는 것이 좋습니다. Reader은 문자 인코딩을 염두에두고 설계되었으므로 이진 데이터를 문자열로 변환하려고한다는 전제하에 읽고있는 내용을 수정하는 경향이 있습니다.

관련 문제