吐槽下 nio
final static int BUFFER_SIZE = 20; // 为了容易出现错误,把缓存弄小点 private static void fuc_Nio() { FileInputStream fis = null; FileChannel fc = null; try { fis = new FileInputStream("src/nio/ReadFile.java"); fc = fis.getChannel(); ByteBuffer buffer = ByteBuffer.allocate(BUFFER_SIZE); CharsetDecoder decoder = Charset.forName("utf-8").newDecoder(); while (fc.read(buffer) != -1) { buffer.flip(); System.out.print(decoder.decode(buffer)); // 出现异常 MalformedInputException: Input length = 1 buffer.clear(); } } catch (IOException ex) { ex.printStackTrace(); } finally { quickClose(fis); quickClose(fc); } } private static void quickClose(Closeable closeable) { if (closeable != null) { try { closeable.close(); } catch (IOException ignored) { } } } private static void rightWay() { FileInputStream fis = null; FileChannel fc = null; try { fis = new FileInputStream("src/nio/ReadFile.java"); fc = fis.getChannel(); ByteBuffer buffer = ByteBuffer.allocate(BUFFER_SIZE); CharBuffer out = CharBuffer.allocate(BUFFER_SIZE * 3); // 为了简单,确保大小足够 CharsetDecoder decoder = Charset.forName("utf-8").newDecoder(); while (fc.read(buffer) != -1) { buffer.flip(); out.clear(); decoder.decode(buffer, out, false); out.flip(); System.out.print(out.toString()); reset(buffer); // 把不能解码的部分移动到前面,用于下次使用 } buffer.flip(); // 剩下的不能解码的部分直接输出 System.out.write(buffer.array(), buffer.position(), buffer.limit() - buffer.position()); } catch (IOException ex) { ex.printStackTrace(); } finally { quickClose(fis); quickClose(fc); } } private static void reset(ByteBuffer bf) { byte[] bytes = new byte[bf.remaining()]; int i = 0; while (bf.hasRemaining()) { bytes[i] = bf.get(); i++; } bf.clear(); for (byte b : bytes) { bf.put(b); } }package nio;/* 弄点切糕 */// src/nio/ReadFile.javaimport java.io.Closeable;import java.io.FileInputStream;import java.io.IOException;import java.nio.ByteBuffer;import java.nio.CharBuffer;import java.nio.channels.FileChannel;import java.nio.charset.Charset;import java.nio.charset.CharsetDecoder;public class ReadFile { final static int BUFFER_SIZE = 20; // 为了容易出现错误,把缓存弄小点 private static void fuc_Nio() { FileInputStream fis = null; FileChannel fc = null; try { fis = new FileInputStream("src/nio/ReadFile.java"); fc = fis.getChannel(); ByteBuffer buffer = ByteBuffer.allocate(BUFFER_SIZE); CharsetDecoder decoder = Charset.forName("utf-8").newDecoder(); while (fc.read(buffer) != -1) { buffer.flip(); System.out.print(decoder.decode(buffer)); // 出现异常 MalformedInputException: Input length = 1 buffer.clear(); } } catch (IOException ex) { ex.printStackTrace(); } finally { quickClose(fis); quickClose(fc); } } private static void rightWay() { FileInputStream fis = null; FileChannel fc = null; try { fis = new FileInputStream("src/nio/ReadFile.java"); fc = fis.getChannel(); ByteBuffer buffer = ByteBuffer.allocate(BUFFER_SIZE); CharBuffer out = CharBuffer.allocate(BUFFER_SIZE * 3); // 为了简单,确保大小足够 CharsetDecoder decoder = Charset.forName("utf-8").newDecoder(); while (fc.read(buffer) != -1) { buffer.flip(); out.clear(); decoder.decode(buffer, out, false); out.flip(); System.out.print(out.toString()); reset(buffer); // 把不能解码的部分移动到前面,用于下次使用 } buffer.flip(); // 剩下的不能解码的部分直接输出 System.out.write(buffer.array(), buffer.position(), buffer.limit() - buffer.position()); } catch (IOException ex) { ex.printStackTrace(); } finally { quickClose(fis); quickClose(fc); } } private static void reset(ByteBuffer bf) { byte[] bytes = new byte[bf.remaining()]; int i = 0; while (bf.hasRemaining()) { bytes[i] = bf.get(); i++; } bf.clear(); for (byte b : bytes) { bf.put(b); } } private static void quickClose(Closeable closeable) { if (closeable != null) { try { closeable.close(); } catch (IOException ignored) { } } } public static void main(String[] args) { rightWay(); // 有效方法,至少我试了可以使用 fuc_Nio(); // 错误方法 }} fis = new FileInputStream(srcFile); fos = new FileOutputStream(destFile); input = fis.getChannel(); output = fos.getChannel(); long size = input.size(); long pos = 0; long count = 0; while (pos < size) { count = size - pos > FILE_COPY_BUFFER_SIZE ? FILE_COPY_BUFFER_SIZE : size - pos; pos += output.transferFrom(input, pos, count); }