java实现服务端与客户端的文件上传和下载等功能。

[ 设计说明链接:]https://blog.csdn.net/qq_41813878/article/details/107240348

运行方式

项目目录:
在这里插入图片描述
先运行服务端TCPserver.java再运行客户端TCPclient.java(用户名:zs 密码:123)。
D:\client文件夹作为客户端文件系统(其中D:\client\download\中存放从服务端下载下来的文件; D:\client\中存放要说上传给服务器的文件),D:\server文件夹作为服务端文件系统(其中D:\server\upload\存放从客户端上传的文件)

TCPclient.java:

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;

/*

 实现步骤:
 1.创建一个本地字节输入流FileInputStream对象,构造方法中绑定要读取的数据源
 2.创建一个客户端Socket对象,构造方法中绑定服务器的IP地址和端口号
 3.使用Socket中的方法getOutputStream,获取网络字节输出流OutputStream对象
 4.使用本地字节输入流FileInputStream对象中的方法read,读取本地文件
 5.使用网络字节输出流OutputStream对象中的方法write,把读取到的文件上传到服务器
 6.使用Socket中的方法getInputStream,获取网络字节输入流InputStream对象
 7.使用网络字节输入流InputStream对象中的方法read读取服务回写的数据
 8.释放资源(FileInputStream,Socket)
 */
public class TCPClient {

	public static void main(String[] args) throws IOException {
		Scanner in = new Scanner(System.in);
		boolean flag = true;

		//
		// 用户登录
		login(in);

		while (flag) {
			System.out.println("请输入对应序号选择功能:");
			System.out.println("0、退出系统");
			System.out.println("1、从服务中获取文件的元数据列表");
			System.out.println("2、上传文件");
			System.out.println("3、下载文件");
			System.out.println("4、检查磁盘空间");
			String key = in.nextLine();

			Socket socket = new Socket("127.0.0.1", 8686);
			DataOutputStream dos = new DataOutputStream(
					socket.getOutputStream());
			dos.writeUTF(key);
			dos.close();
			socket.close();

			switch (key) {
			case "1":
				// 从服务中获取文件的元数据
				getDB();
				break;
			case "2":
				// 上传文件
				sendFile(in);
				break;
			case "3":
				// 下载文件
				receiveFile(in);
				break;
			case "4":
				space();
				break;
			case "0":
				flag = false;
				break;
			default:
				System.out.println("输入无效,请重新输入");
				break;
			}

		}

		// socket.close();
		in.close();
	}

	public static void sendFile(Scanner in) throws IOException {
		String fileName = null;
		String flag = "Y";
		FileInputStream fis = null;
		Socket socket = null;
		while (flag.equals("Y")) {
			System.out.println("请输入要上传的文件名:");
			fileName = in.nextLine();
			File file = new File("d:\\client\\" + fileName);
			// 1.创建一个本地字节输入流FileInputStream对象,构造方法中绑定要读取的数据源
			fis = new FileInputStream(file);
			// 2.创建一个客户端Socket对象,构造方法中绑定服务器的IP地址和端口号
			socket = new Socket("127.0.0.1", 8686);
			// 3.使用Socket中的方法getOutputStream,获取网络字节输出流OutputStream对象
			OutputStream os = socket.getOutputStream();

			DataOutputStream dos = new DataOutputStream(os);
			// 文件名、大小等属性
			dos.writeUTF(file.getName());
			dos.flush();
			// dos.writeLong(file.length());

			// 4.使用本地字节输入流FileInputStream对象中的方法read,读取本地文件
			int len = 0;
			byte[] bytes = new byte[1024];
			while ((len = fis.read(bytes)) != -1) {
				// 5.使用网络字节输出流OutputStream对象中的方法write,把读取到的文件上传到服务器
				os.write(bytes, 0, len);
			}
			
			/*
			 * 解决:上传完文件,给服务器写一个结束标记 void shutdownOutput() 禁用此套接字的输出流。 对于 TCP
			 * 套接字,任何以前写入的数据都将被发送,并且后跟 TCP 的正常连接终止序列。
			 */

			socket.shutdownOutput();
			


//		}
			System.out.println("上传成功");
			System.out.println("是否继续上传:Y/N");
			flag = in.nextLine();
			sendmess(flag);


			// 8.释放资源(FileInputStream,Socket)
//			is.close();
			dos.close();
			os.close();
			socket.close();
			fis.close();
		}

	}

	public static void receiveFile(Scanner in) throws IOException {
		String fileName = null;
		String flag = "Y";
		FileOutputStream fos = null;
		Socket socket = null;
		InputStream is = null;
		DataOutputStream dos = null;

		while (flag.equals("Y")) {
			System.out.println("请输入要下载的文件名:");
			fileName = in.nextLine();

			File dir = new File("d:\\client\\download");
			if (!dir.exists()) {
				dir.mkdirs();
			}

			File file = new File(dir + "\\" + fileName);
			if (!file.exists()) {
				file.createNewFile();
			}
			// 1.创建一个本地字节输入流FileInputStream对象,构造方法中绑定要读取的数据源
			fos = new FileOutputStream(file);
			// 2.创建一个客户端Socket对象,构造方法中绑定服务器的IP地址和端口号
			socket = new Socket("127.0.0.1", 8686);
			// 3.使用Socket中的方法getInputStream,获取网络字节输入流getInputStream对象
			is = socket.getInputStream();

			// 给服务器发送要下载的文件名
			dos = new DataOutputStream(socket.getOutputStream());
			dos.writeUTF(fileName);
			dos.flush();

			int len = 0;
			byte[] bytes = new byte[1024];
			while ((len = is.read(bytes)) != -1) {
				// 7.使用本地字节输入流FileIntputStream对象中的方法read,把读取到的文件保存到本地的硬盘上
				fos.write(bytes, 0, len);

			}

			System.out.println("下载成功!");
			System.out.println("是否继续下载:Y/N");
			flag = in.nextLine();
			sendmess(flag);

			// 8.释放资源(FileInputStream,Socket)
			dos.close();
			is.close();
			socket.close();
			fos.close();
		}
	}

	public static void login(Scanner in) throws IOException {
		int tag = 0;
		Socket socket = new Socket("127.0.0.1", 8686);
		DataOutputStream dos = null;
		DataInputStream dis = null;
		while (tag == 0) {
			System.out.println("请输入用户名:");

			String uname = in.nextLine();

			System.out.println("请输入密码:");
			String pwd = in.nextLine();

			dos = new DataOutputStream(socket.getOutputStream());

			dos.writeUTF(uname);
			dos.flush();

			dos.writeUTF(pwd);
			dos.flush();

			dis = new DataInputStream(socket.getInputStream());
			tag = dis.readInt();
			if (tag == 1) {
				System.out.println("登录成功!");
			} else {
				System.out.println("用户名或密码错误!请重新输入");
			}
		}
		dis.close();
		dos.close();
		socket.close();
	}

	public static void getDB() throws IOException {
		Socket socket = new Socket("127.0.0.1", 8686);
		DataInputStream dis = new DataInputStream(socket.getInputStream());
		int len = dis.readInt();

		for (int i = 0; i < len; i++) {
			System.out.println(dis.readUTF());
		}

		dis.close();
		socket.close();
	}

	public static void space() throws IOException {
		File file = new File("D:");
		long totalSpace = file.getTotalSpace();
		long freeSpace = file.getFreeSpace();
		System.out.println("本地:");
		System.out.println("总空间大小 : " + totalSpace / 1024 / 1024 / 1024 + "G");
		System.out.println("剩余空间大小 : " + freeSpace / 1024 / 1024 / 1024 + "G\n");

		Socket socket = new Socket("127.0.0.1", 8686);
		DataInputStream dis = new DataInputStream(socket.getInputStream());
		long StotalSpace = dis.readLong();
		long SfreeSpace =  dis.readLong();
		System.out.println("服务器:");
		System.out.println("总空间大小 : " + StotalSpace / 1024 / 1024 / 1024 + "G");
		System.out.println("剩余空间大小 : " + SfreeSpace / 1024 / 1024 / 1024 + "G\n");
		dis.close();
		socket.close();

	}
	
	public static void sendmess(String str) throws IOException{
		
		Socket socket = new Socket("127.0.0.1", 8686);
		DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
		
		dos.writeUTF(str);
		
		dos.close();
		socket.close();
	}

}

TCPserver.java:

import java.text.SimpleDateFormat;
import java.util.List;
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Date;
import java.util.Random;
import java.util.Scanner;
import java.io.FileWriter;

/*
 文件上传案例服务器端:读取客户端上传的文件,保存到服务器的硬盘,给客户端回写"上传成功"

 明确:
 数据源:客户端上传的文件
 目的地:服务器的硬盘 d:\\upload\\1.jpg

    实现步骤:
        1.创建一个服务器ServerSocket对象,和系统要指定的端口号
        2.使用ServerSocket对象中的方法accept,获取到请求的客户端Socket对象
        3.使用Socket对象中的方法getInputStream,获取到网络字节输入流InputStream对象
        4.判断d:\\upload文件夹是否存在,不存在则创建
        5.创建一个本地字节输出流FileOutputStream对象,构造方法中绑定要输出的目的地
        6.使用网络字节输入流InputStream对象中的方法read,读取客户端上传的文件
        7.使用本地字节输出流FileOutputStream对象中的方法write,把读取到的文件保存到服务器的硬盘上
        8.使用Socket对象中的方法getOutputStream,获取到网络字节输出流OutputStream对象
        9.使用网络字节输出流OutputStream对象中的方法write,给客户端回写"上传成功"
        10.释放资源(FileOutputStream,Socket,ServerSocket)
 */
public class TCPServer {

	private static List<String> DB = new ArrayList<String>();

	public static void main(String[] args) throws IOException {
		// 1.创建一个服务器ServerSocket对象,和系统要指定的端口号
		ServerSocket server = new ServerSocket(8686);
		//从DB.txt文件中那数据给DB
		initDB(DB);		

		String flag = "Y";
		while(true){
			//验证登录
			check(server);
			while(flag.equals("Y")){
				
				Socket socket = server.accept();
				DataInputStream dis = new DataInputStream(
						socket.getInputStream());
				String key = dis.readUTF();
				dis.close();
				socket.close();
				
				switch (key.charAt(0)) {
				case '1':
					//发送元数据给客户端
					sendDB(server);
					break;
				case '2':
					//上传文件
					takeFile(server);			
					break;
				case '3':
					//下载文件
					sendFile(server);
					break;
				case '4':
					//发送磁盘空间
					sendspace(server);
					break;
				case '0':
					flag = "N";
					break;
				default:
					break;
				}
			}

		
		}


		
		//把新的DB重新存入DB.txt
	//	saveDB(DB);
		
	//	socket.close();
	//	server.close();
	}
	
	public static void takeFile(ServerSocket server) throws IOException {
		// 2.使用ServerSocket对象中的方法accept,获取到请求的客户端Socket对象
		/*
		 * 让服务器一直处于监听状态(死循环accept方法) 有一个客户端上传文件,就保存一个文件
		 */
		String flag = "Y";
		while (flag.equals("Y")) {
			Socket socket = server.accept();
			/*
			 * 使用多线程技术,提高程序的效率 有一个客户端上传文件,就开启一个线程,完成文件的上传(取消使用)
			 */
			
				// 完成文件的上传
		
			try {
				// 3.使用Socket对象中的方法getInputStream,获取到网络字节输入流InputStream对象
				InputStream is = socket.getInputStream();

				DataInputStream dis = new DataInputStream(
						socket.getInputStream());
				// 文件名(和长度)
				String fileName = dis.readUTF();
//						long fileLength = dis.readLong();

				// 4.判断d:\\upload文件夹是否存在,不存在则创建
				File file = new File("d:\\server\\upload");
				if (!file.exists()) {
					file.mkdirs();
				}

				// 5.创建一个本地字节输出流FileOutputStream对象,构造方法中绑定要输出的目的地
				FileOutputStream fos = new FileOutputStream(file + "\\" + fileName);
				// 6.使用网络字节输入流InputStream对象中的方法read,读取客户端上传的文件

				int len = 0;
//				StringBuilder sb = new StringBuilder();
				byte[] bytes = new byte[1024];
				while ((len = is.read(bytes)) != -1) {		
          
					// 7.使用本地字节输出流FileOutputStream对象中的方法write,把读取到的文件保存到服务器的硬盘上
					fos.write(bytes, 0, len);


				// 文件元数据
				File f = new File(file + "\\" + fileName);

				Date dd = new Date();
				// 格式化
				SimpleDateFormat sim = new SimpleDateFormat(
						"yyyy-MM-dd HH:mm:ss");
				String Udate = sim.format(dd);

				String size = "" + f.length() + "bytes";

				DB.add(fileName + "\t" + size + "\t" + Udate);

				flag = getmess(server);
//				socket1.close();

				
				//更新数据库文件
				saveDB(DB);
				// 10.释放资源(FileOutputStream,Socket,ServerSocket)
				fos.close();
				dis.close();
				is.close();
//				socket.close();

//				System.out.println(DB);
			} catch (IOException e) {
						System.out.println(e);
					}
					
		}

	}
	
	
	public static void sendFile(ServerSocket server) throws IOException {
    	
		String flag = "Y";
    	while(flag.equals("Y")){
    		/*
    		 * 使用多线程技术,提高程序的效率 有一个客户端下载文件,就开启一个线程,完成文件的下载(取消使用)
    		 */
			Socket socket = server.accept();
    			  try{
    				//读取下载的文件名
					DataInputStream dis = new DataInputStream(
							socket.getInputStream());
					String fileName = dis.readUTF();
					
    		    	File file = new File("d:\\server\\upload\\"+fileName);
    		        //1.创建一个本地字节输入流FileInputStream对象,构造方法中绑定要读取的数据源
    		    	FileInputStream fis = new FileInputStream(file);				
    		        //3.使用Socket中的方法getOutputStream,获取网络字节输出流OutputStream对象
    		        OutputStream os = socket.getOutputStream(); 		      
    		        DataOutputStream dos = new DataOutputStream(os);

    				
    		        //4.使用本地字节输入流FileInputStream对象中的方法read,读取本地文件
    		        int len = 0;
    		        byte[] bytes = new byte[1024];
    		        while((len = fis.read(bytes))!=-1){
    		            //5.使用网络字节输出流OutputStream对象中的方法write,把读取到的文件发送给客户端
    		            os.write(bytes,0,len);
    		        }
    		        /*
    		            解决:上传完文件,给服务器写一个结束标记
    		            void shutdownOutput() 禁用此套接字的输出流。
    		            对于 TCP 套接字,任何以前写入的数据都将被发送,并且后跟 TCP 的正常连接终止序列。
    		         */
    		        
    		        socket.shutdownOutput();
    		        
    		        flag = getmess(server);

    		        

    		        //8.释放资源(FileInputStream,Socket)

    		        dos.close();
    		        os.close();
    		        fis.close();
    		        dis.close();
//   		        socket.close();
    		        
    			  }catch (Exception e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}

	    }

	}
	
	public static void check(ServerSocket server) throws IOException{
		Socket socket = server.accept();
		DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
		
		DataInputStream dis = new DataInputStream(
				socket.getInputStream());
		String uname = null;
		String pwd = null;
		int tag = 0;
		while(tag==0){
			 uname = dis.readUTF();
			 pwd = dis.readUTF();
			if(uname.equals("zs")&&pwd.equals("123")){
				dos.writeInt(1);
				tag = 1;
			}else{
				dos.writeInt(0);
				tag = 0;
			}
		}
		
		dis.close();
		dos.close();
		socket.close();
	}
	
	public static void sendDB(ServerSocket server) throws IOException{
		Socket socket = server.accept();
		DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
		int len = DB.size();
		dos.writeInt(len);
		
		for(int i=0;i<len;i++){
			dos.writeUTF(DB.get(i));
		}
		dos.close();
		socket.close();
	}
	
	public static void saveDB(List<String> DB ) throws IOException {
		FileWriter fw = new FileWriter("D:\\server\\DB\\DB.txt");
		int len = DB.size();
		for(int i=0;i<len;i++){
			fw.write(DB.get(i));
			fw.write("\r\n");
		}
		 fw.close();
	}
	
	public static void initDB(List<String> DB ) throws IOException{
		 File file = new File("D:\\server\\DB\\DB.txt");
		 if(file.length()==0){
			 return;
		 }
		 FileInputStream fis = new FileInputStream("D:\\server\\DB\\DB.txt");// FileInputStream
		   // 从文件系统中的某个文件中获取字节
		 InputStreamReader  isr = new InputStreamReader(fis);// InputStreamReader 是字节流通向字符流的桥梁,
		 BufferedReader  br = new BufferedReader(isr);// 从字符输入流中读取文件中的内容,封装了一个new InputStreamReader的对象
		 String str = null;
		   while ((str = br.readLine()) != null) {
		    DB.add(str);
	//	    System.out.println(str);
		   }
		   
		  br.close();

	}
	
	public static void sendspace(ServerSocket server) throws IOException{
		 File file = new File("D:");
        long totalSpace = file.getTotalSpace();
        long freeSpace = file.getFreeSpace();
        
		Socket socket = server.accept();
		DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
		dos.writeLong(totalSpace);
		dos.writeLong(freeSpace);
		
		dos.close();
		socket.close(); 
	}
	
	public static String getmess(ServerSocket server) throws IOException{
		Socket socket = server.accept();
		DataInputStream dis = new DataInputStream(socket.getInputStream());
		
		String mess = dis.readUTF();
		
		dis.close();
		socket.close();
		return mess;
	}
}





  • 2
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实现Java客户服务MP3文件,你可以使用以下步骤: 1. 在Java客户,使用`FileInputStream`读取要上的MP3文件。例如: ```java File file = new File("path/to/your/file.mp3"); byte[] buffer = new byte[(int) file.length()]; try (FileInputStream fis = new FileInputStream(file)) { fis.read(buffer); } catch (IOException e) { e.printStackTrace(); } ``` 2. 使用Java的网络库(如`java.net.HttpURLConnection`)建立与服务的HTTP连接,并设置请求方法为POST。例如: ```java URL url = new URL("http://your-server-url.com/upload"); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("POST"); connection.setDoOutput(true); ``` 3. 设置HTTP请求的内容类型为`multipart/form-data`,以便能够上文件。例如: ```java connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW"); ``` 4. 将MP3文件的内容写入HTTP请求的输出流中。例如: ```java try (DataOutputStream outputStream = new DataOutputStream(connection.getOutputStream())) { outputStream.write(buffer); } catch (IOException e) { e.printStackTrace(); } ``` 5. 发送HTTP请求并获取响应。例如: ```java int responseCode = connection.getResponseCode(); if (responseCode == HttpURLConnection.HTTP_OK) { // 上成功 // 处理服务返回的响应数据 } else { // 上失败 // 处理错误情况 } ``` 这样,你就可以通过Java客户将MP3文件服务了。请注意,这只是一个简单的示例,你可能需要根据自己的需求进行适当的修改和错误处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值