在Java Socket中恢复文件上传

时间:2019-01-04 12:47:20

标签: java sockets dataoutputstream

package experiments; 

import java.io.*;

 import java.net.Socket; 
/** * * @author User */ 

/*THE CLIENT*/ public class UploadManager { 

public static void setup(String address, int port,String path){ 

try( Socket s = new Socket(address,port); OutputStream out = s.getOutputStream(); InputStream in = s.getInputStream(); DataOutputStream dos = new DataOutputStream(out); 
DataInputStream dis = new DataInputStream(in); )

{ 
/** * send file name and size to server */ 
System.out.println("processing file now"); 

File from = new File(path); 

if(from.exists() && from.canRead()){ 

String FILENAME = from.getName(); 

long FILESIZE = from.length();
 // String FILEHASH 

 /** * write all ,2 * to SERVER */ dos.writeLong(FILESIZE); dos.writeUTF(FILENAME);
 //dos.writeUTF(FILEHASH); 
dos.flush(); 

/** * what does SERVER HAS TO SAY? */

 String RESPONSE_FROM_SERVER_1 =dis.readUTF();
 if(RESPONSE_FROM_SERVER_1 . equalsIgnoreCase("SEND")){ 
uploadFresh(from,dos); 
}   
    /** * in case there was an interruption we need * resume from an offset. */ 

        if(RESPONSE_FROM_SERVER_1 . equalsIgnoreCase("RESUME")){

 /** * length already sent */

 System.out.println("resuming upload"); 

String LENGTH_ALREADY_READ =dis.readUTF(); 

long OFF_SET = Long.parseLong(LENGTH_ALREADY_READ); 

/** * get the file name so we know the exact file */ 

String FILE_REAL_NAME = dis.readUTF(); 

resume(FILE_REAL_NAME,OFF_SET,dos);
 } 
}else{ System.out.println("Couldn't read: err"); 

} 

}catch(Exception ex){ 
ex.printStackTrace(); 
}
 }
 /** the resume method **/ 

private static void resume(String FILE_REAL_NAME,long OFF_SET,DataOutputStream to)throws Exception{ 

/** * copy from the stream or disk to server */ 

FileInputStream reader = null; 

try{
 reader = new FileInputStream(new File("c:\\movies\\hallow.mp4",FILE_REAL_NAME)); byte[] size = new byte [8192]; 

int COUNT_BYTES_READ ; reader.skip(OFF_SET);

//skip the length already written

 while( (COUNT_BYTES_READ = reader.read(size)) >0{ 

to.write(size); 
to.flush();
 } 
}finally{ 
if( reader != null ) reader.close();

 to.close(); 

}
 } 

/** and the normal send method which works as expected **/ 

private static void uploadFresh(File from, DataOutputStream to)throws Exception{

 /** * copy from the stream or disk to server */ 
FileInputStream reader = null;
 try{ 
reader = new FileInputStream(from); 
byte[] size = new byte [1024];
 int COUNT_BYTES_READ ; 

while( (COUNT_BYTES_READ = reader.read(size)) >0){

 to.write(size,0,COUNT_BYTES_READ); to.flush(); 
} 
}finally{ 
if( reader != null ) reader.close();

 to.close(); 
}
 } 
}

//服务器

public class UserServer { 
String ip_Adress; 
int Port; 
ServerSocket ss; 
String path;

public UserServer(String ip_Adress,int Port ){
 this.Port =Port; this.ip_Adress = ip_Adress; this. path = path;
 } 

public void startserver() throws IOException{
 FileOutputStream fos =null; 
// String realhash; 
out.println("starting server"); 

this.ss= new ServerSocket(Port);
 out.println("starting server on port"+Port); out.println("waiting for client conection......"); 

Socket visitor = this.ss.accept(); 

out.println("1 User connected to port");

 /** 
* reading file name and size from upload 
*/ 
try( OutputStream ot =visitor.getOutputStream(); InputStream in = visitor.getInputStream(); DataOutputStream dos = new DataOutputStream(ot); DataInputStream dis = new DataInputStream(in); ){ 

System.out.println("processing debug"); 
long FILE_SIZE = dis.readLong();

 System.out.println(FILE_SIZE+"processing"); 

String FILE_NAME = dis.readUTF(); System.out.println(FILE_NAME+"processing");

 //String FILEHASH = dis.readUTF(); // System.out.println(FILEHASH+"processing"); 

File file = new File("c:\\aylo\\"+FILE_NAME); 

/** * what do We Have TO Say? */
 if(file.exists()){ 
long SIZE = file.length(); 
if(SIZE<FILE_SIZE){ 


String RESUME = "RESUME";   

//tell client to resume the upload
 dos.writeUTF(RESUME); 

/*sending the resuming length in*/ string String size = String.valueOf(SIZE);

 dos.writeUTF(size); 
dos.flush();

 fos=new FileOutputStream(file,true);
//append to exisiting file 

byte[] b = new byte [1024]; int COUNT_BYTES_READ ;
 while( (COUNT_BYTES_READ = dis.read(b)) >0){ 
fos.write(b);
 fos.flush();
} 
} 
} else{ 
} 
if(!file.exists()){
 file.getParentFile().mkdirs();
 file.createNewFile();

 String SEND = "SEND";
 dos.writeUTF(SEND);
 dos.flush();
 fos=new FileOutputStream(file); 

byte b[]=new byte[1024];

 int s;
 while((s=dis.read(b))>0){ 
fos.write(b,0,s); fos.flush(); System.out.println(s+"processing"); 
} 

} 
System.out.println("i'm done reading ");



}catch(Exception ex){ 

ex.printStackTrace();

 }finally{
 fos.close(); 
if(this.ss!=null) this.ss.close(); 
} 
}   

//主要

public static void main(String []arg){

     UserServer us = new UserServer("localhost", 2089);
     us.startserver();      

    //start client

 UploadManager.setup("localhost", 2089, ("c:\\movies\\hallow.mp4")); 
    }
     }

我已经搜索并搜索了大多数论坛和操作系统,却一无所获。 我想做的是学习或弄清楚如何恢复通过java套接字上传时中断的文件。 现在,我的代码部分可用,但是我总是认为是由 new FileOutputStream(from,true); 构造函数引起的中断或空白 任何人都可以检查我的方法并帮助指出我的错误,示例代码演示也将很好。谢谢!

1 个答案:

答案 0 :(得分:1)

请查看有关变量名称的Java约定;我花了相当长的时间才能找到您的问题,而这很大程度上归因于您的代码看起来不熟悉。另外,确实,请检查您的姓名。命名字节缓冲区以传输字节“大小”类似于命名您最喜欢的猫“马”。这会引起混乱。

问题:这样做的地方很多:

   byte[] buffer = new byte[8192];
   int bytesRead = networkIn.read(buffer);
   fileOut.write(buffer);

,这是不正确的。即使实际读取的字节数少于8192字节,“写入”调用也会写入整个8192字节的整个缓冲区。您需要做的是这样:

   byte[] buffer = new byte[8192];
   int bytesRead = networkIn.read(buffer);
   fileOut.write(buffer, 0, bytesRead);

注意:您的代码中可能存在更多错误;上面的内容肯定会引起问题,并且可以解释为什么恢复操作会生成损坏的文件。