Философия Java3
Шрифт:
}
FileChannel
in = new FileInputStream(args[0]) getChannel. out = new FileOutputStream(args[l]) getChannelО; in.transferTo(0, in.sizeO. out); // Или-
// out transferFrom(in, 0. in.sizeO),
}
} ///;-
Часто такую операцию выполнять вам не придется, но знать о ней полезно.
Преобразование данных
Если вы вспомните программу GetChannel.java, то увидите, что для вывода информации из файла нам приходилось считывать из буфера по одному байту и преобразовывать его от типа byte к типу char. Такой подход явно примитивен — если вы посмотрите
//; io/BufferToText java
// Получение текста из буфера ByteBuffers и обратно
import java.nio *.
import java nio channels.*;
import java nio charset *;
import java.io.*,
public class BufferToText {
private static final int BSIZE = 1024, public static void main(String[] args) throws Exception { FileChannel fc =
new Fi1eOutputStream("data2.txt").getChannel; fc write (ByteBuffer. wrap ("Some text" .getBytesO)); fc closeO;
fc = new FileInputStream("data2.txt").getChannelО; ByteBuffer buff = ByteBuffer allocate(BSIZE); fc read(buff); buff .flipO; // He работает-
System out prmtln(buff.asCharBufferO); продолжение &
// Декодирование с использованием кодировки по умолчанию: buff.rewindO;
String encoding = System.getProperty("file.encoding"); System.out.println("Декодировано в " + encoding + ": "
+ Charset.forName(encoding).decode(buff)); // Кодирование в печатной форме: fc = new Fi1e0utputStreamCdata2.txt").getChannel О; fc.wri te(ByteBuffer.wrap(
"Some text".getBytes("UTF-16BE"))): fc.closeO:
// Повторная попытка чтения:
fc = new FileInputStreamCdata2.txt").getChannelO;
buff.clearO:
fc.read(buff);
buff.flipO:
System.out.pri nt1n(buff.asCharBuffer);
// Использование CharBuffer для записи:
fc = new FileOutputSt reamCdata2.txt"). getChannelO;
buff = ByteBuffer.a11ocate(24); // Больше, чем необходимо
buff.asCharBuffer.put("Some text");
fc.write(buff);
fc.closeO;
// Чтение и вывод:
fc = new FileInputStreamCdata2.txt").getChannelO;
buff.clearO;
fc.read(buff):
buff.flipO;
System.out.pri nt1n(buff.asCha rBuffer);
}
} /* Output: ????
Декодировано в Cpl252: Some text Some text Some text *///:-
Буфер содержит обычные байты, следовательно, для превращения их в символы мы должны либо кодировать их по мере помещения в буфер, либо декодировать их при извлечении из буфера. Это можно сделать с помощью класса java.nio.charset.Charset, который предоставляет инструменты для преобразования многих различных типов в наборы символов:
//: io/Avai1ableCharSets.java
//
import java.nio.charset.*;
import java.util.*;
import static net.mindview.util.Print.*;
public class AvailableCharSets {
public static void main(String[] args) {
SortedMap<String.Charset> charSets = Charset.avai1ableCharsets; Iterator<String> it = charSets.keySetО.iteratorO: whileCit.hasNextO) {
String csName = it.nextO; printnb(csName); Iterator aliases =
charSets get(csName) .aliasesO .iteratorO; if(aliases.hasNextO)
pnntnbC': "); while(aliases hasNextO) {
printnb(aliases.nextO); if(aliases. hasNextO) printnbC'. "),
}
printO;
}
}
} /* Output: Big5. csBig5
Big5-HKSCS: big5-hkscs, big5hk, big5-hkscs:unicode3 0. big5hkscs. Big5_HKSCS
EUC-JP eucjis, x-eucjp, csEUCPkdFmtJapanese, eucjp,
Extended_UNIX_Code_Packed_Format_for_Japanese. x-euc-jp, euc_jp
EUC-KR: ksc5601, 5601, ksc5601_1987, ksc_5601, ksc5601-
1987, euc_kr, ks_c_5601-1987, euckr, csEUCKR
GB18030• gbl8030-2000
GB2312: gb2312-1980, gb2312, EUC_CN, gb2312-80, euc-cn,
euccn, x-EUC-CN
GBK. windows-936, CP936
*///;-
Вернемся к программе BufferToText.java. Если вы вызовете для буфера метод rewind (чтобы вернуться к его началу), а затем используете кодировку по умолчанию в методе decode, данные буфера CharBuffer будут правильно выведены на консоль. Чтобы узнать кодировку по умолчанию вызовите метод System. getProperty("fiLe.encoding"), который возвращает строку с названием кодировки. Передавая эту строку методу Charset.forName, вы получите объект Charset, с помощью которого и декодируете строку.
Другой подход — кодировать данные методом encode так, чтобы при чтении файла выводились данные, пригодные для вывода на печать (пример представлен в программе BufferToText.java). Здесь для записи текста в файл используется кодировка UTF-16BE, и при последующем чтении вам остается лишь преобразовать данные в буфер CharBuffer и вывести его содержимое.
Наконец, мы видим, что происходит, когда вы записываете в буфер ByteBuffer через CharBuffer (мы узнаем об этом чуть позже). Заметьте, что для байтового буфера выделяется 24 байта. На каждый символ (char) отводится два байта, соответственно, буфер вместит 12 символов, а у нас в строке Some Text их только девять. Оставшиеся нулевые байты все равно отображаются в строке, образуемой методом toStringO класса CharBuffer, что и показывают результаты.
Извлечение примитивов
Несмотря на то что в буфере ByteBuffer хранятся только байты, он поддерживает методы для выборки любых значений примитивных типов из этих байтов. Следующий пример демонстрирует вставку и выборку из буфера разнообразных значений примитивных типов:
//. io/GetData java
11 Получение различных данных из буфера ByteBuffer import java nio *.
import static net.mindview util Print *;
public class GetData {
private static final int BSIZE = 1024. public static void main(String[] args) {