编写Java程序,实现客户端向服务端上传文件的功能

Java高级程序设计练习 专栏收录该内容
24 篇文章 4 订阅

查看本章节

查看作业目录


需求说明:

实现客户端向服务端上传文件的功能

当启动服务端后,运行客户端程序,系统提示客户在客户端输入上传文件的完整路径。当客户在客户端输入完成后,服务端实现文件上传

实现思路:

  1. 创建客户端类 FileClient 和服务端类 FileServer
  2. 在客户端类中定义uploadFile(Socket socket)方法,用于上传文件,使用BufferedOutputStream包装socket中输入流对象,使用new FileInputStream输入流对象读取本地文件,使用输出流将文件利用socket管道将数据循环发送至服务端
  3. 在客户端FileCliet类中,使用new Socket连接本地服务端和端口,调用uploadFile方法实现文件上传
  4. 在服务端类FileServer中,定义downFile()方法用于下载文件,该方法中使用BufferedInputStream包装socket中的输入流读取文件内容,并且使用FileOutputStream写到本地
  5. 分别运行服务端和客户端程序进行测试

实现代码:

服务端类 FileServer

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class FileServer {
	public ServerSocket server;
	public Socket socket;

	public void downloadFile() {
		BufferedInputStream bis = null;
		BufferedOutputStream bos = null;
		try {
			// 获取Socket管道字节输入流
			InputStream in = socket.getInputStream();
			// 将Socket管道字节输入流,进行缓冲包装提高读取的速度
			bis = new BufferedInputStream(in);
			// 读取客户端发送的文件名
			int length = bis.read();
			byte[] b = new byte[length];
			bis.read(b);
			// 获取需要下载的文件名
			String fileName = this.getFileName(new String(b));
			// 下载的文件对象
			FileOutputStream fos = new FileOutputStream("H://" + this.getFileName(fileName));
			// 对FileOutputStream进行缓冲包装,提高写入的速度
			bos = new BufferedOutputStream(fos);
			// 创建临时变量保存数据
			int data = 0;
			// 写入文件
			while ((data = bis.read()) != -1) {
				bos.write(data);
			}
			System.out.println("客户/" + socket.getInetAddress() + ":上传文件[" + fileName + "]成功");
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if (bis != null) {
					bis.close();
				}
				if (bos != null) {
					bos.close();
				}
				server.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	// 对文件的全路径进行拆分,返回文件名
	private String getFileName(String fn) {
		String[] files = fn.split("/");
		return files[files.length - 1];
	}

	// 创建服务器
	public void crateServer() {
		try {
			// 创建Socket实例
			server = new ServerSocket(8888);
			// 创建while循环接受多个客户端的连接
			while (true) {
				// 每一个连接的客户端都与服务器维护一条专属的Socket通信管道
				socket = server.accept();
				System.out.println("客户端已经连接");
				downloadFile();
				break;
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public static void main(String[] args) {
		new FileServer().crateServer();
	}
}

客户端类 FileClient

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;

public class FileClient {
	// 向服务器发送数据
	public void uploadFile(Socket socket) {
		BufferedReader reader = null;
		BufferedInputStream bis = null;
		BufferedOutputStream bos = null;
		try {
			System.out.println("请输入要上传文件的完成路径:");
			// 接收键盘输入
			InputStream in = System.in;
			// 获取Socket管道字节输出流
			OutputStream out = socket.getOutputStream();
			// 使用BufferedReader包装,便于按行读取客户端输入的数据
			reader = new BufferedReader(new InputStreamReader(in));
			// 客户端上传到服务端文件的名字
			String fileName = reader.readLine();
			// 创建字符文件输入流,用于读取上传文件中的数据
			FileInputStream fis = new FileInputStream(fileName);
			// 使用字节输入缓冲提高读取的速度
			bis = new BufferedInputStream(fis);
			// 获取Socket管道输出流,将从文件中的数据写入到管道中
			bos = new BufferedOutputStream(out);
			byte[] nbt = fileName.getBytes();
			// 将文件名字符串转换成字节数组的长度写入到Socket管道中
			bos.write(nbt.length);
			// 将字节数组写入到Socket管道中
			bos.write(nbt);
			// 定义临时变量,将从文件中读取到的数据写入到Socket管道中
			int data = 0;
			// 将文件中的数据写入到Socket管道中
			while ((data = bis.read()) != -1) {
				bos.write(data);
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			// 关闭io流和socket
			try {
				if (reader != null) {
					reader.close();
				}
				if (bis != null) {
					bis.close();
				}
				if (bos != null) {
					bos.close();
				}
				socket.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	public static void main(String[] args) {
		Socket client = null;
		try {
			// 创建客户端套接字对象
			client = new Socket("127.0.0.1", 8888);
			new FileClient().uploadFile(client);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

 

  • 1
    点赞
  • 0
    评论
  • 5
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 成长之路 设计师:Amelia_0503 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值