要做一个大文件分块上传的功能,多个文件打包成zip,zip包中有个txt文件用来存放文件信息。
我是用FileInputStream 读取文件,根据服务端给的接口要求,每次读7K,读完一次就把装了7K文件的byte[] 转成Base64字符串,然后post传给服务端,传成功后开始传第二个小块.....
现在的问题是: 当文件小于7K,也就是一次就能读完的时候,文件能转成正确的Base64字符串,传给服务端后也能正常解压。但是,当文件大于7K,需要分块读取的时候,每次读取的文件转成的Base64字符串似乎有问题(7K不是3的整数倍,所以转成Base64后,字符串应该是以=结尾的,实际上,文件小于7K的时候,转成的Base64字符串就是=结尾),所有文件块传给服务端后,服务端合并成zip文件,但是解压不了,我用工具解压出来里面的文件有的是正常的,有的是坏的。
传过去之前的zip文件是完全正常的。
我一直以为是byte[]转Base64的时候存在问题,可是用了各种开源Base64库都是一样的。
下面贴上代码,希望能得到帮助!谢谢!
-
/**
* 文件上传
/
private void uploadphoto() {
try {
if (!uploadDir.exists()) {
uploadDir.mkdir();
}
//***************************图片文件的整理
zipfile = new File(zipfileDir);
if (!zipfile.exists()) {
zipfile.createNewFile();
}
FileOutputStream f = new FileOutputStream(zipfile);
CheckedOutputStream csum = new CheckedOutputStream(f, new Adler32());// 输出校验流,采用Adler32更快
ZipOutputStream outputStream = new ZipOutputStream(csum);//创建压缩输出流
String[] fileName = new String[imageArrayList.size()];
String[] description = new String[imageArrayList.size()];
List list = new ArrayList();
File imageFile = null;
for (int i = 0; i < imageArrayList.size(); i++) {
fileName[i] = imageArrayList.get(i).get(EasyGridView.TEXT);
description[i] = imageArrayList.get(i).get(EasyGridView.DESCRIPTION);
if (null == description[i]){
description[i] = "";
}
imageFile = new File(imageArrayList.get(i).get(EasyGridView.IMAGE));
list.add(imageFile);
}
if (file.exists()){//如果文件存在,就删除后重新创建 data.txt文件的处理
file.delete();
file.createNewFile();
} else {
file.createNewFile();
}
if (null != spinnerSelectedStr && !"".equals(spinnerSelectedStr.trim())) {
if (spinnerSelectedStr.equals("按时完成")) {
finishType = 1;
} else if (spinnerSelectedStr.equals("预计按时完成")) {
finishType = 2;
} else if (spinnerSelectedStr.equals("预计延期完成")) {
finishType = 3;
}
}
UploadInfo uploadInfo = new UploadInfo();
uploadInfo.setComment(comment);
uploadInfo.setFinishType(finishType);
uploadInfo.setPicMemos(description);
uploadInfo.setPicNames(fileName);
uploadInfo.setTaskType(1);
Gson gson = new Gson();
String json = gson.toJson(uploadInfo);
FileUtils.getFile(json.toString().getBytes(), file);
list.add(file);//把data.txt和图片放到一个list里方便打包
FileUtils.zipFile(list, outputStream/*, zipfileDir*/);
if (zipfile.length()%(7*1024) == 0){
blockSize = (int) (zipfile.length()/(7*1024));
}else {
blockSize = (int) (zipfile.length()/(7*1024)) +1;
}
uploadLittleFile(/*fis*/);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 上传小块文件
/
private void uploadLittleFile(){
try {
if (zipfile.exists()/ && fis != null*/){//如果文件存在,即,打zip包成功 1k=1024bit
fis = new FileInputStream(zipfile);
byte[] buffer = new byte[7 * 1024];
int length;
while (-1 != (length = fis.read(buffer))){
byteString = new BASE64Encoder().encode(Arrays.copyOf(buffer,length));
LogUtil.d("file string",byteString);
PhotoApi.uploadPhoto(PreNotifyDetailActivity.this, address,
filename, byteString, blockIndex, /*handler,*/new UploadCallBack() {
@Override
public void onGetResult(int code) throws JSONException {
//一个序号执行成功后 才开始执行下一个序号
blockIndex++;
if (blockIndex == blockSize && submitTimes == 0){//在这里执行任务包
blockIndex = 0;//全部传完后,归零
submitTimes++;
LogUtil.d("dotaskpackage","最后一块传完");
PhotoApi.doTaskPackage(PreNotifyDetailActivity.this,address,filename,new
UploadCallBack(){
@Override
public void onGetResult( int code) throws JSONException{
LogUtil.d("dotaskpackage","提交成功!");
blockIndex = 0;
len = 0;
zipfile.delete();//删除文件
file.delete();
whileflag = true;
isNotLastTime = true;
lastLength = 0;
littleFlag = true;
try {
fis.close();
}catch (Exception e){
e.printStackTrace();
}
finish();//完全上传成功后,关闭这个界面
}
@Override
public void onFailureResult(int code){
if (code == 204){
LogUtil.d("dotaskpackage","zip包解压后data.txt的内容为空! 204");
blockIndex = 0;
len = 0;
zipfile.delete();//删除文件
file.delete();
whileflag = true;
isNotLastTime = true;
lastLength = 0;
littleFlag = true;
// uploadphoto();
// uploadLittleFile(fis);
}else if (code == 400){
LogUtil.d("dotaskpackage","任务解读失败,同时删除zip包! 400");
blockIndex = 0;
len = 0;
zipfile.delete();//删除文件
file.delete();
whileflag = true;
isNotLastTime = true;
lastLength = 0;
littleFlag = true;
// uploadphoto();
// uploadLittleFile(fis);
}else if (code == 404){
LogUtil.d("dotaskpackage","文件未找到或者zip包解压后data.txt文件未找到! 404");
blockIndex = 0;
len = 0;
zipfile.delete();//删除文件
file.delete();
whileflag = true;
isNotLastTime = true;
lastLength = 0;
littleFlag = true;
// uploadphoto();
// uploadLittleFile(fis);
}
}
});
} // uploadLittleFile();
}
@Override
public void onFailureResult(int code) {
if (code == 400){//重新上传本序号 // len -= length;//已读长度要减去length
PhotoApi.uploadPhoto(PreNotifyDetailActivity.this, address,
filename, byteString, blockIndex, /*handler,*/new UploadCallBack() {
@Override
public void onGetResult(int code) throws JSONException { //
ToastUtil.showMessage(PreNotifyDetailActivity.this,"重传本序号成功");
LogUtil.d("dotaskpackage","重传本序号成功");
}@Override public void onFailureResult( int code) { //
ToastUtil.showMessage(PreNotifyDetailActivity.this,"重传本序号失败");
LogUtil.d("dotaskpackage","重传本序号失败");
}
});
}else if (code == 404){//重头开始传
blockIndex = 0;
len = 0;
uploadphoto();
}
}
});} finish(); }else{ // ToastUtil.showMessage(PreNotifyDetailActivity.this, "提交失败,请重试"); } }catch (Exception e){ e.printStackTrace(); }finally { try { if (null != fis) fis.close(); fis = null; }catch (Exception e){ e.printStackTrace(); } } }