Чтение файла ASCII с помощью FileChannel и ByteArrays - PullRequest
5 голосов
/ 18 сентября 2008

У меня есть следующий код:

        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 с использованием символов Юникода? Как мне исправить это?

Ответы [ 6 ]

7 голосов
/ 18 сентября 2008

Вы должны знать, какова кодировка файла, а затем декодировать 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();
        }
    }
}
3 голосов
/ 18 сентября 2008

buf.getChar () ожидает 2 байта на символ, но вы сохраняете только 1. Используйте:

 System.out.print((char) buf.get());
2 голосов
/ 18 сентября 2008

В зависимости от кодировки somefile.txt символ на самом деле может не состоять из двух байтов. Эта страница дает дополнительную информацию о том, как читать потоки с правильной кодировкой.

Облом - файловая система не сообщает вам кодировку файла, потому что она не знает. Насколько это касается, это просто куча байтов. Вы должны либо найти какой-нибудь способ сообщить кодировку программе, как-то ее обнаружить, либо (если возможно) всегда убедиться, что кодировка одинакова (например, UTF-8).

2 голосов
/ 18 сентября 2008

Изменение вашего оператора печати на:

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

Кажется, чтобы помочь.

1 голос
/ 18 сентября 2008

Есть ли конкретная причина, по которой вы читаете файл так, как вы это делаете?

Если вы читаете в ASCII-файле, вам действительно следует использовать Reader.

Я бы сделал что-то вроде:

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

А затем используйте либо readLine или аналогичный для фактического чтения данных!

0 голосов
/ 18 сентября 2008

Да, это Unicode.

Если в вашем файле 14 символов, вы получите только 7 '?'.

Решение в ожидании. Все еще думаю.

...