关于java socket 传输文件时遇到的问题

在使用Java开发Android共享平台时,通过Socket进行文件传输遇到问题,即接收的文件总是比源文件大一个字节。问题源于DataOutputStream的reset()方法,去除该方法后问题解决,强调开发中查阅文档的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

       这段时间在使用java开发一个andriod的共享平台,本人大三水平,大二使用c#开发,前段时间想做一个比赛才开始使用java,所以水平不高,但其中遇到一些值得借鉴的问题,问题先不说,解决这些问题的过程中深感开发这东西看文档实在是太重要了.很多问题遇到的时候非常奇怪但是看完文档后就豁然开朗了.

先说这个论坛上遇到的问题:"点击打开链接",这也是我发的,被大神用reset()方法解决了,但是使用reset()方法有个问题,大家看了我下面为了完成一个文件传输所写的代码:


Server:

public class s{
	public static void main(String[] args){
		try {
			ServerSocket s=new ServerSocket(9528);
            Socket c=s.accept();
            new FileBroadcast(c,"Test.txt","C:\\Users\\cfdt\\Desktop\\tmp\\Test.txt");
            System.in.read();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

public class FileBroadcast extends Thread{
	
	private Socket c;
	private String FileName;
	private String FilePath;
	
	FileBroadcast(Socket c,String FileName,String FilePath){
		this.c=c;
		this.FilePath=FilePath;
		this.FileName=FileName;
		this.start();
	}
	
	public void run(){
		DataOutputStream FileTransferToClientStream;
		ObjectOutputStream FileTransferToClient;
		byte[] buf = new byte[4096];
		File fi = new File(FilePath);
		DataInputStream fis=null;
		try {
			fis = new DataInputStream(new BufferedInputStream(new FileInputStream(FilePath)));
		} catch (FileNotFoundException e1) {
			// TODO Auto-generated catch block
			//Log("At FileBroadcast.java run(); FileNotFoundException; "+e1);
			e1.printStackTrace();
		}
		
		//DataInputStream FileTransferFromServerStream;
			try {
				FileTransferToClientStream=new DataOutputStream(c.getOutputStream());
				//FileTransferFromServerStream=new DataInputStream(clientList.get(i).FileTransfer.getInputStream());
				FileTransferToClient=new ObjectOutputStream(c.getOutputStream());
				//send name length
				Message m=new Message("ServerFileBroadcast","recFile",FileName+"##"+fi.length());
				FileTransferToClient.writeObject(m);
				//FileTransferToClient.reset();
				FileTransferToClient.flush();
				//send data
				long FileLength=fi.length();
				System.out.println("FileLength: "+FileLength);
				int curLength=0;
				System.out.println("curLength: "+curLength);
				while (curLength<FileLength) {
                    int read = 0;
                    if (fis != null) {
                        read = fis.read(buf);
                    }
                    System.out.println("read: "+read);
                    if (read != -1) {
                    	curLength+=read;
                    }else{
                    	break;
                    }
                    System.out.println("curLength: "+curLength);
                    FileTransferToClientStream.write(buf, 0, read);
                    //Thread.sleep(100);
                    FileTransferToClientStream.flush();
                }
				System.out.println("File Length"+fi.length());
				System.out.println("Server end");
				fis.close();
				//Log("At FileBroadcast.java run(); Send file over; ");
				
			} catch (IOException e) {
				// TODO Auto-generated catch block
				//Log("At FileBroadcast.java run(); IOException; "+e);
				e.printStackTrace();
			} 	
		}
	
	
}

Client:

public class c{
	public static void main(String[] args) throws UnknownHostException, IOException, ClassNotFoundException{
		Socket c=new Socket("127.0.0.1",9528);
		ObjectInputStream Fs=new ObjectInputStream(c.getInputStream());
		DataInputStream Dis=new DataInputStream(c.getInputStream());		
		ReceiveFileListener aa=new ReceiveFileListener(Fs,Dis);
		Thread t=new Thread(aa);
		t.start();
	}
}

使用的类:

public class ReceiveFileListener implements Runnable{
	private DataInputStream FileTransferFromServerStream;
	private ObjectInputStream FileTransferFromServer;
	
	ReceiveFileListener(ObjectInputStream FileTransferFromServer
			,DataInputStream FileTransferFromServerStream){
		this.FileTransferFromServer=FileTransferFromServer;
		this.FileTransferFromServerStream=FileTransferFromServerStream;
	}

	public void run() {
		// TODO Auto-generated method stub
		Message m;
		String FileName="d:\\data\\";
		long len=0;
		int bufferSize = 4096;
		int passedlen = 0;
		byte[] buf = new byte[bufferSize];
		DataOutputStream fileOut;
		boolean flag;
		while(true){
			try {
				m=(Message)FileTransferFromServer.readObject();
				flag=true;
				if(m.getCmd().equals("recFile")){
					String[] tmp=m.getMSG().split("##"); 
					FileName+=tmp[0];
					System.out.println(FileName);
					 len=Long.parseLong(tmp[1]);
					 System.out.println("len: "+len);
					 flag=true;
				}else{
					flag=false;
				}
				if(flag){
					fileOut = new DataOutputStream(new BufferedOutputStream(new BufferedOutputStream(new FileOutputStream(FileName))));
					int curLength=0;
					System.out.println("len: "+len);
					System.out.println("curLength: "+curLength);
					while (curLength<len) {
		                int read = 0;
		                if (FileTransferFromServerStream != null) {
		                    read = FileTransferFromServerStream.read(buf);
		                    System.out.println("read: "+read);
		                }
		                
		                if (read != -1) {
		                	curLength+=read;
		                }
		                if(read==-1)
		                {
		                	break;
		                }
		                System.out.println("curLength: "+curLength);
		                fileOut.write(buf, 0, read);
		                fileOut.flush();
		                Arrays.fill(buf,(byte)0);
		            }
					System.out.println("len"+len);
					fileOut.close();
				}
			} catch (ClassNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				//Log("At ClientSocketList.java run(); IOException; "+e);
				e.printStackTrace();
			}
		}
	}
}

上面的代码运行后的结果:


这是server的:


下面是client的:



这是最为诡异的地方,你会发现传输的文件总是比源文件大一个字节,这就是reset()方法干得好事.....


去掉就行了

DataOutputStream 类有个方法叫做reset(),这个方法是用来

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值