2013-11-13 5 views
1
file = new RandomAccessFile(filename, "rw"); 
channel = file.getChannel(); 
MappedByteBuffer buffer = channel.map(FileChannel.MapMode.READ_ONLY, 0, channel.size()); 
buffer.load(); 
for (int i = 0; i < buffer.limit(); i++) 
{ 
     System.out.print((char) buffer.getChar()); 
} 

Однако это выплевывает символы UTF8. Я знаю, что здесь что-то не хватает!Java: FileChannel MappedByteBuffer to UTF8

+2

Вы должны использовать CharBuffer или CharsetDecoder, но здесь нет актуального вопроса. – EJP

ответ

2

Во-первых, здесь есть некоторая путаница в вашей терминологии (я думаю). Символы Java - это UTF-16, а не UTF-8. Вы бы не ожидали, чтобы увидеть символы UTF-8 в char. (На самом деле, UTF-8 использует между 1 и 5 bytes для кодирования одного Unicode кодовой точки. Во многих случаях UTF-8 кодирование символа не будет вписываться в char ...)

Этих терминологический путаница означает, что я не могу быть уверен, что вы на самом деле пытаетесь сделать, или то, что вы на самом деле видите. Поэтому я собираюсь догадаться, что вы на самом деле пытаетесь прочитать файл, который (по вашему мнению) закодирован в UTF-8 ... или, может быть, в 7 или 8-битной кодировке, такой как ASCII или Latin-1.

В этом случае основная проблема заключается в том, что метод getChar() не делает то, что вы ожидаете.

Ваш код, кажется, предполагает, что getChar собирается (каким-то образом) позаботиться об декодировании «следующий символ» из байтов в буфере. Фактически, он делает, чтобы взять следующие два байта в буфере ... что они когда-либо ... объединить их (используя бит-мудрый «shift» и «or») и вернуть их как char. Результат не будет иметь большого сходства с символами исходного файла. В самом деле, вы, вероятно, получите случайную последовательность символов Юникода, со случайными «вещами», которые не печатаются или даже являются незаконными. (Некоторые значения char значения зарезервированы и либо не могут использоваться, либо их нельзя использовать в правильном порядке.)

Вторая проблема заключается в том, что ваша петля попытается «прочитать» больше символов, чем есть в буфер. Метод limit() возвращает количество байтов, а не количество символов.

Мой совет по существу тот же, что и EJP. Для текста используйте CharBuffer или CharsetDecoder.

Смежные вопросы