安卓上传图片的时候,还可以压缩,
但是上传视频的时候,没有好的压缩方式。
后来想到两种解决方式
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();
}