android httpurlconnection post 文件大小,android – HTTPURLConnection – 使用FixedLengthStreamingMode的大文件POST...

所以我正在尝试发送带有大图像文件的multipart / form-data POST请求.我不能预先将文件转换为字节数组,我的应用程序会因OutOfMemory异常而崩溃,所以我必须将文件的内容直接写入连接的输出流.此外,我的服务器不支持分块模式,因此我必须在发送数据之前计算内容长度并使用连接的setFixedLengthStreamingMode.

public void createImagePostWithToken(String accessToken,String text,String type,String imagePath) {

URL imageUrl = null;

String lineEnd = "\r\n";

String twoHyphens = "--";

// generating byte[] boundary here

HttpURLConnection conn = null;

DataOutputStream outputStream = null;

DataInputStream inputStream = null;

int bytesRead,bytesAvailable,bufferSize;

byte[] buffer;

int maxBufferSize = 1*1024*1024;

try

{

long contentLength;

int serverResponseCode;

String serverResponseMessage;

File file = new File(imagePath);

FileInputStream fileInputStream = new FileInputStream(file);

imageUrl = buildUri("posts").toURL();

conn = (HttpURLConnection)imageUrl.openConnection();

conn.setConnectTimeout(30000);

conn.setReadTimeout(30000);

conn.setDoOutput(true);

conn.setDoInput(true);

conn.setRequestMethod("POST");

conn.setRequestProperty("Content-Type","multipart/form-data;boundary=" + boundary);

String stringForLength = new String();

stringForLength += "Content-Type: multipart/form-data;boundary=" + boundary;

stringForLength += twoHyphens + boundary + lineEnd + "Content-Disposition: form-data; name=\"access_token\"" + lineEnd;

stringForLength += "Content-Type: text/plain;charset=UTF-8" + lineEnd + "Content-Length: " + accessToken.length() + lineEnd + lineEnd;

stringForLength += accessToken + lineEnd + twoHyphens + boundary + lineEnd;

stringForLength += "Content-Disposition: form-data; name=\"text\"" + lineEnd;

stringForLength += "Content-Type: text/plain;charset=UTF-8" + lineEnd + "Content-Length: " + text.length() + lineEnd + lineEnd;

stringForLength += text + lineEnd + twoHyphens + boundary + lineEnd;

stringForLength += "Content-Disposition: form-data; name=\"type\"" + lineEnd;

stringForLength += "Content-Type: text/plain;charset=UTF-8" + lineEnd + "Content-Length: " + type.length() + lineEnd + lineEnd;

stringForLength += type + lineEnd + twoHyphens + boundary + lineEnd;

stringForLength += twoHyphens + boundary + lineEnd + "Content-Disposition: form-data; name=\"image\"" + lineEnd;

stringForLength += "Content-Type: application/octet-stream" + lineEnd + "Content-Length: " + file.length() + lineEnd + lineEnd;

stringForLength += lineEnd + twoHyphens + boundary + twoHyphens + lineEnd;

int totalLength = stringForLength.length() + (int)file.length();

conn.setFixedLengthStreamingMode(totalLength);

outputStream = new DataOutputStream( conn.getOutputStream() );

outputStream.writeBytes(twoHyphens + boundary + lineEnd);

// access token

outputStream.writeBytes("Content-Disposition: form-data; name=\"access_token\"" + lineEnd);

outputStream.writeBytes("Content-Type: text/plain;charset=UTF-8" + lineEnd);

outputStream.writeBytes("Content-Length: " + accessToken.length() + lineEnd);

outputStream.writeBytes(lineEnd);

outputStream.writeBytes(accessToken + lineEnd);

outputStream.writeBytes(twoHyphens + boundary + lineEnd);

// text

outputStream.writeBytes("Content-Disposition: form-data; name=\"text\"" + lineEnd);

outputStream.writeBytes("Content-Type: text/plain;charset=UTF-8" + lineEnd);

outputStream.writeBytes("Content-Length: " + text.length() + lineEnd);

outputStream.writeBytes(lineEnd);

outputStream.writeBytes(text + lineEnd);

outputStream.writeBytes(twoHyphens + boundary + lineEnd);

// type

outputStream.writeBytes("Content-Disposition: form-data; name=\"type\"" + lineEnd);

outputStream.writeBytes("Content-Type: text/plain;charset=UTF-8" + lineEnd);

outputStream.writeBytes("Content-Length: " + type.length() + lineEnd);

outputStream.writeBytes(lineEnd);

outputStream.writeBytes(type + lineEnd);

outputStream.writeBytes(twoHyphens + boundary + lineEnd);

// image

outputStream.writeBytes(twoHyphens + boundary + lineEnd);

outputStream.writeBytes("Content-Disposition: form-data; name=\"image\"" + lineEnd);

//outputStream.writeBytes(lineEnd);

outputStream.writeBytes("Content-Type: application/octet-stream" + lineEnd);

outputStream.writeBytes("Content-Length: " + file.length() + lineEnd);

outputStream.writeBytes(lineEnd);

bytesAvailable = fileInputStream.available();

bufferSize = Math.min(bytesAvailable,maxBufferSize);

buffer = new byte[bufferSize];

// Read file

bytesRead = fileInputStream.read(buffer,bufferSize);

while (bytesRead > 0)

{

outputStream.write(buffer,bufferSize);

bytesAvailable = fileInputStream.available();

bufferSize = Math.min(bytesAvailable,maxBufferSize);

bytesRead = fileInputStream.read(buffer,bufferSize);

}

outputStream.writeBytes(lineEnd);

outputStream.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);

Log.d("posttemplate","connection outputstream size is " + outputStream.size());

// finished with POST request body

// Responses from the server (code and message)

serverResponseCode = conn.getResponseCode();

serverResponseMessage = conn.getResponseMessage();

Log.d("posttemplate","server response code "+ serverResponseCode);

Log.d("posttemplate","server response message "+ serverResponseMessage);

fileInputStream.close();

conn.disconnect();

outputStream.flush();

outputStream.close();

} catch (MalformedURLException e)

{

Log.d("posttemplate","malformed url",e);

//TODO: catch exception;

} catch (IOException e)

{

Log.d("posttemplate","ioexception",e);

//TODO: catch exception

}

}

不幸的是,我的应用程序在outputStream.close()时崩溃了IOException,我不明白为什么:

03-16 13:56:51.035: D/posttemplate(6479): java.io.IOException: unexpected end of stream

03-16 13:56:51.035: D/posttemplate(6479): at org.apache.harmony.luni.internal.net.www.protocol.http.FixedLengthOutputStream.close(FixedLengthOutputStream.java:57)

03-16 13:56:51.035: D/posttemplate(6479): at java.io.FilterOutputStream.close(FilterOutputStream.java:66)

03-16 13:56:51.035: D/posttemplate(6479): at com.futubra.api.impl.PostTemplate.createImagePostWithToken(PostTemplate.java:282)

03-16 13:56:51.035: D/posttemplate(6479): at com.futubra.FutubraNewPostActivity.createPost(FutubraNewPostActivity.java:128)

03-16 13:56:51.035: D/posttemplate(6479): at com.futubra.FutubraNewPostActivity_.access$2(FutubraNewPostActivity_.java:1)

03-16 13:56:51.035: D/posttemplate(6479): at com.futubra.FutubraNewPostActivity_$5.run(FutubraNewPostActivity_.java:141)

03-16 13:56:51.035: D/posttemplate(6479): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1088)

03-16 13:56:51.035: D/posttemplate(6479): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581)

03-16 13:56:51.035: D/posttemplate(6479): at java.lang.Thread.run(Thread.java:1019)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值