文档章节

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

王选易
 王选易
发布于 2013/05/28 11:25
字数 696
阅读 6395
收藏 123
点赞 0
评论 19

点击进入我的新博客

#利用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();

	}

}

© 著作权归作者所有

共有 人打赏支持
王选易
粉丝 86
博文 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中的分布式计算框架

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

qq_39521554 ⋅ 05/15 ⋅ 0

《Spring技术内幕》学习笔记18——Spring使用Hessian实现远程调用

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

谜男amu ⋅ 05/16 ⋅ 0

Java序列化技术即将被废除!!!

我们的对象并不只是存在内存中,还需要传输网络,或者保存起来下次再加载出来用,所以需要Java序列化技术。Java序列化技术正是将对象转变成一串由二进制字节组成的数组,可以通过将二进制数据...

Java技术栈 ⋅ 05/30 ⋅ 0

JDK工具jstatd用法详解(转)

jstatd,即虚拟机的jstat守护进程,主要用于监控JVM的创建与终止,并提供一个接口允许远程监控工具依附到在本地主机上运行的JVM。 用法摘要 jstatd [ options ] 命令行选项。这些选项可以是任...

easonjim ⋅ 2017/09/06 ⋅ 0

做几道基础的Java测试题,看看最近有进步吗?欢迎来学习

Java是一种可以撰写跨平台应用软件的面向对象的程序设计语言。Java 技术具有卓越的通用性、高效性、平台移植性和安全性,广泛应用于PC、数据中心、游戏控制台、科学超级计算机、移动电话和互...

启示录是真的 ⋅ 05/24 ⋅ 0

java程序员基础进阶篇,万丈高楼平地起

一.final,finally,finalize 三者区别 Final是一个修饰符: 当final修饰一个变量的时候,变量变成一个常量,它不能被二次赋值 当final修饰的变量为静态变量(即由static修饰)时,必须在声明这...

启示录是真的 ⋅ 05/26 ⋅ 0

Java编程基础知识点和技术点归纳

Java是一种可以撰写跨平台应用软件的面向对象的程序设计语言。Java 技术具有卓越的通用性、高效性、平台移植性和安全性,广泛应用于PC、数据中心、游戏控制台、科学超级计算机、移动电话和互...

Java小辰 ⋅ 05/23 ⋅ 0

关于ORACLE数据传输加密的介绍

Oracle数据库的高级安全选项提供了传输数据加密、数据完整性验证等多项功能,在一定程度上可以保证数据传输的安全性。 连接到ORACLE数据库方式有两种,一种是通过sqlnet.ora文件,另一种是通...

tututu_jiang ⋅ 04/28 ⋅ 0

tomcat支持哪些j2ee技术!

j2ee的13种核心技术:JDBC, JNDI, EJBS, RMI, JSP, JAVA SERVLETS, XML, JMS, JAVA IDL, JTS, JTA, JAVAMAIL 和 JAF tomcat支持的有哪些呢? 我所知道的是 支持:JDBC,JSP,Java Servlet,XML,......

MrBoyce ⋅ 05/14 ⋅ 0

ZooKeeper学习笔记八 ZooKeeper典型应用场景——命名服务

《从Paxos到ZooKeeper分布式一致性原理与实践》 电子工业出版社 命名服务是分布式系统中比较常见的一类场景。命名服务是分布式系统最基本的公共服务之一。在分布式系统中,被命名的实体通常可...

xundh ⋅ 05/02 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

Day 17 vim简介与一般模式介绍

vim简介 vi和Vim的最大区别就是编辑一个文件时vi不会显示颜色,而Vim会显示颜色。显示颜色更便于用户编辑,凄然功能没有太大的区别 使用 yum install -y vim-enhanced 安装 vim的三种常用模式...

杉下 ⋅ 59分钟前 ⋅ 0

【每天一个JQuery特效】根据可见状态确定是否显示或隐藏元素(3)

效果图示: 主要代码: <!DOCTYPE html><html><head><meta charset="UTF-8"><title>根据可见状态确定 是否显示或隐藏元素</title><script src="js/jquery-3.3.1.min.js" ty......

Rhymo-Wu ⋅ 今天 ⋅ 0

OSChina 周四乱弹 —— 初中我身体就已经垮了,不知道为什么

Osc乱弹歌单(2018)请戳(这里) 【今日歌曲】 @加油东溪少年 :下完这场雨 后弦 《下完这场雨》- 后弦 手机党少年们想听歌,请使劲儿戳(这里) @马丁的代码 :买了日本 日本果然赢了 翻了...

小小编辑 ⋅ 今天 ⋅ 12

浅谈springboot Web模式下的线程安全问题

我们在@RestController下,一般都是@AutoWired一些Service,由于这些Service都是单例,所以并不存在线程安全问题。 由于Controller本身是单例模式 (非线程安全的), 这意味着每个request过来,...

算法之名 ⋅ 今天 ⋅ 0

知乎Java数据结构

作者:匿名用户 链接:https://www.zhihu.com/question/35947829/answer/66113038 来源:知乎 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 感觉知乎上嘲讽题主简...

颖伙虫 ⋅ 今天 ⋅ 0

Confluence 6 恢复一个站点有关使用站点导出为备份的说明

推荐使用生产备份策略。我们推荐你针对你的生产环境中使用的 Confluence 参考 Production Backup Strategy 页面中的内容进行备份和恢复(这个需要你备份你的数据库和 home 目录)。XML 导出备...

honeymose ⋅ 今天 ⋅ 0

JavaScript零基础入门——(九)JavaScript的函数

JavaScript零基础入门——(九)JavaScript的函数 欢迎回到我们的JavaScript零基础入门,上一节课我们了解了有关JS中数组的相关知识点,不知道大家有没有自己去敲一敲,消化一下?这一节课,...

JandenMa ⋅ 今天 ⋅ 0

火狐浏览器各版本下载及插件httprequest

各版本下载地址:http://ftp.mozilla.org/pub/mozilla.org//firefox/releases/ httprequest插件截至57版本可用

xiaoge2016 ⋅ 今天 ⋅ 0

Docker系列教程28-实战:使用Docker Compose运行ELK

原文:http://www.itmuch.com/docker/28-docker-compose-in-action-elk/,转载请说明出处。 ElasticSearch【存储】 Logtash【日志聚合器】 Kibana【界面】 答案: version: '2'services: ...

周立_ITMuch ⋅ 今天 ⋅ 0

使用快嘉sdkg极速搭建接口模拟系统

在具体项目研发过程中,一旦前后端双方约定好接口,前端和app同事就会希望后台同事可以尽快提供可供对接的接口方便调试,而对后台同事来说定好接口还仅是个开始、设计流程,实现业务逻辑,编...

fastjrun ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部