Java NIO传输文件

这篇博客介绍了如何使用Java NIO进行文件传输,以解决传统socket方式存在的线程资源消耗问题。通过NIO的Selector实现单线程管理多个连接,降低CPU切换开销。同时,结合线程池进一步优化,提高系统效率。文章提供了NIO传输文件的示例代码,并详细解析了NIO的选择器工作原理。
摘要由CSDN通过智能技术生成

首先请确保已经学习了Java NIO的基础知识,包括Buffer,Channel文件通道和Socket通道,Selector。关于NIO比起I/O的好处,区别等这里就不说了。具体可以参考后面的参考链接等。

这篇博客主要以一个使用NIO传输文件的例子来学习NIO中网络的基本操作

传统的监控socket方式存在的问题

传统的监控多个socket的Java解决方案是为每个socket创建一个线程并使得线程可以在read调用时阻塞,直到数据可用。实际上这种方案有很大的弊端就是当建立很多链接需要创建很多线程,这些线程的创建管理要耗费很大的资源,也许在这个连接上只发送少量的数据,但是CPU切换也要耗费好多资源。于是为了减少系统线程的开销,采用线程池的办法来减少线程创建和回收的成本,但是有一些使用场景仍然是无法解决的,如果建立的都是长连接,事实上它们并不是每时每刻都在传输数据,这时不可能创建那么多的连接。

使用NIO就可以有效的解决这个问题,利用NIO提供的选择器Selector,可以使用一个线程管理多个连接,这实际上是一种I/O复用。

NIO传输文件例子

下面使用NIO做了一个向服务器端上传文件的例子

服务器端代码

public class Server {
	private ByteBuffer buffer = ByteBuffer.allocate(1024*1024);
        //使用Map保存每个连接,当OP_READ就绪时,根据key找到对应的文件对其进行写入。若将其封装成一个类,作为值保存,可以再上传过程中显示进度等等
	Map<SelectionKey, FileChannel> fileMap = new HashMap<SelectionKey, FileChannel>();
	public static void main(String[] args) throws IOException{
		Server server = new Server();
		server.startServer();
	}
	public void startServer() throws IOException{
		Selector selector = Selector.open();
		ServerSocketChannel serverChannel = ServerSocketChannel.open();
		serverChannel.configureBlocking(false);
		serverChannel.bind(new InetSocketAddress(8888));
		serverChannel.register(selector, SelectionKey.OP_ACCEPT);
		System.out.println("服务器已开启...");
		while (true) {
			int num = selector.select();
			if (num == 0) continue;
			Iterator<SelectionKey> it = selector.selectedKeys().iterator();
			while (it.hasNext()) {
				SelectionKey key = it.next();
				if (key.isAcceptable()) {
					ServerSocketChannel serverChannel1 = (ServerSocketChannel) key.channel();
					SocketChannel socketChannel = serverChannel1.acce
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值