原文地址:http://blog.csdn.net/whoami021/article/details/21656875
上一篇文章我们实现聊天的功能,下面我们看文件传输怎么实现。
我的做法是:增加一个文件服务器,所有上传和下载文件的操作都由文件服务器来处理。
因此处理逻辑是这样的:如果用户请求上传文件或者下载文件,那么就将用户直接与文件服务器通信,而不用经过中央服务器。
所以现在的问题是知道java怎么实现上传和下载文件,如果这个问题解决了,那基本就搞定了。
首先,文件传输基本都是用面向连接的方式。因为无连接的方式容易丢包,一旦丢了一个数据包,文件就坏了,所有努力全白费。但是需要注意的是面向连接的方式,在服务器处理完一个连接后该连接就关闭了。
下面看代码,在原来的基础上我新建了两个主要文件:FileServer.java和FileClient..java。
- package chat.net.file;
- import java.io.BufferedInputStream;
- import java.io.BufferedOutputStream;
- import java.io.DataInputStream;
- import java.io.DataOutputStream;
- import java.io.File;
- import java.io.FileInputStream;
- import java.io.FileOutputStream;
- import java.io.IOException;
- import java.net.ServerSocket;
- import java.net.Socket;
- import java.util.Iterator;
- import java.util.Set;
- import java.util.TreeMap;
- import chat.Globals;
- /**
- * 文件服务器
- *
- * @author michael
- *
- */
- public class FileServer {
- private TreeMap fileMap = new TreeMap();
- private final String SavePath = "save/";// 上传文件保存目录
- private final int port = 8821;
- private ServerSocket ss;
- private Socket s;
- private String sender;// 上传者名字
- private String receiver;// 接收者名字
- private int bufferSize = 8192;
- public void start() {
- try {
- // 创建目录
- File file = new File(SavePath);
- if (!file.exists()) {
- file.mkdir();
- }
- ss = new ServerSocket(port);
- while (true) {
- s = ss.accept();
- DataInputStream dis = new DataInputStream(
- new BufferedInputStream(s.getInputStream()));
- dis.readByte();// 运行环境
- int req = dis.readInt();
- if (req == Globals.UploadReq) {// 用户上传文件
- recvFile(dis);
- } else {// 用户下载文件
- sendFile(dis);
- }
- }
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- private void recvFile(DataInputStream dis) {
- DataOutputStream dos = null;
- try {
- sender = dis.readUTF();// 发送者名字
- String savePath = SavePath;
- byte[] buf = new byte[bufferSize];
- long len = 0;
- String fileName = dis.readUTF();// 可能接收到终止的通知
- if (fileName.equals(String.valueOf(Globals.Exit))) {
- dis.close();
- return;
- }
- savePath += fileName;
- dos = new DataOutputStream(new BufferedOutputStream(
- new BufferedOutputStream(new FileOutputStream(savePath))));
- len = dis.readLong();
- System.out.println("文件的长度为:" + len);
- while (true) {
- int read = 0;
- if (dis != null) {
- read = dis.read(buf);
- }
- if (read == -1) {
- break;
- }
- dos.write(buf, 0, read);
- }
- fileMap.put(fileName, sender);
- System.out.println("接收完成,文件存为" + savePath);
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- try {
- dis.close();
- if (dos != null) {
- dos.close();
- }
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- }
- private void sendFile(DataInputStream dis) {
- DataOutputStream dos = null;
- DataInputStream fis = null;
- try {
- receiver = dis.readUTF();
- dos = new DataOutputStream(s.getOutputStream());
- // 给客户端发送文件列表
- String fileList = "文件列表:\n";
- if (fileMap.size() == 0) {
- dos.writeUTF("");
- return;
- }
- Set set = fileMap.keySet();
- Iterator it = set.iterator();
- String key;
- int i = 0;
- while (it.hasNext()) {
- ++i;
- key = it.next();
- fileList += i + ".";
- }
- dos.writeUTF(fileList);
- String fileName = getFileName(fileList, dis.readInt());
- File file = new File(SavePath + fileName);
- // 开始发送文件
- fis = new DataInputStream(new BufferedInputStream(
- new FileInputStream(file)));
- dos.writeUTF(fileName);
- dos.flush();
- dos.writeLong((long) file.length());
- dos.flush();
- byte[] buf = new byte[bufferSize];
- int read = 0;
- while (true) {
- read = fis.read(buf);
- if (read == -1) {
- break;
- }
- dos.write(buf, 0, read);
- }
- dos.flush();
- System.out.println("文件" + fileName + "传输完成");
- } catch (Exception e) {
- // TODO: handle exception
- e.printStackTrace();
- } finally {
- try {
- dis.close();
- if (fis != null) {
- fis.close();
- }
- dos.close();
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- }
- private String getFileName(String fileList, int no) {
- String fileName = fileList.substring(fileList.indexOf(String
- .valueOf(no)));
- fileName = fileName.substring(fileName.indexOf("
关注打赏最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?
立即登录/注册


微信扫码登录