简易文件上传下载器(socket+多线程+io)


这是一个简单的思路,代码给出具体思路

客户端上传下载具体实现



import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
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.net.Socket;
import java.util.Scanner;

/**
 * 客户端
 * 1连接服务端下载
 * 2从键盘输入服务端计算机中的文件路径,并请求下载
 * 3.如果服务端有文件就返回给客户端文件的名称和文件长度
 * 4.从网络上获取服务端下载的文件数据进入客户端的内存
 * 5,把内存的数据写到客户端的硬盘上
 * 1连接服务端上传
 * 2.从键盘输入正确的文件路径,文件存在
 * 3.获取文件名称和长度,并发给客户端
 * 3.从本地获取文件数据写入内存
 * 4.从内存写入到服务端
 * @author PC  
 *
 */
public class FileClient {

	public static void main(String[] args) throws IOException, Exception {
		Scanner input = new Scanner(System.in);
		//创建Socket对象(ip地址,端口号)
		Socket socket = new Socket("localhost",9992);
		//创建网络输入流
		DataInputStream dis = new DataInputStream(
				new BufferedInputStream(socket.getInputStream()));
		//创建网络输出流
		DataOutputStream dos = new DataOutputStream(
				new BufferedOutputStream(socket.getOutputStream()));
		FileClient client = new FileClient();
		System.out.println("请选择您需要的功能:1.上传  2.下载");
		int choise = input.nextInt();
		if(choise==1){
			dos.writeUTF("upload");
			client.upLoad(dis, dos, socket);//上传
		}else{
			dos.writeUTF("download");
			client.downLoad(dis, dos);
			
		}
		
		
		//关流
		dos.close();
		dis.close();
		//关闭套接字
		socket.close();
		

	}
	//下载 
	public void downLoad(DataInputStream dis,DataOutputStream dos) throws Exception{
		Scanner input = new Scanner(System.in);
		//提示信息.请输入服务器中需要下载的文件路径
		System.out.println("请输入服务器中要下载的文件路径:");
		String filePath = input.next();
		//创建 文件对象
		File file = new File(filePath);
		//网络输出流传送文件路径给服务器
		dos.writeUTF(filePath);
		//清除缓存,这时才是真正写出去了
		dos.flush();
		//读取服务器传送过来的文件的名称
		String fileName = dis.readUTF();
		//读取服务器传送过来的文件的长度
		String length = dis.readUTF();
		//提示信息:文件存在
		System.out.println("文件存在: fileName="+fileName+" length="+ length);
		System.out.println("文件将保存在d:/aa/bb/文件夹中.开始接收文件...");
		//构建本地输出流来写到硬盘,写到到d:/aa/bb/文件夹
		DataOutputStream local_dos = new DataOutputStream(
				new BufferedOutputStream(new FileOutputStream("d:/aa/bb/"+fileName)));
		//缓冲数组,减少和硬盘的交互次数
		byte[] buffer = new  byte[1024*1024];
		//循环写到硬盘
		while(true){
			//用来接收网络输入流写到数组数据的长度
			int len = -1;
			if(dis!= null ){
				//网络输入流写到数组数据的长度
				len = dis.read(buffer);
			}
			//判断是否读到末尾
			if(len == -1){
				break;
			}
			//写入到本地,写一次清除缓存一次
			local_dos.write(buffer, 0, len);
			local_dos.flush();
		}
		//关流
		local_dos.close();
		//提示信息:接收完毕
		System.out.println("文件下载完毕 !请在d:/aa/bb/文件夹中查看");
	}

	//上传
	public void upLoad(DataInputStream dis,DataOutputStream dos,Socket socket) throws Exception{
		Scanner input = new Scanner(System.in);
		//提示用户输入需要上传的文件的路径
		System.out.println("请输入客户端需要上传的文件的路径:");
		String filePath = input.next();
		//构架文件对象
		File file = new  File(filePath);
		//判断该路径下是否有对应文件
		for(int i=0;i<3;i++){
			//文件不存在
			if(!file.exists()){
				System.out.println("文件不存在,请确认文件路径是否正确,请重新输入:");
				if(i==3){
					dis.close();
					dos.close();
					socket.close();
					return;
				}		         	
			}else break;
		}
		//有对应文件, 获取文件名称                         
		String fileName = file.getName();
		//发送文件名称给服务器端
		dos.writeUTF(fileName);
		dos.flush();
		//获取文件长度
		long length  =  file.length();
		//发送文件长度给服务器端
		dos.writeUTF(length+"");
		dos.flush();

		System.out.println("文件将保存在服务器的d:/aa/文件夹中.准备开始上传文件...");
		//构建本地输入流,写到内存
		DataInputStream local_dis = new DataInputStream(
				new BufferedInputStream(new FileInputStream(filePath)));
		//构建缓冲
		byte[] buffer = new byte[1024*1024];

		while(true){
			int len =-1;
			//判断本地文件是否为空
			if(local_dis!=null){
				//将数组读取的长度赋给len
				len = local_dis.read(buffer);
			}
			if(len == -1){
				break;
			}
			//将网络输出流读到的数据,读一次写出给服务端一次
			dos.write(buffer,0,len);
			dos.flush();
		}
		//关流
		local_dis.close();
		System.out.println("文件上传完毕 !");
	}
}

服务端



import java.net.ServerSocket;
import java.net.Socket;
/**
 * 
 * 多线程,可以给多个客户端提供服务
 * @author PC
 *
 */
public class FileServer {

	public static void main(String[] args) throws Exception {
		//创建SeverSocket对象
		ServerSocket ss = new ServerSocket(9992);
		System.out.println("Server is starting");
		while(true){
			//开始监听9991端口,这里把服务器挂起
			Socket socket = ss.accept();
			//线程逻辑			
			ThreadHeadler headler= new ThreadHeadler(socket);//实现Runnable接口
			//创建线程
			Thread t1 =new Thread(headler);
			t1.start();
		}

	}

}

线程助手


import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;

public class ThreadHeadler implements Runnable {

	//任务线程需要的属性
    private Socket socket;
    //构造方法
    public  ThreadHeadler(Socket socket){
    	this.socket= socket;
    }
	@Override
	public void run() {
		try {
			//网络输入流
			DataInputStream dis = new  DataInputStream(
					new BufferedInputStream(socket.getInputStream()));
			//网络输出流
			DataOutputStream dos = new DataOutputStream(
					new BufferedOutputStream(socket.getOutputStream()));
			String choise = dis.readUTF();
			FileDownloadAndUpload load = new FileDownloadAndUpload();
			if("upload".equals(choise)){
				load.upload(socket, dos, dis);	
			}else if("download".equals(choise)){
				load.download(socket,dos,dis);
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
	
}

服务端上传下载具体实现



import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
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.net.InetAddress;
import java.net.Socket;
/**
 * 服务端:给客户端提供服务
 * 下载:
 * 1.接收客户端发送的文件路径,并判断文件是否存在
 * 2.如果文件存在,获取文件的名称和长度,并写到网络上
 * 3.从服务器硬盘读取文件内容到内存
 * 4,把内存的文件数据写到网络上
 * 上传:
 * 1.接收客户端传来的文件名称,查看是否已经存在,回馈信息
 * 2.获取文件长度 
 * 3.从网络流写入到内存,在从内存写出到硬盘
 * @author PC
 *
 */
public class FileDownloadAndUpload {
	
	public void upload(Socket socket,DataOutputStream dos,DataInputStream dis){
		try {
	    	//获取网络ip地址
	    	InetAddress ip = socket.getInetAddress();
	    	//网络输入输出流在外面
			//从客户端获取网络上传递过来的字符串
		    String fileName = dis.readUTF();
		    File file = new  File("d:/aa/"+fileName);//上传到d:/aa/
		    //判断文件是否存在
		    if(file.exists()){
		    	dos.writeUTF("您请求的文件已在服务器中,请换其他文件");
		    	dos.flush();
		    	return;
		    }
		    
		    //获取文件的长度
		    String length = dis.readUTF();
		    //准备开始接收文件
		    System.out.println(ip.getHostAddress()+" fileName="+fileName);//"  +length="+length
		    System.out.println(ip.getHostAddress()+" 开始接收文件..");
		    //从内存写到硬盘中(本地流)
		    //本地输出流
			DataOutputStream local_dos= new DataOutputStream(
					new BufferedOutputStream(new FileOutputStream(file)));
		    byte[] buffer = new byte[1024*1024];
		    
		    while(true){
		    	int len=-1;
		    	if(dis!=null){
		    		//网络流输入                                                                                                                                                                                                       
		    		len = dis.read(buffer);
		    	}
		    	if(len==-1){
		    		break;
		    	}
		    	//将缓存中的数据读出来,写到硬盘上
		    	local_dos.write(buffer, 0, len);
		    	local_dos.flush();//清除缓存,标记数据写出完毕,此时才将数据写到服务器硬盘上
		    }
		    //关流
			local_dos.close();
			dos.close();
			dis.close();
			//关闭套接字
			socket.close();
			System.out.println(ip.getHostAddress()+" fileName="+fileName+" 接收完毕!已保存到服务器d:/aa/中");
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	public void download(Socket socket,DataOutputStream dos,DataInputStream dis){
		try {
			//获取客户端的ip地址
			InetAddress ip = socket.getInetAddress();
			//网络输入输出流在外面
			//读取网络输入流传来的,服务器的文件路径
			String filePath = dis.readUTF();
			//构建文件对象
			File file = new File(filePath);
			//判断文件是否存在
			if (!file.exists()){
				//文件不存在,网络输出流:给出提示信息
				dos.writeUTF("文件不存在");
				dos.flush();//清除缓存,真正发出去
				return;//结束此次下载
			}
			//文件存在,就获取服务器中文件的名称
			String fileName = file.getName();
			//将名称给客户端发过去
			dos.writeUTF(fileName);
			dos.flush();
			//获取文件长度
			long length = file.length();
			//给客户端发过去
			dos.writeUTF(length+ "");
			dos.flush();
			//提示给哪个客户端,发送哪个文件
			System.out.println(ip.getHostAddress()+" fileName"+fileName+" length"+length);
			System.out.println("开始发送文件...");
			//构建本地输入流
			DataInputStream local_dis= new DataInputStream(
					    new BufferedInputStream(new FileInputStream(filePath)) );
			//缓冲数组
			byte[] buffer = new byte[1024*1024];
			//将文件写入内存
			while(true){
				int len = -1;
				//判断本地内部是否为空
				if(local_dis!=null){
					//将读取长度赋给len
					len = local_dis.read(buffer);
				}
				if(len == -1){
					break;
				}
				//网络输出流写出给客户端,写完一次清除一次缓存
				dos.write(buffer,0,len);
				dos.flush();
			}
			//关流
			local_dis.close();
			dos.close();
			dis.close();
			//关闭套接字
			socket.close();
			//提示信息传送完毕
			System.out.println("文件传送完毕"); 
					
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}	
		
	}
}

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值