更多参考《Java in a nutshell》
~~
java.nio.charset 字符集包,CharsetEncoder和CharsetDecoder允许对编码和解码过程进行精细的控制
String input = "你123好";Charset charset = Charset.forName("ISO-8859-1");
CharsetEncoder encoder = charset.newEncoder();
encoder.onUnmappableCharacter(CodingErrorAction.IGNORE);
CharsetDecoder decoder = charset.newDecoder();
CharBuffer buffer = CharBuffer.allocate(32);
buffer.put(input);
buffer.flip();
try {
ByteBuffer byteBuffer = encoder.encode(buffer);
CharBuffer cbuf = decoder.decode(byteBuffer);
System.out.println(cbuf); //输出123
} catch (CharacterCodingException e) {
e.printStackTrace();
}
Channel之间transfer数据
public static String readFile(File file) throws IOException {
FileInputStream fis = new FileInputStream(file);
FileChannel channel = fis.getChannel();
ByteArrayOutputStream os = new ByteArrayOutputStream(0x10000);
WritableByteChannel wchannel = Channels.newChannel(os);
channel.transferTo(0, file.length(), wchannel);
channel.close();
wchannel.close();
return os.toString();
}
public static void writeFile(File file, final String content) throws IOException {
if (!file.exists())
file.createNewFile();
FileOutputStream fos = new FileOutputStream(file);
FileChannel channel = fos.getChannel();
ByteArrayInputStream is = new ByteArrayInputStream(content.getBytes());
ReadableByteChannel rchannel = Channels.newChannel(is);
channel.transferFrom(rchannel, 0, content.getBytes().length);
channel.close();
rchannel.close();
}
NIO ByteBuffer
将数据读入缓冲区之前,需要调用clear方法;将缓冲区中的数据输出之前,需要调用flip方法。
ByteBuffer buffer = ByteBuffer.allocate(32);CharBuffer charBuffer = buffer.asCharBuffer();
String content = charBuffer.put("Hello ").put("World").flip().toString();
System.out.println(content);
将Stream转换成byte[]
private byte[] saveStream(InputStream input) throws IOException {ByteBuffer buffer = ByteBuffer.allocate(1024);
ReadableByteChannel readChannel = Channels.newChannel(input);
ByteArrayOutputStream output = new ByteArrayOutputStream(32 * 1024);
WritableByteChannel writeChannel = Channels.newChannel(output);
while ((readChannel.read(buffer)) > 0 || buffer.position() != 0) {
buffer.flip();
writeChannel.write(buffer);
buffer.compact();
}
return output.toByteArray();
}
如果一个流支持标记的话(通过markSupported方法判断),就可以在流开始的地方通过mark方法添加一个标记,当完成一次对流的使用之后,通过reset方法就可以把流的读取位置重置到上次标记的位置,即流开始的地方。如此反复,就可以复用这个输入流。大部分输入流的实现是不支持标记的。可以通过BufferedInputStream进行包装来支持标记。
private InputStream prepareStream(InputStream ins) {BufferedInputStream buffered = new BufferedInputStream(ins);
buffered.mark(Integer.MAX_VALUE);
return buffered;
}
private void resetStream(InputStream ins) throws IOException {
ins.reset();
ins.mark(Integer.MAX_VALUE);
}
Interrupt a thread while doing block I/O operation:
try {
new InputStreamReader(
Channels.newInputStream(
(new FileInputStream(FileDescriptor.in)).getChannel())));
catch (…) {
}
以特定字符编码从文件中读取一行:
File file = new File("test");
FileInputStream is = new FileInputStream(file);
BufferedReader reader = new BufferedReader(new InputStreamReader(is, "gbk"));
String str;
while((str = reader.readLine()) != null) {
System.out.println(str);
}
BufferedInputStream:
File file = new File("moandroid.txt");
InputStream is = new BufferedInputStream(new FileInputStream(file));
long length = file.length();
if(length>Integer.MAX_VALUE)
{
System.out.println(“source file is too large”);
return ;
}
byte[] bytes = new byte[(int)length];
int offset = 0,numRead = 0;
while( offset<bytes.length && (numRead = is.read(bytes,offset,bytes.length-offset))>= 0)
offset += numRead;
if(offset<bytes.length)
throw new IOException(“Could not completely read file”+file.getName());
is.close();
DataInputStream:
File file = new File("moandroid.txt");
is = new DataInputStream(new FileInputStream(file));
int intData = is.readInt();
boolean boolData = is.readBoolean();