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

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

需求说明:


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

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


43.png

44.png


实现思路:


创建客户端类 FileClient 和服务端类 FileServer

在客户端类中定义uploadFile(Socket socket)方法,用于上传文件,使用BufferedOutputStream包装socket中输入流对象,使用new FileInputStream输入流对象读取本地文件,使用输出流将文件利用socket管道将数据循环发送至服务端

在客户端FileCliet类中,使用new Socket连接本地服务端和端口,调用uploadFile方法实现文件上传

在服务端类FileServer中,定义downFile()方法用于下载文件,该方法中使用BufferedInputStream包装socket中的输入流读取文件内容,并且使用FileOutputStream写到本地

分别运行服务端和客户端程序进行测试


实现代码:


服务端类 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();
    }
  }
}
相关文章
|
25天前
|
安全 Java 测试技术
🎉Java零基础:全面解析枚举的强大功能
【10月更文挑战第19天】本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
103 60
|
13天前
|
Java
Java 8 引入的 Streams 功能强大,提供了一种简洁高效的处理数据集合的方式
Java 8 引入的 Streams 功能强大,提供了一种简洁高效的处理数据集合的方式。本文介绍了 Streams 的基本概念和使用方法,包括创建 Streams、中间操作和终端操作,并通过多个案例详细解析了过滤、映射、归并、排序、分组和并行处理等操作,帮助读者更好地理解和掌握这一重要特性。
23 2
|
23天前
|
存储 Java API
Java实现导出多个excel表打包到zip文件中,供客户端另存为窗口下载
Java实现导出多个excel表打包到zip文件中,供客户端另存为窗口下载
31 4
|
29天前
|
JSON Java 开发工具
Java服务端集成Google FCM推送的注意事项和实际经验
本文分享了作者在公司APP海外发布过程中,选择Google FCM进行消息推送的集成经验。文章详细解析了Java集成FCM推送的多种实现方式,包括HTTP请求和SDK集成,并指出了通知栏消息和透传消息的区别与应用场景。同时,作者还探讨了Firebase项目的创建、配置和服务端集成的注意事项,帮助读者解决文档混乱和选择困难的问题。
53 1
|
1月前
|
Java Maven 数据安全/隐私保护
如何实现Java打包程序的加密代码混淆,避免被反编译?
【10月更文挑战第15天】如何实现Java打包程序的加密代码混淆,避免被反编译?
51 2
|
1月前
|
Java 程序员
在Java编程中,关键字不仅是简单的词汇,更是赋予代码强大功能的“魔法咒语”。
【10月更文挑战第13天】在Java编程中,关键字不仅是简单的词汇,更是赋予代码强大功能的“魔法咒语”。本文介绍了Java关键字的基本概念及其重要性,并通过定义类和对象、控制流程、访问修饰符等示例,展示了关键字的实际应用。掌握这些关键字,是成为优秀Java程序员的基础。
24 3
|
1月前
|
Java 数据安全/隐私保护
Java ffmpeg 实现视频加文字/图片水印功能
【10月更文挑战第22天】在 Java 中使用 FFmpeg 实现视频加文字或图片水印功能,需先安装 FFmpeg 并添加依赖(如 JavaCV)。通过构建 FFmpeg 命令行参数,使用 `drawtext` 滤镜添加文字水印,或使用 `overlay` 滤镜添加图片水印。示例代码展示了如何使用 JavaCV 实现文字水印。
|
1月前
|
安全 Java Linux
java程序设置开机自启
java程序设置开机自启
101 1
|
1月前
|
Java
让星星⭐月亮告诉你,jdk1.8 Java函数式编程示例:Lambda函数/方法引用/4种内建函数式接口(功能性-/消费型/供给型/断言型)
本示例展示了Java中函数式接口的使用,包括自定义和内置的函数式接口。通过方法引用,实现对字符串操作如转换大写、数值转换等,并演示了Function、Consumer、Supplier及Predicate四种主要内置函数式接口的应用。
27 1
|
1月前
|
运维 Java Linux
【运维基础知识】Linux服务器下手写启停Java程序脚本start.sh stop.sh及详细说明
### 启动Java程序脚本 `start.sh` 此脚本用于启动一个Java程序,设置JVM字符集为GBK,最大堆内存为3000M,并将程序的日志输出到`output.log`文件中,同时在后台运行。 ### 停止Java程序脚本 `stop.sh` 此脚本用于停止指定名称的服务(如`QuoteServer`),通过查找并终止该服务的Java进程,输出操作结果以确认是否成功。
40 1
下一篇
无影云桌面