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); 构造函数引起的中断或空白 任何人都可以检查我的方法并帮助指出我的错误,示例代码演示也将很好。谢谢!
答案 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);
注意:您的代码中可能存在更多错误;上面的内容肯定会引起问题,并且可以解释为什么恢复操作会生成损坏的文件。