2 u010577768 u010577768 于 2014.05.23 21:33 提问

android http 文件上传遇见的难题!!!求大神指点!!!

要做一个大文件分块上传的功能,多个文件打包成zip,zip包中有个txt文件用来存放文件信息。
我是用FileInputStream 读取文件,根据服务端给的接口要求,每次读7K,读完一次就把装了7K文件的byte[] 转成Base64字符串,然后post传给服务端,传成功后开始传第二个小块.....

现在的问题是: 当文件小于7K,也就是一次就能读完的时候,文件能转成正确的Base64字符串,传给服务端后也能正常解压。但是,当文件大于7K,需要分块读取的时候,每次读取的文件转成的Base64字符串似乎有问题(7K不是3的整数倍,所以转成Base64后,字符串应该是以=结尾的,实际上,文件小于7K的时候,转成的Base64字符串就是=结尾),所有文件块传给服务端后,服务端合并成zip文件,但是解压不了,我用工具解压出来里面的文件有的是正常的,有的是坏的。
传过去之前的zip文件是完全正常的。
我一直以为是byte[]转Base64的时候存在问题,可是用了各种开源Base64库都是一样的。
下面贴上代码,希望能得到帮助!谢谢!

  1. /**
    * 文件上传
    /
    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();
            }
        }
    }
    
Csdn user default icon
上传中...
上传图片
插入图片
准确详细的回答,更有利于被提问者采纳,从而获得C币。复制、灌水、广告等回答会被删除,是时候展现真正的技术了!