/**
* 上传文件到FTP服务器,支持断点续传
* @param local 本地文件名称,绝对路径
* @param remote 远程文件路径,使用/home/directory1/subdirectory/file.ext 按照Linux上的路径指定方式,支持多级目录嵌套,支持递归创建不存在的目录结构
* @return 上传结果
* @throws IOException
*/
public UploadStatus upload(String local,String remote) throws IOException{
FTPClient ftpClient = new FTPClient()
//设置PassiveMode传输
ftpClient.enterLocalPassiveMode()
//设置以二进制流的方式传输
ftpClient.setFileType(FTP.BINARY_FILE_TYPE)
UploadStatus result
//对远程目录的处理
String remoteFileName = remote
if(remote.contains("/")){
remoteFileName = remote.substring(remote.lastIndexOf("/")+1)
String directory = remote.substring(0,remote.lastIndexOf("/")+1)
if(!directory.equalsIgnoreCase("/")&&!ftpClient.changeWorkingDirectory(directory)){
//如果远程目录不存在,则递归创建远程服务器目录
int start=0
int end = 0
if(directory.startsWith("/")){
start = 1
}else{
start = 0
}
end = directory.indexOf("/",start)
while(true){
String subDirectory = remote.substring(start,end)
if(!ftpClient.changeWorkingDirectory(subDirectory)){
if(ftpClient.makeDirectory(subDirectory)){
ftpClient.changeWorkingDirectory(subDirectory)
}else {
System.out.println("创建目录失败")
return UploadStatus.Create_Directory_Fail
}
}
start = end + 1
end = directory.indexOf("/",start)
//检查所有目录是否创建完毕
if(end <= start){
break
}
}
}
}
//检查远程是否存在文件
FTPFile[] files = ftpClient.listFiles(remoteFileName)
if(files.length == 1){
long remoteSize = files[0].getSize()
File f = new File(local)
long localSize = f.length()
if(remoteSize==localSize){
return UploadStatus.File_Exits
}else if(remoteSize >localSize){
return UploadStatus.Remote_Bigger_Local
}
//尝试移动文件内读取指针,实现断点续传
InputStream is = new FileInputStream(f)
if(is.skip(remoteSize)==remoteSize){
ftpClient.setRestartOffset(remoteSize)
if(ftpClient.storeFile(remote, is)){
return UploadStatus.Upload_From_Break_Success
}
}
//如果断点续传没有成功,则删除服务器上文件,重新上传
if(!ftpClient.deleteFile(remoteFileName)){
return UploadStatus.Delete_Remote_Faild
}
is = new FileInputStream(f)
if(ftpClient.storeFile(remote, is)){
result = UploadStatus.Upload_New_File_Success
}else{
result = UploadStatus.Upload_New_File_Failed
}
is.close()
}else {
InputStream is = new FileInputStream(local)
if(ftpClient.storeFile(remoteFileName, is)){
result = UploadStatus.Upload_New_File_Success
}else{
result = UploadStatus.Upload_New_File_Failed
}
is.close()
}
return result
}
UDP是并不是可靠的传输方式,字节序列并没有得到校验,所以传输文件时出现错误也是难免的.因为,txt,doc和jpg本身即使出错也不会影响打开,顶多出现个别字符或是个别像素错误不会影响整体,而exe则是cpu的指令执行序列你错一个就将会导致程序无法执行,如果你懂hash的话可以将文件hash一下看看传输前后的hash码是否相同若不相同说明了传输过程出现了错误需要重传.UDP一般应用在海量的并对准确性要求不高的传输上,并一般伴随有重传机制
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)