public class ClientDemo { public static void main(String[] args) throws IOException { // 客户端将本地文件上传到服务器,并接收服务器的反馈 Socket sc = new Socket("127.0.0.1", 9999); // 本地的字节缓冲输入流,获取本地文件 BufferedInputStream bis = new BufferedInputStream(new FileInputStream("a.jpg")); // 服务器的流,写到网络的服务器中 OutputStream outputStream = sc.getOutputStream(); BufferedOutputStream bos = new BufferedOutputStream(outputStream); int b; while ((b = bis.read()) != -1) { // 通过网络中的流写到服务器中 bos.write(b); } // 给服务器一个结束标记,告诉服务器文件传输结束 sc.shutdownOutput(); // 接收服务器返回的数据 BufferedReader br = new BufferedReader(new InputStreamReader(sc.getInputStream())); String line; while ((line = br.readLine()) != null) { System.out.println(line); } // 关闭客户端和流,释放资源 bis.close(); sc.close(); } }
public class serviceDemo { public static void main(String[] args) throws IOException { // 服务器接收客户端发送的文件,并将文件永久化保存到本地 ServerSocket ss = new ServerSocket(9999); // 方式1:使用while (true),客户端可以多次上传文件,但是无法同时出来多个客户端请求, // 解决方案:使用多线程 // method1(ss); // 方式2:使用线程 弊端:每来一个请求就开辟一条线程,太浪费资源,解决方案:此时创建线程池 // while (true) { // // 当监听到一个客户端请求,就开一条线程去执行请求 // Socket accept = ss.accept(); // RunnableSochet rs = new RunnableSochet(accept); // new Thread(rs).start(); // } // 方式3:创建线程池 ThreadPoolExecutor pool = new ThreadPoolExecutor(2, 5, 60, TimeUnit.SECONDS, new ArrayBlockingQueue<>(5), Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy()); while (true) { // 当监听到一个客户端请求,就开一条线程去执行请求 Socket accept = ss.accept(); RunnableSochet rs = new RunnableSochet(accept); pool.submit(rs); } // ss.close(); } private static void method1(ServerSocket ss) throws IOException { while (true) { // 等待客户端连接 Socket accept = ss.accept(); // 网络的流,将字节流转换为字节缓冲流,使用缓冲流读取客户端上传的文件 BufferedInputStream bis = new BufferedInputStream(accept.getInputStream()); // 本地的流,使用缓冲流将读取到的文件永久化保存到本地 // 使用UUID作为文件名,防止因为使用上传的文件名重复而导致保存的文件被重名的覆盖 UUID uuid = UUID.randomUUID(); String copy = uuid.toString().replace("-", "") + ".jpg"; BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(copy)); int b; while ((b = bis.read()) != -1) { bos.write(b); } // 文件保存后给客户端反馈,将字节流转换为字符流,解决中文乱码问题 BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(accept.getOutputStream())); bw.write("文件上传成功!"); bw.newLine(); bw.flush(); // 只需要关闭本地的流和socket,网络的流会随着socket的关闭自动消失 bos.close(); accept.close(); } } }
public class RunnableSochet implements Runnable { private Socket acceptSocket; public RunnableSochet(Socket socket) { this.acceptSocket = socket; } // 接收文件复制文件的代码写到线程中 @Override public void run() { BufferedOutputStream bos = null; try { // 网络的流,将字节流转换为字节缓冲流,使用缓冲流读取客户端上传的文件 BufferedInputStream bis = new BufferedInputStream(acceptSocket.getInputStream()); // 本地的流,使用缓冲流将读取到的文件永久化保存到本地 // 使用UUID作为文件名,防止因为使用上传的文件名重复而导致保存的文件被重名的覆盖 UUID uuid = UUID.randomUUID(); String copy = uuid.toString().replace("-", "") + ".jpg"; bos = new BufferedOutputStream(new FileOutputStream(copy)); int b; while ((b = bis.read()) != -1) { bos.write(b); } // 文件保存后给客户端反馈,将字节流转换为字符流,解决中文乱码问题 BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(acceptSocket.getOutputStream())); bw.write("文件上传成功!"); bw.newLine(); bw.flush(); } catch (IOException e) { e.printStackTrace(); } finally { // 只需要关闭本地的流和socket,网络的流会随着socket的关闭自动消失 if (bos != null) { try { bos.close(); } catch (IOException e) { e.printStackTrace(); } } if (acceptSocket != null) { try { acceptSocket.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
标签:文件,bos,accept,永久化,bw,new,上传,客户端 From: https://www.cnblogs.com/weiduaini/p/17220179.html