使用 REST API 上传到 Azure Blob 存储时 Zip 存档损坏
Zip Archives get corrupted when uploading to Azure Blob Store using REST API
我一直在用这个把头撞到墙上,上传文本文件没问题,但是当我将 zip 存档上传到我的 blob 存储时 -> 它已损坏,下载后无法打开。
对原始文件与通过 Azure 的文件进行十六进制比较(下图)显示发生了一些细微的替换,但我找不到 change/corruption 的来源。
我试过强制 UTF-8/Ascii/UTF-16,但发现 UTF-8 可能是正确的,none 已经解决了这个问题。
我也尝试过不同的 http 库,但得到了相同的结果。
部署环境强制unirest,无法使用微软API(貌似没问题)
package blobQuickstart.blobAzureApp;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.Base64;
import org.junit.Test;
import kong.unirest.HttpResponse;
import kong.unirest.Unirest;
public class WhosebugExample {
@Test
public void uploadSmallZip() throws Exception {
File testFile = new File("src/test/resources/zip/simple.zip");
String blobStore = "secretstore";
UploadedFile testUploadedFile = new UploadedFile();
testUploadedFile.setName(testFile.getName());
testUploadedFile.setFile(testFile);
String contentType = "application/zip";
String body = readFileContent(testFile);
String url = "https://" + blobStore + ".blob.core.windows.net/naratest/" + testFile.getName() + "?sv=2020-02-10&ss=b&srt=o&sp=c&se=2021-09-07T20%3A10%3A50Z&st=2021-09-07T18%3A10%3A50Z&spr=https&sig=xvQTkCQcfMTwWSP5gXeTB5vHlCh2oZXvmvL3kaXRWQg%3D";
HttpResponse<String> response = Unirest.put(url)
.header("x-ms-blob-type", "BlockBlob").header("Content-Type", contentType)
.body(body).asString();
if (!response.isSuccess()) {
System.out.println(response.getBody());
throw new Exception("Failed to Upload File! Unexpected response code: " + response.getStatus());
}
}
private static String readFileContent(File file) throws Exception {
InputStream is = new FileInputStream(file);
ByteArrayOutputStream answer = new ByteArrayOutputStream();
byte[] byteBuffer = new byte[8192];
int nbByteRead;
while ((nbByteRead = is.read(byteBuffer)) != -1)
{
answer.write(byteBuffer, 0, nbByteRead);
}
is.close();
byte[] fileContents = answer.toByteArray();
String s = Base64.getEncoder().encodeToString(fileContents);
byte[] resultBytes = Base64.getDecoder().decode(s);
String encodedContents = new String(resultBytes);
return encodedContents;
}
}
请帮忙!
byte[] resultBytes = Base64.getDecoder().decode(s);
String encodedContents = new String(resultBytes);
您正在从包含二进制数据的字节数组创建字符串。字符串仅用于可打印字符。你做多个毫无意义的encoding/decoding只是占用更多的内存。
如果内容是 ZIP 格式,它是二进制的,只是 return 字节数组。或者您可以对内容进行编码,但是您应该 return 对内容进行编码。作为一个弱点,您在内存中完成所有操作,限制了内容的潜在大小。
默认情况下,Unirest 文件处理程序将强制使用多部分正文 - Azure 不支持。
一个Byte Array可以直接这样提供:https://github.com/Kong/unirest-java/issues/248
Unirest.put("http://somewhere")
.body("abc".getBytes())
我一直在用这个把头撞到墙上,上传文本文件没问题,但是当我将 zip 存档上传到我的 blob 存储时 -> 它已损坏,下载后无法打开。 对原始文件与通过 Azure 的文件进行十六进制比较(下图)显示发生了一些细微的替换,但我找不到 change/corruption 的来源。 我试过强制 UTF-8/Ascii/UTF-16,但发现 UTF-8 可能是正确的,none 已经解决了这个问题。 我也尝试过不同的 http 库,但得到了相同的结果。 部署环境强制unirest,无法使用微软API(貌似没问题)
package blobQuickstart.blobAzureApp;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.Base64;
import org.junit.Test;
import kong.unirest.HttpResponse;
import kong.unirest.Unirest;
public class WhosebugExample {
@Test
public void uploadSmallZip() throws Exception {
File testFile = new File("src/test/resources/zip/simple.zip");
String blobStore = "secretstore";
UploadedFile testUploadedFile = new UploadedFile();
testUploadedFile.setName(testFile.getName());
testUploadedFile.setFile(testFile);
String contentType = "application/zip";
String body = readFileContent(testFile);
String url = "https://" + blobStore + ".blob.core.windows.net/naratest/" + testFile.getName() + "?sv=2020-02-10&ss=b&srt=o&sp=c&se=2021-09-07T20%3A10%3A50Z&st=2021-09-07T18%3A10%3A50Z&spr=https&sig=xvQTkCQcfMTwWSP5gXeTB5vHlCh2oZXvmvL3kaXRWQg%3D";
HttpResponse<String> response = Unirest.put(url)
.header("x-ms-blob-type", "BlockBlob").header("Content-Type", contentType)
.body(body).asString();
if (!response.isSuccess()) {
System.out.println(response.getBody());
throw new Exception("Failed to Upload File! Unexpected response code: " + response.getStatus());
}
}
private static String readFileContent(File file) throws Exception {
InputStream is = new FileInputStream(file);
ByteArrayOutputStream answer = new ByteArrayOutputStream();
byte[] byteBuffer = new byte[8192];
int nbByteRead;
while ((nbByteRead = is.read(byteBuffer)) != -1)
{
answer.write(byteBuffer, 0, nbByteRead);
}
is.close();
byte[] fileContents = answer.toByteArray();
String s = Base64.getEncoder().encodeToString(fileContents);
byte[] resultBytes = Base64.getDecoder().decode(s);
String encodedContents = new String(resultBytes);
return encodedContents;
}
}
请帮忙!
byte[] resultBytes = Base64.getDecoder().decode(s);
String encodedContents = new String(resultBytes);
您正在从包含二进制数据的字节数组创建字符串。字符串仅用于可打印字符。你做多个毫无意义的encoding/decoding只是占用更多的内存。
如果内容是 ZIP 格式,它是二进制的,只是 return 字节数组。或者您可以对内容进行编码,但是您应该 return 对内容进行编码。作为一个弱点,您在内存中完成所有操作,限制了内容的潜在大小。
默认情况下,Unirest 文件处理程序将强制使用多部分正文 - Azure 不支持。
一个Byte Array可以直接这样提供:https://github.com/Kong/unirest-java/issues/248
Unirest.put("http://somewhere")
.body("abc".getBytes())