文档章节

【JAVA】利用java-RMI进行大文件传输

王选易
 王选易
发布于 2013/05/28 11:25
字数 696
阅读 6525
收藏 123

点击进入我的新博客

#利用java-RMI进行大文件传输

###为什么要用RMI

在这次的项目中,对于客户端与服务器之间的通信,想了许多办法,由于做的是富客户端应用,最终将技术选定在了RMI和Java-sockets两种之间,其中RMI的灵活性不高,客户端和服务器端都必须是java编写,但使用比较方便,反观java-sockets,虽然比较灵活,但需要自己规定服务器端和客户端之间的通信协议。比较麻烦,几经权衡,最终还是选择RMI来进行服务器-客户端通信

###文件上传问题

在使用java-rmi的过程中,必然会遇到一个文件上传的问题,由于在rmi中无法传输文件流(比如rmi中的方法参数不能是FileInputStream之类的),那么我们只好选择一种折中的办法,就是先用FileInputStream将文件读到一个Byte数组中,然后把这个Byte数组作为参数传进RMI的方法中,然后在服务器端将Byte数组还原为outputStream,这样就能通过RMI来传输文件了

这样做也有缺点,就是无法检验传输过来的数据的准确性,汗。。。

下面我就一个实例来讲解一下

###文件结构

在此输入图片描述

FileClient

<!-- lang: java -->
package rmiupload;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;

public class FileClient {

	public FileClient() {
		// TODO Auto-generated constructor stub
	}
	
	public static void main(String[] args) {
		try {
			FileDataService fileDataService = (FileDataService) Naming.lookup("rmi://localhost:9001/FileDataService");
			fileDataService.upload("/Users/NeverDie/Documents/test.mp4", new FileClient().fileToByte("/Users/NeverDie/Music/test.mp4"));
		} catch (MalformedURLException | RemoteException | NotBoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
//这个方法比较重要,通过这个方法把一个名为filename的文件转化为一个byte数组
	private byte[] fileToByte(String filename){
		byte[] b = null;
		try {
			File file = new File(filename);
			b = new byte[(int) file.length()];
			BufferedInputStream is = new BufferedInputStream(new FileInputStream(file));
			is.read(b);
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return b;
	}
}

FileDataService

<!-- lang: java -->
package rmiupload;

import java.net.URL;
import java.rmi.Remote;
import java.rmi.RemoteException;

public interface FileDataService extends Remote{

	//这里的filename应该是该文件存放在服务器端的地址
	public void upload(String filename, byte[] file) throws RemoteException;
	
}

FileDataService_imp

<!-- lang: java -->
package rmiupload;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;
import java.rmi.RemoteException;
import java.rmi.server.RMIClientSocketFactory;
import java.rmi.server.RMIServerSocketFactory;
import java.rmi.server.UnicastRemoteObject;

public class FileDataService_imp extends UnicastRemoteObject implements FileDataService{

	public FileDataService_imp() throws RemoteException {
		
	}

	@Override
	public void upload(String filename, byte[] fileContent) throws RemoteException{
		File file = new File(filename);
		try {
			if (!file.exists())
				file.createNewFile();
			BufferedOutputStream os = new BufferedOutputStream(new FileOutputStream(file));
			os.write(fileContent);
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
;	}

}

FileServer

<!-- lang: java -->
package rmiupload;

import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;

public class FileServer {

	FileDataService fileDataService;
	
	public FileServer() {
		try {
			fileDataService = new FileDataService_imp();
			LocateRegistry.createRegistry(9001);
			Naming.rebind("rmi://localhost:9001/FileDataService", fileDataService);
		} catch (RemoteException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		new FileServer();

	}

}

© 著作权归作者所有

共有 人打赏支持
王选易
粉丝 90
博文 20
码字总数 20066
作品 3
南京
程序员
私信 提问
加载中

评论(19)

xiaobao36
xiaobao36
不错,马克了
起色
起色
好思路,学习了
王选易
王选易

引用来自“缪斯的情人”的评论

这个mina和netty岂不是更好

的确用mina,netty更好,这里只是给出一种简单的解决方案,对于小项目是够用了
缪斯的情人
缪斯的情人
这个mina和netty岂不是更好
hy86
hy86
如果客户端和服务端在网络上不同的机器上进行模拟,会不会有什么问题,要知道RMI容易遇到防火墙的问题
飞天遇见猪
飞天遇见猪
记录MD5码,可以校验准确性了~
温佐镜
温佐镜
用fileToByte方法把大文件读入内存,内存消耗会很严重
湛蓝的天空
感觉还是用socket靠谱些,rmi主要是用来传对象用的。
晒太阳的小猪
晒太阳的小猪
好东西!!!
王选易
王选易

引用来自“jorneyr”的评论

挺好的想法,底层都是Socket,与直接用Socket没有本质的区别。

嗯,似的,只不过是这样可以让整个应用全是用RMI,比较方便
用RMI实现基于Java的分布式计算(1)

向您介绍使用RMI实现Java的分布式计算。由于Java具有跨平台、代码可移植性、安全高效等广泛而强大的功能,因而在开发网络Java分布式应用的时候,可以用它自身的机制实现分布式计算。 概述 随...

山哥
2012/02/24
0
0
java 几种远程服务调用协议的比较

一、综述 本文比较了RMI,Hessian,Burlap,Httpinvoker,web service等5种通讯协议的在不同的数据结构和不同数据量时的传输性能。 RMI是java语言本身提供的远程通讯协议,稳定高效,是EJB的...

哈全文
2012/09/12
0
0
RMI:Java中的分布式计算框架

RMI全称是Remote Method Invocation-远程方法调用,Java RMI在JDK1.1中实现的,其威力就体现在它强大的开发分布式网络应用的能力上,是纯Java的网络分布式应用系统的核心解决方案之一。其实...

qq_39521554
05/15
0
0
java RMI 源码总结(个人理解)

明天早上详细写下两个过程: 1、初始化过程(服务器) 2、客户端调用过程(包括客户端流程、调用服务端流程、返回客户端流程) 当客户端通过RMI注册表找到一个远程接口的时候,所得到的其实是...

Java搬砖工程师
11/16
0
0
《Spring技术内幕》学习笔记18——Spring使用Hessian实现远程调用

Spring目前提供了对RMI、 HttpInvoker、Hessian、Burlap及WebService等Remoting技术的集成。Spring屏蔽了这些实现技术的差异,用户只需开发简单的Java对象(Plain Old Java Objects,POJO)然后...

谜男amu
05/16
0
0

没有更多内容

加载失败,请刷新页面

加载更多

linux中shell if 判断总结

UNIX Shell 里面比较字符写法 -eq 等于; -ne 不等于; -gt 大于; -lt 小于 ; -le 小于等于; -ge 大于等于; -z 空串; -n 非空串; = 两个字符相等; != 两个字符不等 无论什么编程语言都离不开条...

linuxprobe16
23分钟前
0
0
我是如何将博客转成PDF的

前言 只有光头才能变强 之前有读者问过我:“3y你的博客有没有电子版的呀?我想要份电子版的”。我说:“没有啊,我没有弄过电子版的,我这边有个文章导航页面,你可以去文章导航去找来看呀”...

Java3y
25分钟前
1
0
nginx的一些总结

Linux下安装Nginx完整教程及常见错误解决方案 1.Nginx安装环境 Nginx是C语言开发,建议在linux上运行,本教程使用Centos7.0作为安装环境. 1)gcc 安装nginx需要先将官网下载的源码进行编译,编译...

Yao--靠自己
32分钟前
1
0
Predicate函数式接口

Predicate接口主要用于流的筛选,比如在filter方法中传入Predicate判断。 作为函数式接口,这里居然有三个default方法,一个static方法,子孙满堂! 正统的接口方法,就是boolean test(T t)...

woshixin
33分钟前
1
0
sql 开窗函数

开窗函数:在开窗函数出现之前存在着很多用 SQL 语句很难解决的问题,很多都要通过复杂的相关子查询或者存储过程来完成。为了解决这些问题,在 2003 年 ISO SQL 标准加入了开窗函数,开窗函数...

hblt-j
43分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部