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,全称为Non-Blocking Input/Output(非阻塞输入/输出),是Java标准库提供的一种替代传统的I/O模型的新技术。自Java 1.4版本引入NIO后,它为Java开发者提供了更高效的数据传输方式,尤其是在处理大量并发...
Java NIO系列教程(一) Java NIO 概述 Java NIO系列教程(二) Channel Java NIO系列教程(三) Buffer Java NIO系列教程(四) Scatter/Gather Java NIO系列教程(五) 通道之间的数据传输 Java NIO系列教程(六)...
Java NIO,全称为Non-Blocking Input/Output(非阻塞输入/输出),是Java平台中用于替代标准I/O(BIO)模型的一种新机制。NIO在Java 1.4版本引入,提供了更高效的数据处理和通道通信方式,特别适用于高并发、大数据...
**NIO(New Input/Output)是Java编程语言中用于替代标准I/O(BIO,Blocking I/O)的一组API,它提供了非阻塞式的I/O操作方式,极大地提升了Java在处理I/O密集型应用时的性能。NIO在Java 1.4版本中被引入,之后在...
### Java NIO (New IO) 详解 #### 1. 引言 在Java的世界里,I/O(Input/Output)操作是程序与外部环境进行交互的重要方式之一。随着技术的发展,传统I/O模型逐渐显露出一些局限性,特别是在处理高并发场景下,其...
在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...
Java NIO库提供了多种实现,如`java.nio.channels`包下的各种Channel和Selector类,以及`java.nio`包下的Buffer类。 在学习NIO时,首先需要理解Channel、Buffer、Selector的基本概念和使用方法,然后通过实例来熟悉...
Java NIO 深入探讨了 1.4 版的 I/O 新特性,并告诉您如何使用这些特性来极大地提升您所写的 Java 代码的执行效率。这本小册子就程序员所面临的有代表性的 I/O 问题作了详尽阐述,并讲解了 如何才能充分利用新的 I/O ...
在Java编程领域,NIO(New Input/Output)是一个重要的概念,它提供了非阻塞I/O操作的能力,相比传统的BIO(Blocking I/O),在处理大量并发连接时表现出更高的效率和性能。本项目"基于nio的简易聊天室"旨在通过NIO...
Java NIO(New IO)是Java 1.4版本引入的...同时,通过Anontion和Applet的结合,你可以看到如何在不同的场景下结合使用这些技术,增强代码的灵活性和可扩展性。请务必仔细研究并实践这些示例,以深化你的Java NIO知识。
在这种情况下,我们可以利用Selector来监听多个客户端连接上的读写事件。当一个客户端发送消息时,Selector会通知我们哪个Channel有可读事件,然后我们可以从该Channel读取消息并转发给其他客户端。 #### 六、总结 ...
3. Position(位置):表示下一个可以读取的数据项的基于零的索引,或数据项可以被写入的位置。 4. Mark(标记):一个基于零的索引,用于在调用缓冲区的reset()方法时,将缓冲区的position重置到标记位置。标记初始...
NIO 相比标准 IO,有更多的优势,特别是在高并发连接的情况下。在 NIO 中,单线程可以管理多个通道,而标准 IO 则需要多个线程来管理多个连接。这样,NIO 可以更好地处理高并发连接,减少资源占用和提高性能。 5. ...
`getForder()`函数假设是用来获取某个目录下的子目录名称。 - **设置缓冲区大小**:`final int BUFFER_SIZE=0x300000;` 设置了每次读取的缓冲区大小为3MB。 - **定义文件范围**:通过`begin_fz`、`begin_fm`、`end...
Java NIO,全称为Non-Blocking Input/Output(非阻塞输入/输出),是Java标准库提供的一种替代传统I/O模型的新...通过系统学习,开发者将更好地理解Java NIO的优势,并能在适当的情况下选择使用NIO而非传统的BIO模型。
它基于Java NIO API,利用其非阻塞I/O特性,可以同时处理大量连接,尤其适合于高并发的网络环境。HttpCore NIO 4.3版是对该框架的进一步优化和完善,增强了对HTTP/1.1协议的支持,同时保持了良好的兼容性和稳定性。 ...
4. **管道(Pipe)**:在某些特定情况下,两个线程之间可以使用`java.nio.Pipe`进行单向数据传递。 5. **文件系统API**:NIO还提供了`java.nio.file`包,包含一系列与文件系统交互的类,如Files、Paths等。 Java ...
《NIO入门》一书是理解Java NIO(New Input/Output)的重要参考资料,NIO在Java编程中扮演着至关重要的角色,特别是在处理高并发、大数据传输等场景下。本PDF文档将引领读者深入理解这一核心概念。 NIO,全称New ...