`
jarbee
  • 浏览: 28320 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

通过RMI下载UNIX系统上的文件

    博客分类:
  • java
阅读更多
Server端:
1. 定义远程通讯的接口和与接口相关的类(这里只有RemoteFileInfo.java)。该接口必须继承接口Remote,它里面的方法都要抛出RemoteException异常。
FileManager.java
import java.rmi.Remote;
import java.rmi.RemoteException;

public interface FileManager extends Remote {

	/**
	 * 从远程服务器获取文件信息
	 * 
	 * @param path
	 * @param fileName
	 * @return
	 * @throws RemoteException
	 */
	public RemoteFileInfo getRemoteFile(String path, String fileName)
			throws RemoteException;

}

RemoteFileInfo.java
import java.io.Serializable;
import java.util.List;

/**
 * 文件实体类
 */
public class RemoteFileInfo implements Serializable{
	private String fileName; 	// 文件名
//	private byte[] content;
	private List content;		// 文件内容 (每1024个字节的内容作为列表的一个元素)
	
	
	public RemoteFileInfo(String fileName, List content) {
		this.fileName = fileName;
		this.content = content;
	}

	
	public List getContent() {
		return content;
	}

	public void setContent(List content) {
		this.content = content;
	}
	

	public String getFileName() {
		return fileName;
	}

	public void setFileName(String fileName) {
		this.fileName = fileName;
	}
	
}

2. 实现接口,根据RMI规范,接口实现类的名应以“接口文件名+Impl.java”命名。此类不仅要实现远程接口,还要继承UnicastRemoteObject类,声明构造函数(构造函数也要抛出RemoteException异常)
FileManagerImpl.java
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * 文件操作实现类
 */
public class FileManagerImpl extends UnicastRemoteObject implements FileManager {
private static final Log log = LogFactory.getLog(FileManagerImpl.class);

	public FileManagerImpl() throws RemoteException {
		super();
	}

	public RemoteFileInfo getRemoteFile(String path, String fileName)
			throws RemoteException {
		try {
			RemoteFileInfo remoteFile;
			List content = new ArrayList();
			File file = new File(path + fileName);
			BufferedInputStream in = new BufferedInputStream(
					new FileInputStream(file));
			
			// 处理大文件时,每次读取1024个字节存到centent对象
			byte[] bufContent = new byte[1024];
			while(in.read(bufContent) !=-1){
				content.add(bufContent);
				bufContent = new byte[1024];
			}
			
			/*
			// 只能用到内容少的文件,遇到大文件会出现内容溢出错误
			byte[] content = new byte[(int)file.length()];
			
			in.read(content);
			*/
			remoteFile = new RemoteFileInfo(fileName,content);
			log.info("Getting ["+fileName+"] is successful");
			
			return remoteFile;
		} catch (IOException e) {
			log.error("Failed to get ["+fileName+"] ...");
			e.printStackTrace();
			return null;
		}
	}

3. 生成Stub类(JDK为5.0或以上可以忽略此步),作此步时要先生成了实现类的class文件.
使用javac命令生成.class文件。(e.g. Unix下:javac -classpath .:./lib/commons-logging.jar:
./lib/log4j-1.2.15.jar package1/package2/FileManagerImpl.java)
 在命令行中运行 rmic –v1.2 FileManagerImpl,若实现类被打包要加上包名(e.g. rmic –v1.2 packageA.packageB.packageC. FileManagerImpl).
 若执行成功则会生成一个FileManagerImpl_Stub.class的类文件.
4. 实现RMI应用布署程序
FileServer.java
import java.io.InputStream;
import java.io.IOException;
import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * 布署应用
*/
public class FileServer {
	private static final Log log = LogFactory.getLog(FileServer.class);
	public static final String CONFIG_FILE_PATH = "/conf/config.properties";
	
	/**
	 * 获取配置信息
	 * @return	URL
	 */
	public static Map getURL(){
		try{
			String url, port;
			Map configs = new HashMap();
			Properties prop = new Properties();
			InputStream in = FileServer.class.getResourceAsStream(CONFIG_FILE_PATH);
		
			prop.load(in);
			url = prop.getProperty("server.interface");
			port = prop.getProperty("server.port");
			configs.put("url", url);
			configs.put("port", port);
			
			return configs;
		} catch (IOException e){
			System.out.println("读取配置信息失败!");
			e.printStackTrace();
			return null;
		}
	}
	
	public static void main(String[] args){
		try {
			Map configs = getURL();
			if(configs != null){
				String port = configs.get("port").toString();
				String url = configs.get("url").toString();
				
				// 根据端口号开启一个RMI服务.也可以不指定,默认为1099
				LocateRegistry.createRegistry(Integer.parseInt(port));
				FileManagerImpl fileMng = new FileManagerImpl();
						
				log.info("Binding URL:"+url);
			
				// 注册一个RMI应用
				// e.g. url: //127.0.0.1:20002/FILE_MNG
				Naming.rebind(url, fileMng);
				log.info("Deploy Remote File Server successfully!");
			}
			else{
				log.error("Binding Remote File Server failed...");
			}
			
		} catch (RemoteException e) {
			e.printStackTrace();
		} catch (MalformedURLException e) {
			e.printStackTrace();
		}
	}
	
}

5. 为了便于维护,最好将以上程序打到一个JAR包中,在META-INF下的MANIFEST.MF文件中指定运行JAR包需要的Main方法所在的类等信息,像这样:
Manifest-Version: 1.0
Main-Class: package1.package2..FileServer
Class-Path: webapp-server.jar commons-logging.jar log4j-1.2.15.jar
在Unix中用nohup命令在后台启动这个JAR包:
nohup java -jar lib/webapp-server.jar >> $HOME/nohupout/fileserver_log.out &
用ps –ef|grep webapp查看此进程。
如没有进程启动,查看日志文件的错误信息。

客户端1. 客户端需要的文件类有: 远程接口FileManager.java及其相关类,Stub类.
业务类
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import nantian.fxjk.web.util.AccessRemoteServer;

/**
 * 后台文件操作业务类
 */
public class FileClient {
	
	/**
	 * 获取远程服务器上的文件信息
	 * 
	 * @param path		文件路径
	 * @param fileName	文件名
	 * @return
	 */
	public RemoteFileInfo getRemoteFile(String path, String fileName){
		try{
			Map configs = getConfig();
			
			if (configs != null) {
				String url = configs.get("url").toString();
				String defaultPath = configs.get("abs_path").toString();
				
				// 查找一个已布署的远程服务
				// e.g. url: //128.128.96.2:20002/FILE_MNG
				FileManager fileMng = (FileManager) Naming.lookup(url);
	
				RemoteFileInfo file = fileMng.getRemoteFile(
						defaultPath + path, fileName);
				
				return file;
			}
			else{
				System.out.println("读取配置信息失败.");
				return null;
			}
		} catch (MalformedURLException e) {
			e.printStackTrace();
			return null;
		} catch (RemoteException e) {
			e.printStackTrace();
			return null;
		} catch (NotBoundException e) {
			e.printStackTrace();
			return null;
		}
	}

	/**
	 * 将远程服务器上的文件取到本地
	 * 
	 * @param fileInfo
	 * @return
	 */
	public boolean getRemoteFileToLocal(RemoteFileInfo fileInfo,
			String downloadPath) {
		File path = new File(downloadPath);

		if (!path.exists()) {
			path.mkdirs();
		}
		try {
			BufferedOutputStream out = new BufferedOutputStream(
					new FileOutputStream(downloadPath + fileInfo.getFileName()));
			List content = fileInfo.getContent();
			
			for(int i=0; i<content.size(); i++){
				out.write((byte[])content.get(i));
			}
			out.close();

			return true;
		} catch (IOException e) {
			e.printStackTrace();
			return false;
		}
	}

	/**
	 * 获取访问远程对象的相关配置信息
	 * 
	 * @return		配置信息
	 */
	public Map getConfig() {
		try {
			Map configs = new HashMap();
			Properties prop = new Properties();
			InputStream in = FileClient.class
					.getResourceAsStream(AccessRemoteServer.CONFIG_FILE_PATH);

			prop.load(in);
			configs.put("url", prop.getProperty("server.interface"));
			configs.put("abs_path", prop.getProperty("server.path"));
			configs.put("down_path", prop.getProperty("download.path"));

			return configs;
		} catch (IOException e) {
			e.printStackTrace();
			return null;
		}
	}

2. 编写响应请求的Servlet类
DownloadSysFileAction.java
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 下载后台文件的请求响应类
*/
public class DownloadSysFileAction extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		
		PrintWriter out;
		OutputStream outStream;
		FileClient fc = new FileClient();
		String fileLocation = request.getParameter("file");
		fileLocation = fileLocation.trim();
		String path = getPath(fileLocation);
		String fileName = getFileName(fileLocation);
		
		
		RemoteFileInfo file = fc.getRemoteFile(path, fileName);
		
		if(file != null){
			List content = file.getContent();
			outStream = response.getOutputStream();
			response.reset();
			response.setContentType("application/x-msdownload"); // 纯下载方式
			response.setHeader("content-disposition", "attachment; filename="+file.getFileName());
			
			for(int i=0; i<content.size(); i++){
				outStream.write((byte[]) content.get(i));
			}
			response.flushBuffer();
			outStream.close();
		}
		else{
			response.setContentType("text/html;charset=UTF-8");
			out = response.getWriter();
			out.println("<script type='text/javascript'>");
			out.println("alert('不存在该文件!'); window.close();");
			out.println("</script>");
			out.close();
			return ;
		}
		
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doGet(request,response);
	}
	// … … … 
}

3. 前台页面提供要下载的文件名和所在路径,再调用这个Servlet就可以下载远程服务器上的文件了
分享到:
评论

相关推荐

    获取windows or unix系统下服务器MAC地址及服务器IP地址

    在IT领域,获取服务器的MAC(Media Access Control)地址和IP(Internet Protocol)地址是常见的系统管理任务。MAC地址是网络设备的物理地址...在Unix/Linux系统中,还可以利用内核提供的虚拟文件系统来获取这些信息。

    asm.zip_Linux/Unix编程

    【标题】"asm.zip_Linux/Unix编程" 文件包涵盖了多个与Linux/Unix系统相关的编程主题,特别是关于URI(统一资源标识符)和UriBuilder类的使用。在Linux和Unix环境中,开发人员经常需要处理这些类来构建和操作URLs,...

    局域网中远程桌面监控系统的设计与实现.doc

    3.兼容性:远程桌面监控系统需要在不同的平台上运行,例如Windows、Linux、Unix等。 在本文中,我们将详细介绍远程桌面监控系统的设计与实现过程,包括系统的分析、设计和开发的全部过程。我们将使用Java语言实现...

    最新的大学计算机学科操作系统原理(有关如何学习操作系统原理)ppt课件下载

    后来,网络操作系统(如Windows NT,UNIX)和分布式操作系统(如Java RMI,DCE)应运而生,支持多台计算机间的协作和资源共享。 操作系统的发展历程展示了计算机科学的进步,从最初的无操作系统到现在的高度复杂和...

    操作系统的发展与分类ppt课件.ppt

    4. 分时系统:多个用户可以共享一台计算机,每个用户感觉上都在独占系统,如UNIX系统。 5. 实时操作系统:适用于需要快速响应的环境,如航空航天、工业控制等领域。 6. 个人计算机操作系统:如MS-DOS、Windows等,...

    操作系统复习资料大全——考试必备.doc

    - 分布式系统:运行在不同机器上,但用户感知为单一系统,如Java RMI、DCE等。 6. **习题解析**: - 操作系统是系统软件(A)。 - 多道程序设计是指在一台处理机上并发运行多个程序(D)。 - 随机性不会直接...

    操作系统精髓与设计原理第五版答案

    7. 并发和分布式系统:介绍并发编程的概念,线程管理和分布式系统的原理,如RPC、RMI等。 8. 实时系统:讲述实时操作系统的特性,调度策略,以及满足硬实时和软实时要求的方法。 9. 网络操作系统:讲解在网络环境...

    计算机导论-论文-计算机操作系统.pdf

    4. **文件系统管理**:操作系统组织和管理磁盘上的数据,提供文件创建、读取、写入和删除等功能。 5. **安全性管理**:保护系统资源,防止非法访问,确保数据的安全性。 6. **网络通信**:在多计算机环境中,操作...

    操作系统习题集(南京晓庄学院操作系统习题答案)参考.pdf

    - **文件系统**:组织和管理磁盘上的数据,支持文件的创建、读写、删除等操作。 - **安全管理**:保护系统和用户数据,防止非法访问。 操作系统的设计目标是提高资源利用率、减少用户等待时间、增强系统的可靠性和...

    计算机文化基础教程第二章操作系统基础知识PPT学习教案.pptx

    2. **分时操作系统**:分时系统允许多个用户同时通过终端使用计算机,每个用户轮流占用处理器,实现交互式操作,如Unix和Linux系统。 3. **实时操作系统**:实时操作系统对响应时间有严格要求,适用于工业控制、军事...

    Websphere 多系统安装及集群配置

    6. 配置集群间通信,如共享文件系统(用于共享应用程序和配置)、RMI端口和HTTP/HTTPS端口。 7. 部署应用程序到集群,确保所有服务器实例都能访问。 三、AIX环境下的WebSphere安装与配置 “WebSphere在AIX环境中...

    RmiChat:Java RMI示例的通讯聊天。-开源

    例如,`RmiChat.jar`可能包含了聊天服务的实现,而`rmi.policy`文件则定义了RMI的安全策略,这在处理跨网络的交互时尤其重要,因为RMI操作可能涉及到权限控制。 RMI的使用步骤通常包括以下几步: 1. **定义远程接口...

    自考计算机应用基础-第2章.ppt

    6. **分布式操作系统**:分布在不同计算机上的系统组件共同工作,形成一个整体,如Java RMI或Google的GFS。 在个人计算机领域,常见的操作系统有DOS、Windows、OS/2和UNIX。Windows 2000作为一款微软公司开发的网络...

    2016年系统架构设计师考试考点,重点,难点汇总

    13. UNIX Shell 是UNIX操作系统中的命令行解释器,用于执行用户输入的命令。 14. DSS(Decision Support System)即决策支持系统,是一种交互式的计算机系统,旨在帮助决策制定。 15. COTS(Commercial Off-The-...

    java实现守护进程,有单独的监听进程, 两个或多个进程,两个或多个jvm

    3. 设置父进程为init进程:在Unix系统中,这通常是通过改变进程组和会话ID来实现的,但在Java中,这个操作较复杂,可能需要通过操作系统调用来完成。 创建多个进程和JVM可以通过`java.lang.ProcessBuilder`类实现。...

    大学计算机基础第5章作业.pdf

    分布式操作系统(DOS)如Java RMI、CORBA,使分布在不同节点的程序协同工作。两者的主要区别在于,NOS强调网络资源的共享和管理,而DOS强调分布式计算的透明性和协作性。 4. 进程有就绪、运行和等待三种基本状态。...

    第2章 计算机基础知识 .ppt

    3. **分时操作系统**:允许多个用户同时交互使用,如早期的Unix系统。 4. **实时操作系统**:响应时间严格,常用于工业控制等领域。 5. **网络操作系统**:支持网络环境下多用户共享资源,如Windows NT。 6. **...

    计算机网络技术总结.pdf

    2. 分时系统:允许多个用户同时在线交互,如Unix和Linux系统,具有多路性、交互性和及时性,适用于多用户共享计算资源的环境。 3. 实时系统:快速响应外部事件,保证处理时间限制,常用于工业控制和航空航天等领域...

    ACE自适配通讯环境课件

    总之,ACE是一个强大的通信软件开发工具,通过提供一套全面的库和框架,简化了在多种操作系统上构建复杂通信服务的难度。对于需要在分布式系统中实现高效通信的开发者来说,ACE是一个不可或缺的资源。

    apache-jmeter-5.6.2.zip

    - `bin` 目录:包含可执行文件和配置文件,如`jmeter.bat`(Windows)或`jmeter.sh`(Unix/Linux)。 - `lib` 目录:包含JMeter运行所需的库文件,如JUnit、MongoDB等连接器。 - `LICENSE` 和 `NOTICE` 文件:包含了...

Global site tag (gtag.js) - Google Analytics