首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >上传镜像到服务器会损坏镜像

上传镜像到服务器会损坏镜像
EN

Stack Overflow用户
提问于 2016-03-08 06:39:14
回答 2查看 770关注 0票数 3

我的应用程序中有一个图像上传方法,它需要将图像和字符串发送到我的服务器。

问题是,服务器接收内容(图像和字符串),但当它将图像保存在磁盘上时,它已损坏,无法打开。

这是脚本的相关部分。

代码语言:javascript
复制
HttpPost httpPost = new HttpPost(url);

Bitmap bmp = ((BitmapDrawable) imageView.getDrawable()).getBitmap();
ByteArrayOutputStream stream = new ByteArrayOutputStream();

bmp.compress(Bitmap.CompressFormat.PNG, 100, stream);

byte[] byteArray = stream.toByteArray();
String byteStr = new String(byteArray);

StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("--"+boundary+"\r\n");
stringBuilder.append("Content-Disposition: form-data; name=\"content\"\r\n\r\n");
stringBuilder.append(message+"\r\n");

stringBuilder.append("--"+boundary+"\r\n");
stringBuilder.append("Content-Disposition: form-data; name=\"image\"; filename=\"image.jpg\"\r\n");

stringBuilder.append("Content-Type: image/jpeg\r\n\r\n");

stringBuilder.append(byteStr);
stringBuilder.append("\r\n");

stringBuilder.append("--"+boundary+"--\r\n");
StringEntity entity = new StringEntity(stringBuilder.toString());
httpPost.setEntity(entity);

我不能更改服务器,因为其他客户端正在使用它,并且它为他们工作。我只需要知道为什么图像会被破坏。

EN

回答 2

Stack Overflow用户

发布于 2016-03-08 06:53:48

当您执行new String(byteArray)时,它会将二进制文件转换为缺省字符集(通常是UTF-8)。大多数字符集都不适合二进制数据编码。换句话说,如果您将某些二进制字符串编码为UTF-8,然后解码回二进制,您将不会得到相同的二进制字符串。

由于您使用的是多部分编码,因此需要直接写入实体的流。Apache HTTP客户端具有用于执行此操作的帮助器。See this guide,或this Android guide到上传的多部分。

如果只需要使用字符串,可以使用以下命令安全地将字节数组转换为字符串

代码语言:javascript
复制
String byteStr = android.util.Base64.encode(byteArray, android.util.Base64.DEFAULT);

但需要注意的是,您的服务器需要将字符串Base64解码回字节数组,并将其保存到图像中。此外,传输大小会更大,因为Base64编码不像原始二进制编码那样节省空间。

票数 3
EN

Stack Overflow用户

发布于 2016-03-08 17:04:30

上面的解决方案不起作用,因为您正在使用new String(byteArray)。构造函数使用默认编码对字节数组进行编码-请参阅What is the default encoding -很可能数据中有无法编码为字符的字节序列。

更准确地说,字符集定义了如何将字符表示为字节。大多数字符集都有256个以上的字符。这就是为什么你需要一个以上的字节来表示一个字符。UTF-8和UTF-16最多使用四个字节。所以你在数字空间和字符空间之间有一个映射,这个映射不是先验的。因此,很可能在数字空间中存在一个没有映射到它的字符的数字。

@Samuel建议的解决方案是万无一失的,因为Base64使用A-Z,a-z,0-9,+,/,并以=结束表示一个字节。我更喜欢这个解决方案!

如果你不想或不能使用Base64,那么你可以试着把每个字节按原样扔到StringBuilder中,希望服务器在你得到它之前不做任何编码。

代码语言:javascript
复制
for (byte b : byteArray) {
  stringBuilder.append((char)b);
}

我一般不推荐这个解决方案,但它可能会帮助你完成你的工作。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35855558

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档