演示以本机作为服务器,从本地任选一个文件传输到服务器(本机)。
一、客户端实现代码
public class Upload_Client {
public static void main(String[] args) throws IOException {
//1.创建客户端,并连接指定ip和端口号
Socket socket = new Socket("127.0.0.1",54321);
//2.获取和服务器端连接的IO流
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintStream ps = new PrintStream(socket.getOutputStream());
Scanner sc = new Scanner(System.in);
//3.输入上传文件名
String fileName;
//4.判断文件名的对错
while(true) {
System.out.println("请输入上传文件名:");
fileName = sc.nextLine();
File file = new File(fileName);
if (!file.exists()) {
System.out.println("路径不存在,请重新输入:");
} else if (file.isDirectory()){
System.out.println("此路径为文件夹路径,请重新输入:");
}else{
//5.将文件名传输给服务器,请勿将绝对路径传过去,否则会报“文件名、目录名或卷标语法不正确”错误,惨痛教训。
ps.println(file.getName());
break;
}
}
//6.等待返回结果
String result = br.readLine();
System.out.println(result);
//7.根据服务器返回结果判断是否需要继续上传
if("文件存在".equals(result)){
System.out.println("此文件已存在,不用上传");
socket.close();
return;
}
//8.文件不存在,上传文件,以字节流方式传输,字符流只能传输文本
FileInputStream fis = new FileInputStream(fileName);
byte[] arr = new byte[8912];
int len;
//9.将文件内容上传
while((len=fis.read(arr))!=-1){
ps.write(arr,0,len);
}
//10.关流
fis.close();
socket.close();
}
}
二、服务器端实现代码
public class Upload_Server {
public static void main(String[] args) throws IOException {
//创建服务器端
ServerSocket server = new ServerSocket(54321);
System.out.println("启动服务器,绑定54321端口");
//接收请求
while(true) {
//接收一个Socket
final Socket socket = server.accept();
new Thread(){
public void run()
{
try {
//和请求客户端建立IO流
InputStream is = socket.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
PrintStream ps = new PrintStream(socket.getOutputStream());
//获取上传文件名字
String fileName = br.readLine();
//建立文件夹
File dir = new File("upload");
dir.mkdir();
File file = new File(dir,fileName);
if(file.exists()){
ps.println("文件存在");
socket.close();
return;
}else{
ps.println("文件不存在");
}
//文件不存在,上传到本地
FileOutputStream fos = new FileOutputStream(file);
byte[] arr = new byte[8912];
int len;
//写入文件
while((len = is.read(arr))!=-1){
fos.write(arr,0,len);
}
//关流
fos.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}.start();
}
}
}
三、总结
1.从本地读取文件和向服务器传输文件的IO流一定要使用字节流,因为字符流只能传输文本文件。
2.客户端向服务器端传输文件名的时候只需要传名字,别传绝对路径,因为服务器没有此路径。
3.客户端和服务器端的输出流选PrintStream的优点在于可以传输字节流也可以传输字符流,并且可以自动刷新缓冲区。
4.如果选取的输出流没有自动刷新缓冲区的功能则每次传输时需要手动调用flush,否则对方接收不到数据。
觉得有用的小伙伴请点赞、评论或收藏一下多支持支持博主小弟,跪安~~