浏览 1382 次
锁定老帖子 主题:吐槽下 nio
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2012-12-20
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) { } } } o(︶︿︶)o 唉,解码失败,百度了一下,无果。。。 这段代码修改自 一本叫 疯狂java xx 的书,没看几页,各种错误,让人心灰意冷,果然不应该看国内的书啊。。。。 怎么弄呢,用 PipedInputStream ? 这不行,否则 非阻塞 就费了。。 我很好奇,Writer 是怎么做到的,看了一下源代码,我重新修改了一下,这下子没有错误了。。 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.java import 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(); // 错误方法 } } 顺便弄上一段 复制文件 的源代码(commons-io),不然 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); } 写书的那些白痴,不经过测试的代码就别搞上去。。。 源代码编码是 utf-8,用eclipse的话应该会出现乱码,搞不懂 eclipse 为什么默认编码为 gb2312 。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |