Java NIO 读取文件、写入文件、读取写入混合
前言
Java NIO(new/inputstream outputstream)使用通道、缓冲来操作流,所以要深刻理解这些概念,尤其是,缓冲中的数据结构(当前位置(position)、限制(limit)、容量(capacity)),这些知识点要通过写程序慢慢体会。
NIO vs 传统IO
NIO是面向缓冲、通道的;传统IO面向流
通道是双向的既可以写、也可以读;传统IO只能是单向的
NIO可以设置为异步;传统IO只能是阻塞,同步的
缓冲区结构图
NIO是面向缓冲区的,缓冲区可以理解为一块内存,有大小。缓冲区有位置、界限、容量几个概念。
capacity:容量,缓冲区的大小
limit:限制,表示最大的可读写的数量
position:当前位置,每当读写,当前位置都会加一
flip和clear方法,内部就操作这三个变量。
缓冲区常用方法
clear:将当前位置设置为0,限制设置为容量,目的是尽最大可能让字节,由通道读取到缓冲中
flip:当前位置置为限制,然后将当前位置置为0,目的是将有数据部分的字节,由缓冲写入到通道中。通常用在读与写之间。
读写文件代码
package com.nio; import java.io.*;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset; public class TestJavaNio { public static String pathname = "d://read.txt";
public static String filename = "d://write.txt"; @SuppressWarnings("resource")
public static void main(String[] args) {
readNIO();
writeNIO();
//testReadAndWriteNIO();
} public static void readNIO() {
FileInputStream fin = null;
try {
fin = new FileInputStream(new File(pathname));
FileChannel channel = fin.getChannel(); int capacity = 1000;// 字节
ByteBuffer bf = ByteBuffer.allocate(capacity);
System.out.println("限制是:" + bf.limit() + ",容量是:" + bf.capacity() + " ,位置是:" + bf.position());
int length = -1; while ((length = channel.read(bf)) != -1) { /*
* 注意,读取后,将位置置为0,将limit置为容量, 以备下次读入到字节缓冲中,从0开始存储
*/
bf.clear();
byte[] bytes = bf.array();
System.out.println("start.............."); String str = new String(bytes, 0, length);
System.out.println(str);
//System.out.write(bytes, 0, length); System.out.println("end................"); System.out.println("限制是:" + bf.limit() + "容量是:" + bf.capacity() + "位置是:" + bf.position()); } channel.close(); } catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fin != null) {
try {
fin.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
} public static void writeNIO() {
FileOutputStream fos = null;
try { fos = new FileOutputStream(new File(filename));
FileChannel channel = fos.getChannel();
ByteBuffer src = Charset.forName("utf8").encode("你好你好你好你好你好");
// 字节缓冲的容量和limit会随着数据长度变化,不是固定不变的
System.out.println("初始化容量和limit:" + src.capacity() + ","
+ src.limit());
int length = 0; while ((length = channel.write(src)) != 0) {
/*
* 注意,这里不需要clear,将缓冲中的数据写入到通道中后 第二次接着上一次的顺序往下读
*/
System.out.println("写入长度:" + length);
} } catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
} public static void testReadAndWriteNIO() {
FileInputStream fin = null;
FileOutputStream fos = null;
try {
fin = new FileInputStream(new File(pathname));
FileChannel channel = fin.getChannel(); int capacity = 100;// 字节
ByteBuffer bf = ByteBuffer.allocate(capacity);
System.out.println("限制是:" + bf.limit() + "容量是:" + bf.capacity() + "位置是:" + bf.position());
int length = -1; fos = new FileOutputStream(new File(filename));
FileChannel outchannel = fos.getChannel(); while ((length = channel.read(bf)) != -1) { //将当前位置置为limit,然后设置当前位置为0,也就是从0到limit这块,都写入到同道中
bf.flip(); int outlength = 0;
while ((outlength = outchannel.write(bf)) != 0) {
System.out.println("读," + length + "写," + outlength);
} //将当前位置置为0,然后设置limit为容量,也就是从0到limit(容量)这块,
//都可以利用,通道读取的数据存储到
//0到limit这块
bf.clear(); }
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fin != null) {
try {
fin.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
} }
Java NIO 读取文件、写入文件、读取写入混合的更多相关文章
- JAVA NIO FileChannel 内存映射文件
文件通道总是阻塞式的. 文件通道不能创建,只能通过(RandomAccessFile.FileInputStream.FileOutputStream)getChannel()获得,具有与File ...
- Java NIO之内存映射文件——MappedByteBuffer
大多数操作系统都可以利用虚拟内存实现将一个文件或者文件的一部分"映射"到内存中.然后,这个文件就可以当作是内存数组来访问,这比传统的文件要快得多. 内存映射文件的一个关键优势是操作 ...
- Java IO和Java NIO 和通道 在文件拷贝上的性能差异分析
1. 在JAVA传统的IO系统中,读取磁盘文件数据的过程如下: 以FileInputStream类为例,该类有一个read(byte b[])方法,byte b[]是我们要存储读取到用户空间的缓冲区 ...
- java nio通过ByteBuffer输出文件信息
1.通过ByteBuffer的get()方法每次读取一个字节转换成char类型输出. fc = new FileInputStream("src/demo20/data.txt") ...
- Java NIO FileVisitor 高效删除文件
在公司项目中,由于做个二维码扫码平台项目,预计每天产生的二维码图片达到十几G,所以要做个定时清理任务来定时清理图片,根据不同场景保留图片,规则是:1.二维码统一登录图片几个小时有效 2.电子名片二 ...
- Java NIO(四)文件通道
文件通道 通道是访问I/O服务的导管,I/O可以分为广义的两大类:File I/O和Stream I/O.那么相应的,通道也有两种类型,它们是文件(File)通道和套接字(Socket)通道.文件通道 ...
- java nio 快速read大文件
If you want to make your first example faster FileChannel inChannel = new FileInputStream(fileName). ...
- Java NIO学习笔记五 FileChannel(文件通道)
Java NIO FileChannel Java NIO FileChannel是连接文件的通道.使用FileChannel,您可以从文件中读取数据和将数据写入文件.Java NIO FileCha ...
- Java NIO 完全学习笔记(转)
本篇博客依照 Java NIO Tutorial翻译,算是学习 Java NIO 的一个读书笔记.建议大家可以去阅读原文,相信你肯定会受益良多. 1. Java NIO Tutorial Java N ...
- Java NIO 进程间通信
转自:http://blog.csdn.net/lingzhm/article/details/45026119 传统的进程间通信的方式有大致如下几种: (1) 管道(PIPE) (2) 命名 ...
随机推荐
- Swift ARC 自动引用计数
1.ARC 引用类型在堆上的内存分配过程中有 8 字节的地址长度用来保存对象的引用计数,堆上的内存并不像栈上那样立即进行回收,系统会定时对堆上的内存进行检查,当某个实例不再被使用时,引用计数会变为 0 ...
- mysql乱码问题解决办法
最近开发一下小项目,遇到了最常见的乱码问题. 1.数据库使用utf-8 utf-8_generic_ci编码,使用csv上传并导入数据,插入数据的时候出现了问题,有很大部分数据没有被导入,所以使用m ...
- stale element reference: element is not attached to the page document 异常
在执行脚本时,有时候引用一些元素对象会抛出如下异常 org.openqa.selenium.StaleElementReferenceException: stale element referenc ...
- 第三部分:Android 应用程序接口指南---第二节:UI---第八章 Toast通知
第8章 Toast通知 Toast通知是在窗口前面弹出的信息.它只占有信息所需要的空间量,并且用户当前的activity仍然是可见的.可互动的.这种通知自动地淡入和淡出,它不接受交互事件.他相当于一种 ...
- Current online Redo 和 Undo 损坏的处理方法
转自:http://blog.csdn.net/tianlesoftware/article/details/6261475 Oracle 不同故障的恢复方案 http://blog.csdn.net ...
- 解决Redis之MISCONF Redis is configured to save RDB snapshots, but is currently not able to persist o...
解决Redis之MISCONF Redis is configured to save RDB snapshots, but is currently not able to persist o... ...
- PHP Backdoor + Reverse Shell on Vulnerable Website
翻译总结自: https://shellgam3.com/2016/07/27/php-backdoor-reverse-shell-on-vulnerable-website/ 扫描Web服务器,爆 ...
- 【30集iCore3_ADP出厂源代码(ARM部分)讲解视频】30-8底层驱动之RTC
视频简介:该视频介绍iCore3应用开发平台中RTC的基本配置方法以及在应用开发平台中的实时显示. 源视频包下载地址:链接:http://pan.baidu.com/s/1o80jHvc 密码:f8r ...
- php5.6-lumen与php5.6-phalcon性能对比
场景一: 两个框架简单输出helloworld phalcon:{QPS:7349,平均响应时间:124.11ms},lumen{QPS:1327,平均响应时间:721.54ms} QPS: phal ...
- Django 源码小剖: Django 中的 WSGI
Django 其内部已经自带了一个方便本地测试的小服务器, 所以在刚开始学习 Django 的时候并不需搭建 apache 或者 nginx 服务器. Django 自带的服务器基于 python w ...