【JavaSe】网络编程篇(三) 使用网络编程完成文件上传

JavaSe·网络编程篇(三) 使用网络编程完成文件上传


1. 文件上传分析图解

在这里插入图片描述

  1. 【客户端】输入流,从硬盘读取文件数据到程序中。
  2. 【客户端】输出流,写出文件数据到服务端。
  3. 【服务端】输入流,读取文件数据到服务端程序。
  4. 【服务端】输出流,写出文件数据到服务器硬盘中。

2. 基本实现文件上传

服务端实现:

public class FileUpload_Server {
	public static void main(String[] args) throws IOException {
		System.out.println("服务器 启动..... ");
		// 1. 创建服务端ServerSocket
		ServerSocket serverSocket = new ServerSocket(6666);
		// 2. 建立连接
		Socket accept = serverSocket.accept();
		// 3. 创建流对象
		// 3.1 获取输入流,读取文件数据
		BufferedInputStream bis = new BufferedInputStream(accept.getInputStream());
		// 3.2 创建输出流,保存到本地 .
		BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("copy.jpg"));
		// 4. 读写数据
		byte[] b = new byte[1024 * 8];
		int len;
		while ((len = bis.read(b)) !=1) {
		bos.write(b, 0, len);
		}
		//5. 关闭 资源
		bos.close();
		bis.close();
		accept.close();
		System.out.println("文件上传已保存");
	}
}

客户端实现:

public class FileUPload_Client {
	public static void main(String[] args) throws IOException {
		// 1.创建流对象
		// 1.1 创建输入流,读取本地文件
		BufferedInputStream bis = new BufferedInputStream(new FileInputStream("test.jpg"));
		// 1.2 创建输出流,写到服务端
		Socket socket = new Socket("localhost", 6666);
		BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream());
		//2.写出数据.
		byte[] b = new byte[1024 * 8 ];
		int len ;
		while (( len = bis.read(b))!=1) {
		bos.write(b, 0, len);
		bos.flush();
		}
		System.out.println("文件发送完毕");
		// 3.释放资源
		bos.close();
		socket.close();
		bis.close();
		System.out.println("文件上传完毕 ");
	}
}

3. 文件上传优化分析

3.1 文件名称写死的问题

服务端,保存文件的名称如果写死,那么最终导致服务器硬盘,只会保留一个文件,建议使用系统时间优化,保证文件名称唯一

FileOutputStream fis = new FileOutputStream(System.currentTimeMillis()+".jpg") // 文件名称
BufferedOutputStream bos = new BufferedOutputStream(fis);

3.2 循环接收的问题

服务端,指保存一个文件就关闭了,之后的用户无法再上传,这是不符合实际的,使用循环改进,可以不断的接收不同用户的文件

// 每次接收新的连接,创建一个Socket
whiletrue{
	Socket accept = serverSocket.accept();
	......
}

3.3 效率问题

服务端,在接收大文件时,可能耗费几秒钟的时间,此时不能接收其他用户上传,所以,使用多线程技术优化

whiletrue{
	Socket accept = serverSocket.accept();
		// accept 交给子线程处理.
		new Thread(()> {
		......
		InputStream bis = accept.getInputStream();
		......
	}).start();
}

3.4 优化实现

public class FileUpload_Server {
	public static void main(String[] args) throws IOException {
		System.out.println("服务器 启动..... ");
		// 1. 创建服务端ServerSocket
		ServerSocket serverSocket = new ServerSocket(6666);
		// 2. 循环接收,建立连接
		while (true) {
			Socket accept = serverSocket.accept();
			/*
			3. socket对象交给子线程处理,进行读写操作
				Runnable接口中,只有一个run方法,使用lambda表达式简化格式
			*/
			new Thread(()> {
				try (
					//3.1 获取输入流对象
					BufferedInputStream bis = new BufferedInputStream(accept.getInputStream());
					//3.2 创建输出流对象, 保存到本地 .
					FileOutputStream fis = new FileOutputStream(System.currentTimeMillis() + ".jpg");
					BufferedOutputStream bos = new BufferedOutputStream(fis);) {
					// 3.3 读写数据
					byte[] b = new byte[1024 * 8];
					int len;
					while ((len = bis.read(b)) !=1) {
						bos.write(b, 0, len);
					}
					//4. 关闭 资源
					bos.close();
					bis.close();
					accept.close();
					System.out.println("文件上传已保存");
				} catch (IOException e) {
					e.printStackTrace();
				}
			}).start();
		}
	}
}

4. 信息回写分析图解

在这里插入图片描述
前四步与基本文件上传一致.
5. 【服务端】获取输出流,回写数据。
6. 【客户端】获取输入流,解析回写数据。

5. 回写实现

服务端:

public class FileUpload_Server {
	public static void main(String[] args) throws IOException {
		System.out.println("服务器 启动..... ");
		// 1. 创建服务端ServerSocket
		ServerSocket serverSocket = new ServerSocket(6666);
		// 2. 循环接收,建立连接
		while (true) {
			Socket accept = serverSocket.accept();
			/*
			3. socket对象交给子线程处理,进行读写操作
			Runnable接口中,只有一个run方法,使用lambda表达式简化格式
			*/
			new Thread(()> {
			try (
				//3.1 获取输入流对象
				BufferedInputStream bis = new BufferedInputStream(accept.getInputStream());
				//3.2 创建输出流对象, 保存到本地 .
				FileOutputStream fis = new FileOutputStream(System.currentTimeMillis() + ".jpg");
				BufferedOutputStream bos = new BufferedOutputStream(fis);
				) {
				// 3.3 读写数据
				byte[] b = new byte[1024 * 8];
				int len;
				while ((len = bis.read(b)) !=1) {
				bos.write(b, 0, len);
				}
				// 4.=======信息回写===========================
				System.out.println("back ........");
				OutputStream out = accept.getOutputStream();
				out.write("上传成功".getBytes());
				out.close();
				//================================
				//5. 关闭 资源
				bos.close();
				bis.close();
				accept.close();
				System.out.println("文件上传已保存");
			} catch (IOException e) {
				e.printStackTrace();
			}
			}).start();
		}
	}
}

客户端:

public class FileUpload_Client {
	public static void main(String[] args) throws IOException {
		// 1.创建流对象
		// 1.1 创建输入流,读取本地文件
		BufferedInputStream bis = new BufferedInputStream(new FileInputStream("test.jpg"));
		// 1.2 创建输出流,写到服务端
		Socket socket = new Socket("localhost", 6666);
		BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream());
		//2.写出数据.
		byte[] b = new byte[1024 * 8 ];
		int len ;
		while (( len = bis.read(b))!=1) {
			bos.write(b, 0, len);
		}
		// 关闭输出流,通知服务端,写出数据完毕
		socket.shutdownOutput();
		System.out.println("文件发送完毕");
		// 3. =====解析回写============
		InputStream in = socket.getInputStream();
		byte[] back = new byte[20];
		in.read(back);
		System.out.println(new String(back));
		in.close();
		// ============================
		// 4.释放资源
		socket.close();
		bis.close();
	}
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值