java NIO(二)之通道

StandardOpenOption详解 package java.nio.file; /** * Defines the standard open options. * * @since 1.7 */ public enum StandardOpenOption implements OpenOption { /** * Open for read access. * 读取一个已存在的文件,如果文件不存在或被占用则抛出异常 */ READ, /** * Open fo 阅读详情

一、通道(Channel):

用于源节点与目标节点的连接。在 Java NIO 中负责缓冲区中数据的传输。Channel 本身不存储数据,因此需要配合缓冲区进行传输。

 
 二、通道的主要实现类
  java.nio.channels.Channel 接口:
  |--FileChannel:用于读取、写入、映射和操作文件的通道。
  |--SocketChannel:通过 UDP 读写网络中的数据通道。
  |--ServerSocketChannel:通过 TCP 读写网络中的数据。
  |--DatagramChannel:可以监听新进来的 TCP 连接,对每一个新进来的连接都会创建一个 SocketChannel。
 
 三、获取通道
 1. Java 针对支持通道的类提供了 getChannel() 方法
  本地 IO:

  FileInputStream/FileOutputStream

  RandomAccessFile
  网络IO:
  Socket
  ServerSocket
  DatagramSocket
 
 2. 在 JDK 1.7 中的 NIO.2 针对各个通道提供了静态方法 open()
 3. 在 JDK 1.7 中的 NIO.2 的 Files 工具类的 newByteChannel()
 
 四、通道之间的数据传输
 transferFrom()
 transferTo()

 五、分散(Scatter)与聚集(Gather)
  分散读取(Scattering Reads):将通道中的数据分散到多个缓冲区中

  聚集写入(Gathering Writes):将多个缓冲区中的数据聚集到通道中

  六、字符集:Charset
  编码:字符串 -> 字节数组
  解码:字节数组  -> 字符串

支持通道的类 getChannel() 方法

//非直接缓冲区,通道完成对文件的复制
	@Test
	public void test01() throws Exception{
		FileInputStream in=new FileInputStream("z6.png");
		FileOutputStream ou=new FileOutputStream("2.jpg");
		//获取通道
		FileChannel channeIn = in.getChannel();
		FileChannel channelOu = ou.getChannel();
		//分配指定大小缓冲区
		ByteBuffer allocate = ByteBuffer.allocate(1024);
		//将通道中的数据读入缓冲区
		while(channeIn.read(allocate)!=-1){
			//切换读取数据模式
			allocate.flip();
			//将缓冲区数据写入通道
			channelOu.write(allocate);
			//清楚缓冲区
			allocate.clear();
		}
		channeIn.close();
		channelOu.close();
		in.close();
		ou.close();
	}


静态方法 open()

//使用直接缓冲区完成文件的复制(内存映射文件)
	@Test
	public void test02() throws IOException{
		FileChannel read = FileChannel.open(Paths.get("z6.png"), StandardOpenOption.READ);
		//StandardOpenOption.CREATE_NEW如果不存在则报错,不进行覆盖,create如果存在则进行覆盖
		//Path path = Paths.get("e:/", "/s","/s");   可以进行路径的拼接
		FileChannel write = FileChannel.open(Paths.get("2.png"), 
			StandardOpenOption.WRITE,StandardOpenOption.READ,StandardOpenOption.CREATE);
		//内存映射文件
		MappedByteBuffer mapR = read.map(MapMode.READ_ONLY, 0, read.size());
		MappedByteBuffer mapW = write.map(MapMode.READ_WRITE, 0, read.size());
		byte[] dst=new byte[mapR.limit()];
		//直接对缓冲区进行数据的读写操作-因是直接缓冲区可以直接操作,不借用通道
		mapR.get(dst);
		mapW.put(dst);
		read.close();
		write.close();
	}

    以上两种方式,在使用1G大小的视频进行复制测试的时候,使用直接缓冲区的速度明显高于非直接缓冲区,但直接缓冲区有的时候会出现文件复制完成,程序却没有结束的情况。直接缓冲区进行分配和取消分配所需成本通常高于非直接缓冲区 。直接缓冲区的内容可以驻留在常规的垃圾回收堆之外,因此,它们对应用程序的内存需求量造成的影响可能并不明显。所以,建议将直接缓冲区主要分配给那些易受基础系统的机 本机 I/O  操作影响的大型、持久的缓冲区。一般情况下,最好仅在直接缓冲区能在程序性能方面带来明显好

处时分配它们。

通道之间的数据传输

//通道之间的数据传输,直接缓冲区
	@Test
	public void test03() throws Exception{
		FileChannel read = FileChannel.open(Paths.get("z6.png"), StandardOpenOption.READ);
		FileChannel write = FileChannel.open(Paths.get("7.png"), 
			StandardOpenOption.WRITE,StandardOpenOption.READ,StandardOpenOption.CREATE);
		//read.transferTo(0, read.size(), write);
		write.transferFrom(read, 0, read.size());
		read.close();
		write.close();
	}

分散(Scatter)与聚集(Gather)

@Test
	public void test04() throws IOException{
		RandomAccessFile read=new RandomAccessFile("1.txt", "rw");//rw为读写操作简写 
		FileChannel channel = read.getChannel();//获取通道
		ByteBuffer allocate1 = ByteBuffer.allocate(100);//分配缓冲区
		ByteBuffer allocate2 = ByteBuffer.allocate(10000);
		ByteBuffer dsts[]={allocate1,allocate2};
		channel.read(dsts);
		
		System.out.println(new String(dsts[0].array(), 0, dsts[0].limit()));
		System.out.println("==================");
		System.out.println(new String(dsts[1].array(), 0, dsts[1].limit()));
		//以上得出结论在写入缓冲区的时候 ,是有序的,按顺序操作
		//写入
		for (ByteBuffer byteBuffer : dsts) {
		 byteBuffer.flip();
	    }
		RandomAccessFile write=new RandomAccessFile("2.txt", "rw");
		FileChannel channel2 = write.getChannel();
		channel2.write(dsts);
		channel2.close();
		channel.close();
		write.close();
		read.close();
	}


字符集:Charset

@Test
	public void test05() throws IOException{
		//nio 支持的编码
		/*SortedMap<String,Charset> availableCharsets = Charset.availableCharsets();
		Set<Entry<String,Charset>> entrySet = availableCharsets.entrySet();
		for (Entry<String, Charset> entry : entrySet) {
			System.out.println(entry.getKey()+"=="+entry.getValue());
		}*/
		Charset cs = Charset.forName("GBK");
		CharsetEncoder newEncoder = cs.newEncoder();//编码
		CharsetDecoder newDecoder = cs.newDecoder();	//解码
		CharBuffer cBuf = CharBuffer.allocate(1024);
		cBuf.put("我是中国人");
		cBuf.flip();
		ByteBuffer bBuf = newEncoder.encode(cBuf);//编码
		for (int i = 0; i < bBuf.limit(); i++) {
			System.out.println(bBuf.get());
		}
		bBuf.flip();
		CharBuffer decode = newDecoder.decode(bBuf);	//解码
		System.out.println("=========");
		System.out.println(decode.toString());
	}

SpringBoot 插件化开发详细总结 SpringBoot 插件化开发方案总结 阅读详情

相关推荐

【AUTOSAR-COM】-10.5-APP CAN Frame/PDU“发送周期不准“的影响因素

一个Tx PDU在COM模块中的数据流; Tx APP CAN Frame/PDU"发送周期不准"的影响因素;

「汽车电子助手」的博客 2361

Java NIO 学习总结(一)

Java NIO 学习总结(一)主要内容: 1.IO与NIO的区别 2.NIO的缓冲区数据存取操作 3.通道(Channel)的原理与获取 4.通道的数据传输与内存映射文件 5.分散读取与聚集写入 6.字符集Charset一、IO与NIO的区别 1.NIO与原IO有同样的作用和目的,但使用方式完全不同,NIO支持面向缓冲区,基于通道的IO操作...

Juwenzhe_HEBUT的博客 306

2021年工训赛智能搬运赛项物料颜色识别代码,硬件openmv

本代码是经过调试的稳定版本,颜色识别准确性高且稳定性好。在智能搬运赛项中取得了省特等奖。

使用Files工具类进行文本写入时,设置为在文件末尾追加,而不是在文件开头进行覆盖。

这时再执行Java 在写入文件时追加内容而不是覆盖原有内容。每次写入的内容都会被添加到文件的末尾,而不会覆盖之前的内容。: 这个选项表示如果文件不存在,将会创建一个新文件。如果文件已经存在,它不会覆盖现有文件,而是继续在文件中写入内容。: 这个选项表示在写入文件时追加内容而不覆盖。它告诉文件系统将新数据添加到文件的末尾,而不是从文件的开头开始写入。使用Files.write()时默认情况下会将内容写入文件并覆盖文件的现有内容。如果想要在写入时追加内容而不覆盖的话你需要定义追加项。

selele的博客 1630

7天掌握NIO和SOCKET,第四天,通道打开文件的StandardOpenOption的枚举常量的使用方法,判断通道是否打开

import java.io.File; import java.io.RandomAccessFile; import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.nio.channels.FileChannel; import java.nio.charset.Charset; import java.nio.fi...

qq_40666620的博客 1780

java-使用StandardOpenOption.CREATE的Files.newInputStream中的NoSuchFileException

我正在尝试打开一个文件以进行读取或创建该文件(如果不存在). 我使用以下代码: String location = "/test1/test2/test3/"; new File(location).mkdirs(); location += "fileName.properties"; Path confDir = Paths.get(location); InputStream...

weixin_44109689的博客 1885

Java NIO 教程 () 通道

Java NIO 教程 () 通道 NIO中的通道有点像IO中的流式对象,但是又有一些不同: 在一个通道中,你既能够读,也能够写.流式对象通常是单向的 通道支持异步读写 通道永远与缓冲区绑定(从缓冲区读入,写入缓冲区) 通道的实现 以下是NIO中最重要的通道实现 FileChannel DatagramChannel SocketChannel ServerSocketChannel F...

博言杂谈 205

Java NIO 通道通道基础

概念通道NIO提供的一个全新的东西,提供与I/O服务的直接连接。Channel用于在字节缓冲区和位于通道的另一侧的实体(通常是一个文件或者套接字)之间进行有效的传输数据。接口定义 public interface Channel extends Closeable { public boolean isOpen(); public...

lwgzj的博客 4401

java nio 关闭channel_JAVA NIO()Channel通道

Channel概述Channel是一个通道,可以通过它读取和写入数据,通道与流的不同之处在于通道是双向的,流是单向的;NIO中通过channel封装了对数据源的操作,通过channel 我们可以操作数据源,但又不必关心数据源的具体物理结构。在大多数应用中,channel与文件描述符或者socket是一一对应的。Channel用于在字节缓冲区和位于通道另一侧的实体(通常是一个文件或套接字)之间有效地...

weixin_29279101的博客 644

java nio 通道()

java nio 通道()

jiangfullll的专栏 1279

Java NIO()通道Channel

一、通道(Channel): 用于源节点与目标节点的连接。在 Java NIO 中负责缓冲区中数据的传输。Channel 本身不存储数据,因此需要配合缓冲区进行传输。  通道的主要实现类      java.nio.channels.Channel 接口:          |--FileChannel:用于读取、写入、映射和操作文件的通道。          |--SocketChan...

Pazz 1311

JAVA NIO()Channel通道

Channel概述   Channel是一个通道,可以通过它读取和写入数据,通道与流的不同之处在于通道是双向的,流是单向的;NIO中通过channel封装了对数据源的操作,通过channel 我们可以操作数据源,但又不必关心数据源的具体物理结构。在大多数应用中,channel与文件描述符或者socket是一一对应的。Channel用于在字节缓冲区和位于通道另一侧的实体(通常是一个文件或套接字)之...

weixin_30664615的博客 105

Java NIO 通道通道分散/聚集

基于通道NIO又提供了另一个重要功能,分散(Scatter)和聚集(Gather)。Scatter(分散):指的是从通道中读取(read)数据分散到多个缓冲区Buffer中,该过程会将每个缓冲区填满,直到通道中无数据或者缓冲区没有空间。Gather(聚集):指的是将多个缓冲区Buffer聚集起来写入(write)通道的过程,类似于将多个缓冲区的内容链接起来写入通道。代码public interf...

lwgzj的博客 348

java.nio.file.StandardOpenOption

[url=http://www.knowsky.com/889137.html]java.nio.file.StandardOpenOption[/url] READ 以读取方式打开文件 WRITE   已写入方式打开文件 CREATE 如果文件不存在,创建 CREATE_NEW 如果文件不存在,创建;若存在,异常。 APPEND 在文件的尾部追加 DELETE_ON_CLOSE ...

痴迷无限好 3179

Java NIO学习篇之StandardOpenOption详解

定义: StandardOpenOption是一个枚举类,代表着文件连接时的标准选项。通常可以多个选项一起使用。 public enum StandardOpenOption implements OpenOption { /** * 以读的方式连接文件。 */ READ, /** * 以写的方式连接文件。 */ WRITE, /** * 以追加的方式连接文件,不会覆盖文件原本内容,在后面追加。 */

qq_40837310的博客 6520

FileChannel(API详解)

1、两种获取通道的方法2、read3、write4、获取和设置通道的位置、大小5、long transferTo(position,count,WritableByteChannel dest)6、long transferFrom(ReadableByteChannel src,position,count)8、将通道文件区域直接映射到内存 map() 1、两种获取通道的方法 FileChan...

你学废了吗? 7212

Java NIO通道FileChannel详解

定义: StandardOpenOption是一个枚举类,代表着文件连接时的标准选项。通常可以多个选项一起使用。 public enum StandardOpenOption implements OpenOption { /** * 以读的方式连接文件。 */ READ, /** * 以写的方式连接文件。 */ WRITE, /** * 以追加的方式连接文件,不会覆盖文件原本内容,在后面追加。 */ ...

lixinkuan的博客 2923

Java尚硅谷基础笔记-day14 IO流

第十三章 IO流File类的使用IO流原理及流的分类节点流缓冲流转换流标准输入、输出流打印流数据流对象流随机存取文件流NIO.2中Path、Paths,Files类的使用 File类的使用 IO流原理及流的分类 节点流 缓冲流 转换流 标准输入、输出流 打印流 数据流 对象流 随机存取文件流 NIO.2中Path、Paths,Files类的使用 ...

alyja的博客 864

Java 入门指南:Java NIO —— Channel(通道

通道(Channel)是 `NIO`(New Input/Output)模型中的一个重要概念。通道代表着与底层 I/O 设备(如文件、网络套接字等)之间的连接,用于将数据传输到缓冲区或从缓冲区传输数据。 Channel 不与数据打交道,它只负责运输数据 通道NIO 中起到了桥梁作用,负责将数据从缓冲区传输到通道或者从通道传输到缓冲区。它是一个双向的数据传输通道

热带鱼的技术博客 2666
上一篇: java Nio(一)之缓冲区
下一篇: mybaties之for each
yjaspire
博客等级 码龄11年 55粉丝 78原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值