2008-09-18 8 views
5

읽기 나는 다음과 같은 코드를 가지고 :아스키되는 FileChannel와 파일 ByteArrays

 String inputFile = "somefile.txt"; 
     FileInputStream in = new FileInputStream(inputFile); 
     FileChannel ch = in.getChannel(); 
     ByteBuffer buf = ByteBuffer.allocateDirect(BUFSIZE); // BUFSIZE = 256 

     /* read the file into a buffer, 256 bytes at a time */ 
     int rd; 
     while ((rd = ch.read(buf)) != -1) { 
      buf.rewind(); 
      for (int i = 0; i < rd/2; i++) { 
       /* print each character */ 
       System.out.print(buf.getChar()); 
      } 
      buf.clear(); 
     } 

을하지만 문자가 표시 얻을의. 이것이 유니 코드 문자를 사용하는 Java와 관련이 있습니까? 이 문제를 어떻게 해결합니까?

답변

7

파일의 인코딩이 무엇인지 알아야하며 ByteBuffer를 해당 인코딩을 사용하는 CharBuffer로 디코딩해야합니다. 파일이 ASCII라고 가정하면 :

import java.util.*; 
import java.io.*; 
import java.nio.*; 
import java.nio.channels.*; 
import java.nio.charset.*; 

public class Buffer 
{ 
    public static void main(String args[]) throws Exception 
    { 
     String inputFile = "somefile"; 
     FileInputStream in = new FileInputStream(inputFile); 
     FileChannel ch = in.getChannel(); 
     ByteBuffer buf = ByteBuffer.allocateDirect(BUFSIZE); // BUFSIZE = 256 

     Charset cs = Charset.forName("ASCII"); // Or whatever encoding you want 

     /* read the file into a buffer, 256 bytes at a time */ 
     int rd; 
     while ((rd = ch.read(buf)) != -1) { 
      buf.rewind(); 
      CharBuffer chbuf = cs.decode(buf); 
      for (int i = 0; i < chbuf.length(); i++) { 
       /* print each character */ 
       System.out.print(chbuf.get()); 
      } 
      buf.clear(); 
     } 
    } 
} 
+0

각 문자를 개별적으로 인쇄하지 않으려면'buf.rewind()'대신'buf.flip()'을 사용하고 pass 전체 chbuf를'System.out.print()' – hertzsprung

0

예, 유니 코드입니다.

파일에 14 개의 Chars가있는 경우 7 개만 얻을 수 있습니다. '?

해결 방안. 아직도 생각하고있어.

1

당신이하는 방식대로 파일을 읽는 특별한 이유가 있습니까?

ASCII 파일을 읽는 경우 정말로 독자를 사용해야합니다.

File inputFile = new File("somefile.txt"); 
BufferedReader reader = new BufferedReader(new FileReader(inputFile)); 

을 그리고 readLine 또는 유사한 중 하나가 실제로 데이터를 읽기 위해 사용

나는 뭔가 같이 할 것입니다!

+1

나는 엄청난 양의 데이터를 가지고 있으며, 읽기 시간을 최적화하려고합니다. 참조 : http://nadeausoftware.com/articles/2008/02/java_tip_how_read_files_quickly – Jake

+0

@ Jake, 예제에서는 바이트를 읽고 char로 디코딩합니다. BufferedReader를 사용하는 것보다 빠르다고 생각하는 이유는 무엇입니까? 흥미로운 벤치 마크에서는 문자를 읽지 않습니다. –

2

에 인쇄 문을 변경 :

System.out.print((char)buf.get()); 

도움이 보인다.

3

buf.getChar()는 문자 당 2 바이트를 기대하고 있지만, 당신은 단지 1. 저장됩니다 somefile.txt의 인코딩에 따라

System.out.print((char) buf.get()); 
+0

당신이 코드를 수정하는 것을 잊었을 때 여전히 읽습니다. .get() –

2

를, 문자는 실제로 2 바이트로 구성 할 수 없습니다 . This page은 적절한 인코딩으로 스트림을 읽는 방법에 대한 자세한 정보를 제공합니다.

파일 시스템이 알 수 없기 때문에 파일 인코딩을 알려주지 않습니다. 관련해서는 바이트 수입니다. 인코딩을 프로그램에 전달하거나, 어떻게 든 감지하거나 (가능한 경우) 항상 인코딩이 동일하도록 보장해야합니다 (예 : UTF-8).