首页 > 代码库 > 安卓分段上传文件、视频

安卓分段上传文件、视频

安卓上传图片的时候,还可以压缩,

但是上传视频的时候,没有好的压缩方式。

后来想到两种解决方式

1是用传统的http post 方式上传,传的内容是文件流,不过不知道承受力有多大,优点是这个方法已经成熟,传文件流,把传base64 处理过的,内存溢出情况少很多。

2是android 端,分段上传文件。


第二种是根本解决内存溢出方法

其核心思想是

1 同一个文件,分段上传上去采用相同的名字,后台把接收到的base64 数据拼接。

2 既然是分段,传完一段才能传下一段,并且完整拼接。


每个段都传完了,证明这个文件传完,这个判断在安卓端实现。

我做的时候参考文章http://blog.csdn.net/defonds/article/details/8575893


这个是java写的。缺陷是没有把小文件包含进去。

下面我附上我的完整代码,用的是webService方式上传,代码可能不够精简,希望大家提出意见

/**
* 分段上传视频
*/
private void sectionUpload() {


File file = new File(videoPath);
int fileLen = 0;
try {
FileInputStream fis = new FileInputStream(file);


fileLen = fis.available();
} catch (FileNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}


// 31457280 30M
if (fileLen >= 31457280) {
tishiDialog(WeiGuiAPIActivity.this, "上传文件不能大于30M");
return;
}


AsyncShowDialog.dialogShow(this);


new Thread() {
public void run() {
try {
int blockIndex = 1;
int blockNumber = 1;
String ext = videoPath
.substring(videoPath.lastIndexOf("."));//


// 有后缀之后,还得存一个图片名字
String fileName = Tools.getCurrentUtcTime_no_space() + ext;
FileInputStream fis = null;
ByteArrayOutputStream baos = null;
// 现在是要得到一个路径
File file = new File(videoPath);
fis = new FileInputStream(file);
RandomAccessFile raf = new RandomAccessFile(file, "r");// 负责读取数据


int fileLen = fis.available();


// 视频格式、大小
blockNumber = (int) (fileLen / blockSize);
// 10704745
if (fileLen % blockSize != 0) {
blockNumber = blockNumber + 1;
}
while (blockIndex <= blockNumber) {


BufferedInputStream bis = new BufferedInputStream(fis);
// bis.read(buffer, byteOffset, byteCount)
baos = new ByteArrayOutputStream();


// byte[] buffer_1 = new byte[1024 * 1024];
byte[] buffer = new byte[1024];


String uploadBuffer = null;
// fis.read(buffer, byteOffset, byteCount);
// 写是1kb 1,kb


if (blockIndex == 1) {
int n = 0;
long readLength = 0;// 记录已读字节数
if (fileLen >= blockSize) {
while (readLength <= blockSize - 1024) {// 大部分字节在这里读取


n = raf.read(buffer, 0, 1024);
readLength += 1024;
baos.write(buffer, 0, n);
}
if (readLength < blockSize) {// 余下的不足 1024
// 个字节在这里读取
// n = raf.read(buffer, 0, (int)(blockSize -
// readLength));
n = raf.read(buffer, 0, 1024);
baos.write(buffer, 0, n);
}


} else {
while (readLength <= fileLen - 1024) {// 大部分字节在这里读取


n = raf.read(buffer, 0, 1024);
readLength += 1024;
baos.write(buffer, 0, n);
}
}


} else if (blockIndex < blockNumber) {// 既不是第一块,也不是最后一块
raf.seek(blockSize * (blockIndex - 1));// 跳过前[块数*固定大小
// ]个字节
// fis.skip(blockSize * (blockIndex - 1));
int n = 0;
long readLength = 0;// 记录已读字节数
while (readLength <= blockSize - 1024) {// 大部分字节在这里读取
n = raf.read(buffer, 0, 1024);
readLength += 1024;
baos.write(buffer, 0, n);
}
if (readLength <= blockSize) {// 余下的不足 1024 个字节在这里读取
n = raf.read(buffer, 0,
(int) (blockSize - readLength));
baos.write(buffer, 0, n);
}
} else {// 最后一块
raf.seek(blockSize * (blockIndex - 1));// 跳过前[块数*固定大小
// ]个字节
int n = 0;
while ((n = raf.read(buffer, 0, 1024)) != -1) {
baos.write(buffer, 0, n);
}
}


// while((count = fis.read(buffer)) >= 0) {
// baos.write(buffer, 0, count);
// }
try {
if (baos != null) {
baos.flush();
baos.close();
}
if (fis != null) {


fis.close();
}


} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// uploadBuffer = new String(Base64.encode(baos
// .toByteArray()));


// baos.flush();


// 难道这里需要写一个循环上传


try {
// 其实是这句话内存泄露了
uploadBuffer = new String(Base64.encode(baos
.toByteArray()));
} catch (OutOfMemoryError e) {
// TODO Auto-generated catch block
Toast.makeText(WeiGuiAPIActivity.this, "内存泄露", 0)
.show();
e.printStackTrace();
}


// 这块容易内存泄露


// String test = baos.toByteArray().toString();


List<WSParam> params = new ArrayList<WSParam>();


// int size = uploadBuffer.length();


params.add(new WSParam("filename", fileName));
params.add(new WSParam("data", uploadBuffer));


params.add(new WSParam("pwd", MyData.Md5PWD));


String strResult = null;
try {
Connection2PHP connection = new Connection2PHP();
Object result = null;
try {
result = connection.callWebService(
MyData.webServiceURL, "uploadVideo",
params);


} catch (Exception e) {


e.printStackTrace();
}


if (result == null) {
Tools.log("服务器没有开");
strResult = "";
// 上传错误,重新上传。
continue;
} else {
strResult = result.toString();
CommonJSONParser parser = new CommonJSONParser();
Map map = parser.parse(strResult);
String videoName = map.get("filename")
.toString();


// 只取第一段的时候的值
if (blockIndex == 1) {
sb_video = sb_video.append(videoName + "#");
}


}


} catch (Exception e) {
e.printStackTrace();
}


blockIndex++;


}


//
Message msg = handler.obtainMessage();
msg.what = 1;
Bundle bundle = new Bundle();
bundle.putString("result", "上传成功");
msg.setData(bundle);
handler.sendMessage(msg);





} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {


}
};


}.start();
}