android下大文件分割上传

时间:2023-03-09 04:34:22
android下大文件分割上传
  1. 由于android自身的原因,对大文件(如影视频文件)的操作很容易造成OOM,即:Dalvik堆内存溢出,利用文件分割将大文件分割为小文件可以解决问题。

  • 文件分割后分多次请求服务。
     //文件分割上传
    public void cutFileUpload(String fileType,String filePath)
    {
    try
    {
    FileAccessI fileAccessI = new FileAccessI(filePath, 0);
    Long nStartPos = 0l;
    Long length = fileAccessI.getFileLength();
    int mBufferSize = 1024 * 100; //每次处理1024 * 100字节
    byte[] buffer = new byte[mBufferSize];
    FileAccessI.Detail detail;
    long nRead = 0l;
    String vedioFileName = Usual.f_getUUID(); //分配一个文件名
    long nStart = nStartPos;
    int i = 0;
    while (nStart < length)
    {
    detail = fileAccessI.getContent(nStart);
    nRead = detail.length;
    buffer = detail.b;
    JSONObject mInDataJson = new JSONObject();
    mInDataJson.put("a", "282");
    mInDataJson.put("FileName", vedioFileName);
    mInDataJson.put("start", nStart); //服务端获取开始文章进行写文件
    mInDataJson.put("filetype", fileType);
    nStart += nRead;
    nStartPos = nStart;
    String url = UsualA.f_getXmlSOAUrl(UsualA.mServiceFastByteUrl, "n.uploadvedio", mInDataJson.toString(),
    "282");
    HttpFastUtil.f_httpPostByte(url, buffer, false);
    }
    }
    catch (Exception e)
    {
    }
  • 文件分割类
     package ishitong.mppsp.android.util;
    
     import java.io.*;
    
     public class FileAccessI implements Serializable
    { RandomAccessFile oSavedFile;
    long nPos; public FileAccessI() throws IOException
    {
    this("", 0);
    }
    public FileAccessI(String sName, long nPos) throws IOException
    {
    oSavedFile = new RandomAccessFile(sName, "rw");//创建一个随机访问文件类,可读写模式
    this.nPos = nPos;
    oSavedFile.seek(nPos);
    }
    public synchronized int write(byte[] b, int nStart, int nLen)
    {
    int n = -1;
    try
    {
    oSavedFile.write(b, nStart, nLen);
    n = nLen;
    }
    catch (IOException e)
    {
    e.printStackTrace();
    }
    return n;
    }
    //每次读取102400字节
    public synchronized Detail getContent(long nStart)
    {
    Detail detail = new Detail();
    detail.b = new byte[102400];
    try
    {
    oSavedFile.seek(nStart);
    detail.length = oSavedFile.read(detail.b);
    }
    catch (IOException e)
    {
    e.printStackTrace();
    }
    return detail;
    } public class Detail
    { public byte[] b;
    public int length;
    } //获取文件长度
    public long getFileLength()
    {
    Long length = 0l;
    try
    {
    length = oSavedFile.length();
    }
    catch (IOException e)
    {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    return length;
    }
    }
  • 服务端获得分割的文件,利用RandomAccessFile进行文件整理
     /**
    * 音视频图片处理
    * @param mStr
    * @return
    * @throws Exception
    */
    public static String f_uploadVedio(String mStr) throws Exception
    {
    String mResult = Usual.mEmpty;
    String fileType = Usual.mEmpty;
    int startPosL = 0;
    RandomAccessFile oSavedFile = null;
    JSONObject jsonObject = new JSONObject(mStr);
    String vedioJsonStr = jsonObject.getString("VEDIO");
    byte[] vedioBytes = Usual.f_fromBase64String(vedioJsonStr);
    startPosL = (Integer) jsonObject.get("start"); //接收客户端的开始位置(文件读取到的字节大小)
    fileType = (String)jsonObject.getString("filetype");
    String fileName = (String)jsonObject.getString("FileName");
    if(fileType.equals("picture"))
    {
    oSavedFile = new RandomAccessFile("E:\\"+fileName+".jpg","rw");
    }
    else if(fileType.equals("photo"))
    {
    oSavedFile = new RandomAccessFile("E:\\"+fileName+".jpg","rw");
    }
    else if(fileType.equals("voice"))
    {
    oSavedFile = new RandomAccessFile("E:\\"+fileName+".mp3","rw");
    }
    else if(fileType.equals("video"))
    {
    oSavedFile = new RandomAccessFile("E:\\"+fileName+".mp4", "rw");
    }
    //设置标志位,标志文件存储的位置
    oSavedFile.seek(startPosL);
    oSavedFile.write(vedioBytes);
    oSavedFile.close();
    mResult = "000";
    return mResult;
    }