`
悲伤逆流成河
  • 浏览: 672 次
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

吐槽下 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) {
            }
        }
    }


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 。

分享到:
评论

相关推荐

    java NIO.zip

    Java NIO,全称为Non-Blocking Input/Output(非阻塞输入/输出),是Java标准库提供的一种替代传统的I/O模型的新技术。自Java 1.4版本引入NIO后,它为Java开发者提供了更高效的数据传输方式,尤其是在处理大量并发...

    JavaNIO chm帮助文档

    Java NIO系列教程(一) Java NIO 概述 Java NIO系列教程(二) Channel Java NIO系列教程(三) Buffer Java NIO系列教程(四) Scatter/Gather Java NIO系列教程(五) 通道之间的数据传输 Java NIO系列教程(六)...

    Java NIO英文高清原版

    Java NIO,全称为Non-Blocking Input/Output(非阻塞输入/输出),是Java平台中用于替代标准I/O(BIO)模型的一种新机制。NIO在Java 1.4版本引入,提供了更高效的数据处理和通道通信方式,特别适用于高并发、大数据...

    NIO 入门.chm,NIO 入门.chm

    **NIO(New Input/Output)是Java编程语言中用于替代标准I/O(BIO,Blocking I/O)的一组API,它提供了非阻塞式的I/O操作方式,极大地提升了Java在处理I/O密集型应用时的性能。NIO在Java 1.4版本中被引入,之后在...

    javaNiO.doc

    ### Java NIO (New IO) 详解 #### 1. 引言 在Java的世界里,I/O(Input/Output)操作是程序与外部环境进行交互的重要方式之一。随着技术的发展,传统I/O模型逐渐显露出一些局限性,特别是在处理高并发场景下,其...

    基于nio实现的多文件上传源码

    在Java编程领域,NIO(New IO)是一个重要的特性,它是Java 1.4版本引入的,用于替代标准的IO API。NIO提供了一种非阻塞I/O操作的方式,特别适用于处理大量的并发连接,例如在文件传输、网络通信等场景。本主题...

    java NIO和java并发编程的书籍

    java NIO和java并发编程的书籍java NIO和java并发编程的书籍java NIO和java并发编程的书籍java NIO和java并发编程的书籍java NIO和java并发编程的书籍java NIO和java并发编程的书籍java NIO和java并发编程的书籍java...

    nio demo for nio学习笔记(体系结构以及模块介绍)

    Java NIO库提供了多种实现,如`java.nio.channels`包下的各种Channel和Selector类,以及`java.nio`包下的Buffer类。 在学习NIO时,首先需要理解Channel、Buffer、Selector的基本概念和使用方法,然后通过实例来熟悉...

    Java NIO 中文 Java NIO 中文 Java NIO 中文文档

    Java NIO 深入探讨了 1.4 版的 I/O 新特性,并告诉您如何使用这些特性来极大地提升您所写的 Java 代码的执行效率。这本小册子就程序员所面临的有代表性的 I/O 问题作了详尽阐述,并讲解了 如何才能充分利用新的 I/O ...

    基于nio的简易聊天室

    在Java编程领域,NIO(New Input/Output)是一个重要的概念,它提供了非阻塞I/O操作的能力,相比传统的BIO(Blocking I/O),在处理大量并发连接时表现出更高的效率和性能。本项目"基于nio的简易聊天室"旨在通过NIO...

    JAVA-NIO-DEMO

    Java NIO(New IO)是Java 1.4版本引入的...同时,通过Anontion和Applet的结合,你可以看到如何在不同的场景下结合使用这些技术,增强代码的灵活性和可扩展性。请务必仔细研究并实践这些示例,以深化你的Java NIO知识。

    Java NIO系列教程(一) Java NIO 概述

    在这种情况下,我们可以利用Selector来监听多个客户端连接上的读写事件。当一个客户端发送消息时,Selector会通知我们哪个Channel有可读事件,然后我们可以从该Channel读取消息并转发给其他客户端。 #### 六、总结 ...

    Java IO, NIO and NIO.2

    3. Position(位置):表示下一个可以读取的数据项的基于零的索引,或数据项可以被写入的位置。 4. Mark(标记):一个基于零的索引,用于在调用缓冲区的reset()方法时,将缓冲区的position重置到标记位置。标记初始...

    IO和NIO区别

    NIO 相比标准 IO,有更多的优势,特别是在高并发连接的情况下。在 NIO 中,单线程可以管理多个通道,而标准 IO 则需要多个线程来管理多个连接。这样,NIO 可以更好地处理高并发连接,减少资源占用和提高性能。 5. ...

    java nio 包读取超大数据文件

    `getForder()`函数假设是用来获取某个目录下的子目录名称。 - **设置缓冲区大小**:`final int BUFFER_SIZE=0x300000;` 设置了每次读取的缓冲区大小为3MB。 - **定义文件范围**:通过`begin_fz`、`begin_fm`、`end...

    java nio 尚硅谷 12讲 new

    Java NIO,全称为Non-Blocking Input/Output(非阻塞输入/输出),是Java标准库提供的一种替代传统I/O模型的新...通过系统学习,开发者将更好地理解Java NIO的优势,并能在适当的情况下选择使用NIO而非传统的BIO模型。

    httpcore-nio-4.3.jar包

    它基于Java NIO API,利用其非阻塞I/O特性,可以同时处理大量连接,尤其适合于高并发的网络环境。HttpCore NIO 4.3版是对该框架的进一步优化和完善,增强了对HTTP/1.1协议的支持,同时保持了良好的兼容性和稳定性。 ...

    Java NIO Socket基本

    4. **管道(Pipe)**:在某些特定情况下,两个线程之间可以使用`java.nio.Pipe`进行单向数据传递。 5. **文件系统API**:NIO还提供了`java.nio.file`包,包含一系列与文件系统交互的类,如Files、Paths等。 Java ...

    NIO入门pdf分享

    《NIO入门》一书是理解Java NIO(New Input/Output)的重要参考资料,NIO在Java编程中扮演着至关重要的角色,特别是在处理高并发、大数据传输等场景下。本PDF文档将引领读者深入理解这一核心概念。 NIO,全称New ...

Global site tag (gtag.js) - Google Analytics