`

使用java NIO实现复制文件

阅读更多
前几天自己在做一个小实验来着,突然想到自己以前通过TCP(socket)的方式做过复制文件的事情,然后就想到貌似没试过UDP(DatagramSocket)的方式实现复制文件(其实这从头就是个错误的思路)。遂马上动手试验,理所当然的写到后面就发现这样的方式有缺陷(UDP本身特性决定了),但是在思索有不有其他的变通的方式实现的时候,无意中看到了NIO这个以前一直没注意的东西,当时还想通过NIO找一些变通方式,但是看着看着觉得NIO很有意思。例如,这个实现本地复制文件的方法
FileChannel src=new FileInputStream(new File(pathName_from)).getChannel();
FileChannel dst=new FileOutputStream(new File(pathName_to)).getChannel();
dst.transferFrom(src, 0, src.size());


可能很多人以前都知道和使用过NIO的很多特性,但是我以前真是没接触过所以受到触动,就学习了更多NIO的东西,然后就实现了下面的这个程序。
服务端:
package com.googlefans.NIO;

import java.io.FileOutputStream;
import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;

public class NIOCopyServer implements Runnable{

	private FileChannel channel_to;
	private Selector selector;
	
	@SuppressWarnings("resource")
	public NIOCopyServer(int port) throws IOException{
		selector=Selector.open();
		ServerSocketChannel serverChannel=ServerSocketChannel.open();
		serverChannel.configureBlocking(false);
		serverChannel.socket().bind(new InetSocketAddress(InetAddress.getLocalHost(),port));
		serverChannel.register(selector, SelectionKey.OP_ACCEPT);
		channel_to=new FileOutputStream("E:\\testTo.txt").getChannel();
	}
	
	@Override
	public void run() {
		// TODO Auto-generated method stub
		while(true){
			try {
				selector.select();
				Iterator<SelectionKey> it=selector.selectedKeys().iterator();
				ByteBuffer inBuffer=ByteBuffer.allocate(1024);
				if(it.hasNext()){
					SelectionKey key=it.next();
					it.remove();
					if(key.isAcceptable()){
						ServerSocketChannel server=(ServerSocketChannel)key.channel();
						SocketChannel channel=server.accept();
						channel.configureBlocking(false);
						while(channel.read(inBuffer)!=-1){
							inBuffer.flip();
							channel_to.write(inBuffer);
							inBuffer.compact();
						}
						System.out.println("服务器端复制完毕!");
					}else if(key.isReadable()){
						read(key);
					}
				}
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
		}
	}

	public void read(SelectionKey key) throws IOException{
		SocketChannel channel=(SocketChannel)key.channel();
		ByteBuffer byteBuf=ByteBuffer.allocateDirect(1024);
		channel.read(byteBuf);
		byte[] data=byteBuf.array();
		String msg=new String(data).trim();
		System.out.println("服务器端收到信息:"+msg);
	}
	
}



客户端:
package com.googlefans.NIO;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.util.Iterator;

public class NIOCopyClient implements Runnable{

	private Selector selector;
	private FileChannel channel_from;
	
	@SuppressWarnings("resource")
	public NIOCopyClient(InetAddress ip,int port) throws IOException{
		selector=Selector.open();
		SocketChannel channel=SocketChannel.open();
		channel.configureBlocking(false);
		channel.connect(new InetSocketAddress(ip,port));
		channel.register(selector, SelectionKey.OP_CONNECT);
		channel_from=new FileInputStream(new File("E:\\testFrom.txt")).getChannel();
	}
	
	@Override
	public void run() {
		// TODO Auto-generated method stub
		while(true){
			try {
				selector.select();
				Iterator<SelectionKey> it=selector.selectedKeys().iterator();
				ByteBuffer outBuffer=ByteBuffer.allocate(1024);
				if(it.hasNext()){
					SelectionKey key=it.next();
					it.remove();
					if(key.isConnectable()){
						SocketChannel channel=(SocketChannel)key.channel();
						if(channel.isConnectionPending()){
							channel.finishConnect();
						}
						channel.configureBlocking(false);
						while(channel_from.read(outBuffer)!=-1){
							outBuffer.flip();
							channel.write(outBuffer);
							outBuffer.compact();
						}
						System.out.println("客户端上传完毕!");
					}else if(key.isReadable()){
						read(key);
					}
				}
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

	public void read(SelectionKey key) throws IOException{
		SocketChannel channel=(SocketChannel)key.channel();
		ByteBuffer bb=ByteBuffer.allocate(1024);
		channel.read(bb);
		byte[] bytes=bb.array();
		String msg=new String(bytes).trim();
		System.out.println("客户端收到信息:"+msg);
	}
}



实现类:

package com.googlefans.NIO;

import java.io.IOException;
import java.net.InetAddress;

public class NIOCopy {

	private final static int PORT=5111;
	public static void main(String[] args){
		try {
			Thread server=new Thread(new NIOCopyServer(PORT));
			Thread client=new Thread(new NIOCopyClient(InetAddress.getLocalHost(), PORT));
			server.start();
			client.start();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}



当然我这段程序还是有很多不令人满意的地方,比如read()方法。还是希望各位ITeye的大牛们多多指导。
0
0
分享到:
评论

相关推荐

    NIO与零拷贝_javanio_nio和零拷贝_

    java nio和零拷贝 方面知识,适合对nio和零拷贝感兴趣的开发人员

    javaNIO实例

    该资源包含了一个用javaNIO实现的读写文件以及复制文件的简单的demo,程序注释清晰,简单易懂,喜欢的下载!!!

    java实现文件夹同步/对比功能

    纯java实现,nio复制。其中文件夹复制同步使用channel实现,文件夹的交并集对比使用lamda实现,文件的同步比对逻辑通过比对文件的大小、日期、修改时间等实现

    编写一个java应用程序将一个包含多个子目录和文件的目录复制到另外一个指定的目录下

    编写一个java应用程序,将一个包含多个子目录和文件的目录复制到另外一个指定的目录下。 实验要求 1)欲复制的目录中包含的文件数和子目录层次未知,必须在程序执行时获得这些信息。 2)显示欲复制的目录的...

    Java思维导图xmind文件+导出图片

    Java客户端实现Kafka生产者与消费者实例 kafka的副本机制及选举原理剖析 基于kafka实现应用日志实时上报统计分析 RabbitMQ 初步认识RabbitMQ及高可用集群部署 详解RabbitMQ消息分发机制及主题消息分发 ...

    java文件读写处理

    对文件的读取,写入,文件复制等,包括:customBuffer复制文件,nioBuffer复制文件,nioTransfer复制文件

    nio:Clojure对java.nio的支持

    将clojure.java.io的输入流,输出流和复制功能扩展到java.nio类。 定义新的强制功能缓冲区,字节缓冲区,字符缓冲区,双缓冲区,浮点缓冲区,整数缓冲区,长缓冲区,短缓冲区,通道,可读通道和可写通道。 这些功能...

    flumeng-plugins-udp:使用java nio消费udp消息的flume-ng源码插件

    使用java nio消费udp消息的flume-ng源码插件Flume-ng ( )。 该插件基于 Apache Flume 1.5.0.1 和 Redis 2.8.17。特征源消费udp消息Netty ( ) 使用用法构建或下载 jar。 使用mvn clean package检出和构建将flumeng-...

    JAVA上百实例源码以及开源项目

     Java二进制IO类与文件复制操作实例,好像是一本书的例子,源代码有的是独立运行的,与同目录下的其它代码文件互不联系,这些代码面向初级、中级Java程序员。 Java访问权限控制源代码 1个目标文件 摘要:Java源码,...

    JAVA上百实例源码以及开源项目源代码

     Java二进制IO类与文件复制操作实例,好像是一本书的例子,源代码有的是独立运行的,与同目录下的其它代码文件互不联系,这些代码面向初级、中级Java程序员。 Java访问权限控制源代码 1个目标文件 摘要:Java源码,...

    疯狂JAVA讲义

    学生提问:当我们使用编译C程序时,不仅需要指定存放目标文件的位置,也需要指定目标文件的文件名,这里使用javac编译Java程序时怎么不需要指定目标文件的文件名呢? 13 1.5.3 运行Java程序 14 1.5.4 根据...

    java7-fs-more:java.nio.file 的一组实用方法(递归复制删除等)

    这是什么这是一组用于操作 JSR 203 的所有内容的实用程序,即新的 java.nio.file API。 它需要 Java 7+。 除了 JRE 之外没有其他依赖项。版本当前版本是0.2.0 : dependencies { compile( group : " ...

    Java JDK 7学习笔记(国内第一本Java 7,前期版本累计销量5万册)

    12.4 nio2文件系统 405 12.4.1 api架构概述 405 12.4.2 操作路径 406 12.4.3 属性读取与设定 409 12.4.4 操作文档与目录 412 12.4.5 读取、访问目录 414 12.4.6 过滤、搜索文档 418 12.5 重点复习 ...

    Java常见面试问题整理.docx

    在JDK1.4 中新加入了NIO(New Input/Output)类,引入了一种基于通道(Channel)与缓冲区(Buffer)的I/O 方式,它可以使用native 函数库直接分配堆外内存,然后通过一个存储在Java堆中的DirectByteBuffer 对象作为这块...

    java6.0源码-elfinder-java-connector:elFinderJava插件实现

    对远程服务器上的文件和文件夹的所有操作(复制、移动、上传、创建文件夹/文件、重命名等) 本地文件系统和支持 Web 驱动程序的总代码基础结构,例如:Dropobox。 档案创建/提取(zip、tar、tgz) 支持的命令 调暗...

    java8stream源码-SharedBookmark:同步我的工作书签

    java8 stream 源码 Table of Contents 杂项 ...[数据库主从复制,读写分离,负载均衡,分库分表分别表达的什么概念? ]() RSS RPC框架 本科毕设 Mathematica 测试工作 stability test mysqltest 投

    JAVA核心知识点整理(有效)

    25 JAVA8 与元数据.................................................................................................................................25 2.4. 垃圾回收与算法 .................................

    panoptic:[已弃用] 监视您的文件和目录的更改!

    panoptic 现在已被弃用,因为有更干净、更好的方法 - 最显着的是 Java NIO 的 Watcher API - 来监视文件系统。 如果你想接手,联系我; 否则,未来的发展将仅限于处理现有实施的问题。用法莱宁根( ) [panoptic " ...

    Eclipse

    由于eclipse-to-maven使用java.nio功能,因此您需要JDK 1.7+ 使用Maven“ mvn clean install”创建eclipse-to-maven版本 将现有工作空间复制到单独的目录中。 设置 在运行应用程序之前,请遵循以下src/main/java/...

Global site tag (gtag.js) - Google Analytics