赞
踩
fastdfs支持断点续传需要客户进行切片上传,并且切片字节大小小于等于storage配置的buff_size,默认是256k。当fastdfs storage接收客户端上传数据时,如果出现超时的情况会对文件offset和接收时记录的start、end进行比较,当offset>start 并且 offset < end时即写入文件的数据是应接收的一部分数据时,会truncate。所以当切片大小小于buff_size时,每次写入时如果发生异常,因未达到buff_size,所以服务端还未写入文件,不会产生truncate问题。注意发生异常,下次传输时,需根据fileid获取服务端的文件大小,然后对文件流进行skip之后,继续上传即可。
以下是核心代码
/**
* 如果fileid不为空则代表是续传
* @param local_filename
* @param fileid
* @return
*/
public UploadResultInfo upload_file(String local_filename, String fileid) {
StorageClient1 client = null;
try {
client = assignResourse(fileid);
} catch (Exception e) {
return new UploadResultInfo(fileid,local_filename, e.getMessage());
}
try{
// 如果file没有值则代表是新文件上传不是续传
try {
if (fileid == null || fileid.trim().length() == 0) {
String ext_name = fetchFileExtName(local_filename);
fileid = client.upload_appender_file1(new byte[] {}, ext_name,
null);
}
} catch (Exception e) {
return new UploadResultInfo(fileid,local_filename, "上传文件失败");
}
// ------------开始按照文件切片追加文件----------------------
long size = 0;
try {
File file = new File(local_filename);
long length = file.length();
logger.debug("FileService StorageServer:"
+ client.getStorageServer() + ",TrackerServer:"
+ client.getTrackerServer());
FileInfo fileInfo = fetchFileInfo(client,fileid);
size = fileInfo.getFileSize();
logger.debug("FileService StorageServer:"
+ client.getStorageServer() + ",TrackerServer:"
+ client.getTrackerServer());
// 客户端记录已上成功上传到服务端的记录
size = upload_file(client,fileid, size, length, new FileInputStream(file));
//只有当完全上传成功才返回一个完整的UploadResultInfo对象
if(size == length){
UploadResultInfo uploadresultinfo = new UploadResultInfo(fileid,true,local_filename, "上传文件成功",size);
uploadresultinfo.setUrl(ProtoCommon.HTTP.concat(fileInfo.getSourceIpAddr()).concat("/").concat(fileid));
return uploadresultinfo;
}
return new UploadResultInfo(fileid,local_filename, "追加文件失败1",size);
} catch (FileNotFoundException e) {
return new UploadResultInfo(fileid,local_filename, "本地文件未找到,追加失败",size);
} catch (Exception e) {
return new UploadResultInfo(fileid,local_filename, "追加文件失败2",size);
}
}finally {
releaseResourse(client);
}
}
/**
*
* @param fileid 远程文件标识用于追加
* @param skipsize 已成功上传的文件大小
* @param length 完整文件大小
* @param is 完整文件流
* @return
* @throws Exception
*/
public long upload_file(StorageClient1 client,String fileid, long skipsize, long length,
InputStream is) throws Exception {
if (skipsize >= length) {
return length;
}
byte[] buff = new byte[ClientGlobal.section_size];
is.skip(skipsize);
while (skipsize < length) {
int readcount = is
.read(buff,
0,
(length - skipsize) < buff.length ? (int) (length - skipsize)
: buff.length);
int result = -1;
try {
byte[] newbuffer;
if (readcount < buff.length) {
newbuffer = new byte[readcount];
System.arraycopy(buff, 0, newbuffer, 0, readcount);
result = client.append_file1(fileid, newbuffer);
} else {
result = client.append_file1(fileid, buff);
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (result != 0) {
return skipsize;
}
skipsize += readcount;
logger.debug(fileid+"->skipsize:"+skipsize);
}
return length;
}
完整代码下载见http://download.csdn.net/detail/kaka20099527/8833107
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。