`

使用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和零拷贝_

    - **直接内存(Direct Byte Buffer)**:Java NIO中的直接缓冲区可以分配在JVM堆外内存,减少从Java对象到本机内存的拷贝,从而实现零拷贝。 - **mmap(Memory Mapped File)**:Java的FileChannel提供了一个映射...

    nio.rar_FastCopyFile.java_NIO_UseFloatBuffer.java_java nio_文件锁

    这个文件很可能是一个示例程序,演示了如何使用Java NIO进行高效的大文件复制。在传统的Java I/O中,我们通常使用InputStream和OutputStream进行文件复制,而这种方式需要不断读写,造成大量的上下文切换,效率较低...

    Large-File-Processing-master_javanio_java大文件处理_

    本项目“Large-File-Processing-master_javanio_java大文件处理_”显然专注于通过Java NIO实现大文件处理,下面我们将详细探讨相关的知识点。 1. **Java NIO基础**:NIO的核心组件包括通道(Channels)、缓冲区...

    NIO复制文件

    在复制文件时,我们用它来存储从源文件读取或写入目标文件的数据。 下面是一个简单的文件复制代码示例: ```java import java.io.IOException; import java.nio.ByteBuffer; import java.nio.channels.FileChannel...

    Java.NIO资源下载资源下载

    根据提供的文件信息,我们可以提取并总结出关于Java NIO(New Input/Output)的重要知识点。 ### Java NIO 概述 Java NIO 是 Java 平台的一个重要特性,首次出现在 Java 1.4 版本中。它为 Java 开发者提供了一套...

    Java NIO 中英文版

    - Java NIO提供了一组文件系统操作API,例如FileChannel用于读写文件,MappedByteBuffer实现了内存映射文件,可以直接通过内存访问文件内容,提高了读写速度。 4. **缓冲区的分类** - **ByteBuffer**:用于处理...

    java nio入门学习,两个pdf

    2. **文件操作**:NIO提供了高效、灵活的文件读写能力,特别是对于大数据处理,如日志分析、文件复制等。 3. **网络编程**:在网络通信中,NIO可以实现高效的客户端与服务器之间的数据传输,如HTTP、FTP服务器。 4...

    java中实现复制文件和文件夹

    在Java编程语言中,复制文件和文件夹...总的来说,Java中复制文件和文件夹涉及到文件I/O操作,可以通过使用基本的流类或`Files`类来实现。在处理复杂文件系统操作时,确保正确处理边界条件和异常,以保证程序的健壮性。

    NIO处理大文件

    这段代码展示了如何使用NIO读取一个大文件并写入另一个文件,通过循环读取和清空缓冲区,实现了高效的文件复制。 8. 性能对比: 相较于传统的IO,NIO在处理大文件时通常具有更高的吞吐量和更低的CPU占用。尤其是...

    java nio与io性能测试

    `FileChannel`类是NIO中用于文件操作的通道,配合`ByteBuffer`可以实现高效的文件读写。 在性能测试中,通常我们会比较IO和NIO在处理相同任务时的耗时。`CopyFile.java`可能是用于对比两者的文件复制性能的代码示例...

    java 使用IO流实现文件的复制

    本篇文章将详细介绍如何使用Java的IO流来实现文件的复制。 首先,我们需要了解Java中的IO流体系。Java的IO库基于流的概念,流可以视为数据的序列,可以从源(如键盘、文件)读取到目的地(如显示器、文件)。IO流...

Global site tag (gtag.js) - Google Analytics