首页 > 其他分享 >实现客户端上传文件,服务器接收并永久化存储

实现客户端上传文件,服务器接收并永久化存储

时间:2023-03-15 21:46:12浏览次数:45  
标签:文件 bos accept 永久化 bw new 上传 客户端

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

相关文章