客户端
package com.ithiema.yunpan;
import java.io.*;
import java.net.Socket;
import java.util.ResourceBundle;
import java.util.Scanner;
public class FileUpDownServiceImp implements FileUpDownService {
/*
用来保存当前浏览的目录
*/
_public File current = new File(“root”)_;
private ResourceBundle bundle;
private String downloadPath;
private String serverAddress;
private int port;
@Override<br /> public void start_() {<br /> _try _{<br /> //初始化下载路径,读取配置文件中的数据<br /> _bundle = ResourceBundle._getBundle(_"yunpan"_)_;<br /> downloadPath = bundle.getString_(_"DownloadPath"_)_;<br /> serverAddress = bundle.getString_(_"serverAddress"_)_;<br /> port = Integer._parseInt(_bundle.getString_(_"port"_))_;<br /> File downloadDir = new File_(_downloadPath_)_;<br /> if _(_downloadDir.isFile_()) {<br /> _throw new BusinessException_(_"文件不能当做下载目录,请更改下载路径配置!"_)_;<br /> _} _else if _(_!downloadDir.exists_() _&& !downloadDir.mkdirs_()) {<br /> _throw new BusinessException_(_"下载目录初始化失败,请检查下载路径配置是否正确!"_)_;<br /> _}
_Scanner sc = new Scanner_(_System._in)_;<br /> System._out_.println_(_"*******欢迎进入黑马网盘*******"_)_;<br /> _//先显示根目录文件<br /> _scanDirection_(_current_)_;
while _(_true_) {<br /> _System._out_.println_(_"***************************************************************************"_)_;<br /> System._out_.println_(_"1)浏览当前目录 \t2)浏览子目录 \t3)返回上一级目录 \t4)下载文件 \t5)上传文件 \t6)退出系统"_)_;<br /> System._out_.println_(_"***************************************************************************"_)_;<br /> String choice = sc.nextLine_()_;<br /> String str="6";<br /> if _(_choice.equals_(_str_)){<br /> _break;<br /> _}<br /> _switch _(_choice_) {<br /> _case "1":<br /> scanDirection_(_current_)_;<br /> break;<br /> case "2":<br /> System._out_.println_(_"请输入要浏览的子目录:"_)_;<br /> String dir = sc.nextLine_()_;
try _{<br /> //扫描<br /> _scanDirection_(_new File_(_current, dir_))_;<br /> _} _catch _(_Exception e_) {<br /> _e.printStackTrace_()_;<br /> _}<br /> _break;<br /> case "3":<br /> if _(_current.getName_()_.equals_(_"root"_)) {<br /> _System._out_.println_(_"没有上一级了"_)_;<br /> _} _else _{<br /> _scanDirection_(_current.getParentFile_())_;<br /> _}
_break;<br /> case "4":<br /> _//下载<br /> _System._out_.println_(_"请输入要下载的文件名(含后缀):"_)_;<br /> String fileName = sc.nextLine_()_;_//abc<br /> //current=root<br /> _downloadFile_(_new File_(_current, fileName_))_;_//root/abc
_break;
case "5":<br /> while _(_true_) {<br /> _System._out_.println_(_"请输入在计算机中要上传的文件路径"_)_;<br /> String uploadFilePath = sc.nextLine_()_;<br /> File upFile = new File_(_uploadFilePath_)_;<br /> if _(_!upFile.exists_()) {<br /> _System._out_.println_(_"文件不存在,请重新输入!"_)_;<br /> _} _else if _(_upFile.isDirectory_()) {<br /> _System._out_.println_(_"抱歉,不支持目录上传!"_)_;<br /> _} _else if _(_upFile.isFile_()) {<br /> _uploadFile_(_upFile_)_;<br /> break;<br /> _}<br /> }
_default:<br /> System._out_.println_(_"功能尚在开发中...."_)_;<br /> _}
}<br /> } _catch _(_Exception e_) {<br /> _e.printStackTrace_()_;<br /> _}<br /> }
/**<br /> * 连接服务端<br /> *<br /> * @return<br /> * @throws IOException<br /> */<br /> _@Override<br /> public Socket connect_() _throws IOException _{<br /> _Socket socket = new Socket_(_serverAddress, port_)_;<br /> return socket;<br /> _}
/**<br /> * 文件浏览<br /> *<br /> * @param path<br /> * @throws IOException<br /> */<br /> _@Override<br /> public void scanDirection_(_File path_) {<br /> //连接服务端<br /> _try _(_Socket socket = connect_()_;<br /> InputStream netIn = socket.getInputStream_()_;<br /> OutputStream netOut = socket.getOutputStream_()_;_) {
//获取了协议<br /> _Protocol scanDirProtocol = Protocol._getScanDirProtocol(_path.getPath_())_;<br /> send_(_netOut, scanDirProtocol_)_;<br /> _//接收消息<br /> _InputStreamReader isr = new InputStreamReader_(_netIn_)_;<br /> BufferedReader br = new BufferedReader_(_isr_)_;<br /> String content;<br /> _//System.out.println("开始接收数据:");<br /> _String firstLine = br.readLine_()_;_//协议<br /> _Protocol protocol = Protocol._parseProtocol(_firstLine_)_;
_//System.err.print("pro:" + protocol);<br /> _if _(_protocol.getStatus_()_.equals_(_Protocol.Status._OK)) {<br /> //成功<br /> _current = new File_(_protocol.getFileName_())_;<br /> System._out_.println_(_"---------------------------------------------------"_)_;<br /> System._out_.println_(_"当前目录:" + current_)_;<br /> while _((_content = br.readLine_()) _!= null_) {<br /> _System._out_.println_(_content_)_;<br /> _}<br /> } _else _{<br /> _System._out_.println_(_"浏览失败:" + protocol.getMessage_())_;<br /> _}
} _catch _(_IOException e_) {<br /> _e.printStackTrace_()_;<br /> _}<br /> }
/**<br /> * 文件下载<br /> *<br /> * @param file<br /> */<br /> _@Override<br /> public void downloadFile_(_File file_) {<br /> //TODO 按照文档提供业务流程完成客户端下载文件<br /> _try _(<br /> _Socket socket=connect_()_;<br /> OutputStream netOut=socket.getOutputStream_()_;<br /> InputStream netIn=socket.getInputStream_()_;<br /> _){<br /> _Protocol downloadProtocol = Protocol._getDownloadProtocol(_file.getPath_())_;<br /> send_(_netOut,downloadProtocol_)_;<br /> Protocol response = Protocol._parseProtocol(_netIn_)_;<br /> if_(_response.getStatus_()_.equals_(_Protocol.Status._OK)){<br /> _try _(_FileOutputStream fos=new FileOutputStream_(_new File_(_downloadPath,file.getName_()))){<br /> _IOUtil._copy(_netIn,fos_)_;<br /> _}<br /> _System._out_.println_(_"下载好了 请自行查看!"_)_;<br /> _}_else _{<br /> _System._out_.println_(_"下载失败 请确认原因:"+response.getMessage_())_;
_}<br /> }_catch _(_Exception e_){<br /> _e.printStackTrace_()_;
_}
}
/**<br /> * 文件上传<br /> *<br /> * @param upFile<br /> */<br /> _@Override<br /> public void uploadFile_(_File upFile_) {<br /> //TODO 按照文档提供业务流程完客户端上传文件<br /> //1.客户端连接服务端,参考文件浏览功能<br /> _try_(_Socket socket=connect_()_;<br /> InputStream netIn=socket.getInputStream_()_;<br /> OutputStream netOut = socket.getOutputStream_()_;_){<br /> //2.发送协议<br /> //构建一个虚拟路径,告诉服务端上传的位置<br /> _Protocol uploadProtocol = Protocol._getUploadProtocol(_new File_(_current,upFile.getName_()))_;<br /> send_(_netOut,uploadProtocol_)_;<br /> _//解析服务器返回的协议信息<br /> _Protocol response = Protocol._parseProtocol(_netIn_)_;<br /> _//判断服务端是否可以上传?<br /> _if_(_response.getStatus_()_.equals_(_Protocol.Status._OK)){<br /> _try _(_FileInputStream localIn=new FileInputStream_(_upFile_)){<br /> //开始上传文件<br /> _System._out_.println_(_"正在上传"+response.getMessage_())_;<br /> IOUtil._copy(_localIn, netOut_)_;<br /> _//通知对方文件已经上传完毕
_socket.shutdownOutput_()_;<br /> _}<br /> _response=Protocol._parseProtocol(_netIn_)_;<br /> System._out_.println_(_"已经成功上传:"+response.getMessage_())_;
_}_else _{<br /> _System._out_.println_(_"上传失败了"+response.getMessage_())_;<br /> _}<br /> } _catch _(_IOException e_) {<br /> _e.printStackTrace_()_;<br /> _}
// Protocol uploadProtocol = Protocol.getUploadProtocol(new File(current,upFile.getName()));
// System.out.println(“uploadProtocol = “ + uploadProtocol);
}
/**<br /> * 发送协议<br /> *<br /> * @param netOut 网络输出流<br /> * @param scanDirProtocol 协议<br /> * @throws IOException<br /> */<br /> _private void send_(_OutputStream netOut, Protocol scanDirProtocol_) _throws IOException _{<br /> _String protocol = scanDirProtocol.toString_()_;<br /> _//System.out.println("客户端发送:" + protocol);<br /> _netOut.write_(_protocol.getBytes_())_;<br /> _}
}
服务端
package com.itheima.service;
import com.itheima.Protocol;
import com.itheima.exception.BusinessException;
import com.itheima.util.IOUtil;
import java.io.*;
import java.net.Socket;
import java.util.ResourceBundle;
/
协议定义: 协议+数据
第一行是协议,第二行开始就是数据
/
_public class FileUpDownServiceImp implements Runnable, FileUpDownService {
_private final ResourceBundle bundle;<br /> private final File rootDir;<br /> private Socket socket;
public FileUpDownServiceImp_(_Socket socket_) {<br /> _this.socket = socket;<br /> _//1 读取配置文件中的端口,根目录等配置信息<br /> _bundle = ResourceBundle._getBundle(_"yunpan"_)_;
_//云盘的根目录<br /> _rootDir = new File_(_bundle.getString_(_"rootDir"_))_;<br /> if _(_rootDir.isFile_()) {<br /> _throw new BusinessException_(_"根目录路径与已存在文件冲突"_)_;<br /> _} _else if _(_!rootDir.exists_() _&& !rootDir.mkdirs_()) {<br /> _throw new BusinessException_(_"根目录创建失败,请检查配置路径是否正确"_)_;<br /> _}
}
_@Override<br /> public void run_() {<br /> _try _(_Socket socket = this.socket;_) {<br /> _InputStream netIn = socket.getInputStream_()_;<br /> OutputStream netOut = socket.getOutputStream_()_;<br /> _//读协议<br /> _final Protocol protocol = Protocol._parseProtocol(_netIn_)_;<br /> System._out_.println_(_"接收客户端数据:"+protocol_)_;<br /> _//识别客户端操作类型<br /> _String type = protocol.getType_()_;<br /> switch _(_type_) {<br /> _case Protocol.Type._SCAN_:_//客户端要浏览<br /> _scanDirectory_(_protocol, netIn, netOut_)_;<br /> break;
case Protocol.Type._DOWNLOAD_:_//客户端要下载<br /> _downloadFile_(_protocol, netIn, netOut_)_;<br /> break;
case Protocol.Type._UPLOAD_:_//客户端要上传<br /> _uploadFile_(_protocol, netIn, netOut_)_;<br /> break;<br /> _}
} _catch _(_IOException e_) {<br /> _e.printStackTrace_()_;<br /> _}<br /> }
/**<br /> * 浏览目录<br /> *<br /> * @param protocol<br /> * @param netIn<br /> * @param netOut<br /> * @throws IOException<br /> */<br /> _@Override<br /> public void scanDirectory_(_Protocol protocol, InputStream netIn, OutputStream netOut_) _throws IOException _{<br /> //创建协议对象,用来响应客户端<br /> _Protocol response = new Protocol_()_;<br /> _//获取客户端想要浏览的目录<br /> _String fileName = protocol.getFileName_()_;
_//root是提供给客户端的虚拟路径,转换为服务端的真实路径<br /> _String fileDir = fileName.replace_(_"root", rootDir.toString_())_;<br /> File dir = new File_(_fileDir_)_;
if _(_!dir.isDirectory_()) {<br /> //目录不存在,构建协议返回<br /> _response.setType_(_Protocol.Type._SCAN)_;<br /> response.setStatus_(_Protocol.Status._FAILED)_;_//失败<br /> _response.setMessage_(_"目录不存在,只能浏览当前子目录"_)_;<br /> send_(_netOut, response_)_;_//发送协议<br /> } _else _{<br /> //目录存在,构建协议返回<br /> _response.setType_(_Protocol.Type._SCAN)_;<br /> response.setStatus_(_Protocol.Status._OK)_;_//成功<br /> _response.setFileName_(_protocol.getFileName_())_;<br /> send_(_netOut, response_)_;_//发送协议
//把具体数据随后发送<br /> //把文件数据按照:"文件类型 名称" 发送,每一个子文件一行<br /> _OutputStreamWriter osw = new OutputStreamWriter_(_netOut_)_;<br /> File_[] _children = dir.listFiles_()_;
for _(_File child : children_) {<br /> _String fileType = child.isFile_() _? "文件" : "目录";<br /> osw.write_(_fileType + " " + child.getName_() _+ "\r\n"_)_;_//每个文件一行<br /> }<br /> //刷新数据<br /> _osw.flush_()_;
_}
}
/**<br /> * 文件上传功能<br /> *<br /> * @param protocol<br /> * @param netIn<br /> * @param netOut<br /> */<br /> _@Override<br /> public void uploadFile_(_Protocol protocol, InputStream netIn, OutputStream netOut_) _throws IOException _{<br /> //将虚拟路径变成服务端的真实路径<br /> _String fileName = protocol.getFileName_()_.replace_(_"root", rootDir.toString_())_;<br /> _//TODO 按照文档提供业务流程完服务端上传文件<br /> _if_(_new File_(_fileName_)_.exists_()){<br /> _protocol.setStatus_(_Protocol.Status._FAILED)_;<br /> protocol.setMessage_(_"文件已经存在!!"_)_;<br /> send_(_netOut,protocol_)_;<br /> _} _else _{<br /> _protocol.setStatus_(_Protocol.Status._OK)_;<br /> send_(_netOut,protocol_)_;<br /> try _(_FileOutputStream fos=new FileOutputStream_(_fileName_)){<br /> _IOUtil._copy(_netIn, fos_)_;
_}<br /> _protocol.setMessage_(_"恭喜文件上传成功了!!!"_)_;<br /> send_(_netOut,protocol_)_;<br /> _}
}
/**<br /> * 文件下载功能<br /> *<br /> * @param protocol<br /> * @param netIn<br /> * @param netOut<br /> * @throws IOException<br /> */<br /> _@Override<br /> public void downloadFile_(_Protocol protocol, InputStream netIn, OutputStream netOut_) _throws IOException _{<br /> //解析要下载的文件<br /> //将虚拟路径变成服务端的真实路径<br /> _String fileName = protocol.getFileName_()_.replace_(_"root", rootDir.toString_())_;<br /> _//TODO 按照文档提供业务流程完成服务端下载文件<br /> _if _(_new File_(_fileName_)_.isFile_()){<br /> _protocol.setStatus_(_Protocol.Status._OK)_;<br /> send_(_netOut,protocol_)_;<br /> try _(_FileInputStream fis=new FileInputStream_(_fileName_)){<br /> _IOUtil._copy(_fis,netOut_)_;<br /> socket.shutdownOutput_()_;<br /> System._out_.println_(_"发送完成了! 请签收!"_)_;<br /> _}<br /> }_else _{<br /> _protocol.setStatus_(_Protocol.Status._FAILED)_;<br /> protocol.setMessage_(_"文件不存在,请确定输入有效文件!"_)_;<br /> send_(_netOut,protocol_)_;
_}
}<br /> /**<br /> * 发送协议数据<br /> * @param netOut 网络输出流<br /> * @param response 协议<br /> * @throws IOException<br /> */<br /> _private void send_(_OutputStream netOut, Protocol response_) _throws IOException _{
//将要发送的协议变成字符串<br /> _String pro = response.toString_()_;<br /> netOut.write_(_pro.getBytes_())_;<br /> System._out_.println_(_"服务端响应数据:" + pro_)_;<br /> _}<br />}
_