- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在尝试使用 azure storage Rest api 来推送 block blob 类型,但问题是要事先了解内容长度以便上传。
对于需要在没有可用长度信息的情况下中继 inputStream 的情况,我们是否有解决方法。
String accesskey = "accesskey";
String storageAccount = "storageAccount";
String containerName = "containerName";
String workgroupId = UUID.randomUUID().toString();
String objectId = "1." + UUID.randomUUID().toString();
String blobName = getAzureAccessKey(containerName, workgroupId, objectId);
String version = "2018-03-28";
String putData = "testData";
SimpleDateFormat fmt = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss");
fmt.setTimeZone(TimeZone.getTimeZone("GMT"));
String currentDate = fmt.format(Calendar.getInstance().getTime()) + " GMT";
String urlResource = "/"+ Paths.get(storageAccount, containerName, blobName).toString();
String headerResource = "x-ms-blob-type:BlockBlob\nx-ms-date:" + currentDate + "\nx-ms-version:" + version;
String putUrl = "https://" + storageAccount + ".blob.core.windows.net/" + containerName + "/" + blobName;
System.out.println(putUrl);
String newline = "\n";
List listToSign = Lists.newArrayList();
listToSign.add("PUT");
listToSign.add("");
listToSign.add("");
listToSign.add("");
listToSign.add("");
listToSign.add("application/octet-stream");
listToSign.add("");
listToSign.add("");
listToSign.add("");
listToSign.add("");
listToSign.add("");
listToSign.add("");
listToSign.add(headerResource);
listToSign.add(urlResource);
String stringToSign = String.join(newline, listToSign);
Base64 base64 = new Base64();
System.out.println(stringToSign);
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(new SecretKeySpec(base64.decode(accesskey), "HmacSHA256"));
String authKey = new String(base64.encode(mac.doFinal(stringToSign.getBytes("UTF-8"))));
String authHeader = "SharedKey " + storageAccount + ":"+ authKey;
System.out.println(authHeader);
InputStreamEntity entity = new InputStreamEntity(
new ByteArrayInputStream(putData.getBytes(StandardCharsets.UTF_8)), -1,
ContentType.APPLICATION_OCTET_STREAM);
// set chunked transfer encoding ie. no Content-length
entity.setChunked(true);
HttpPut httpPut = null;
try {
DefaultHttpClient httpClient = new DefaultHttpClient();
httpClient.removeRequestInterceptorByClass(org.apache.http.protocol.RequestContent.class);
httpPut = new HttpPut(putUrl);
httpPut.setHeader("Host", storageAccount + ".blob.core.windows.net");
httpPut.setHeader("Transfer-Encoding","chunked");
//httpPut.setHeader("Content-Length","0");
httpPut.setHeader("Content-Type","application/octet-stream");
httpPut.addHeader("x-ms-blob-type", "BlockBlob");
httpPut.addHeader("x-ms-date", currentDate);
httpPut.addHeader("x-ms-version", version);
httpPut.addHeader("Authorization",authHeader);
httpPut.setEntity(entity);
System.out.println("Request Headers");
for (Header header : httpPut.getAllHeaders()) {
System.out.println(header.getName() + ":" + header.getValue());
}
HttpResponse response = httpClient.execute(httpPut);
System.out.println(response.getStatusLine());
for (Header header: response.getAllHeaders()) {
System.out.println(header.getName()+":"+ header.getValue());
}
// Read the contents of an entity and return it as a String.
String content = EntityUtils.toString(response.getEntity());
System.out.println(content);
} finally {
if(httpPut != null ){
httpPut.releaseConnection();
}
}
服务器响应
HTTP Error 400. There is an invalid content length or chunk length in the request.
如果我将内容长度设置为签名和 header 信息的一部分,则上述代码有效。
最佳答案
我们可以使用ByteArrayEntity
来获取内容长度,而不是使用InputStreamEntity
这是一个简单的演示供您引用:
FileInputStream fileInputStream=null;
ByteArrayOutputStream bos = null ;
try {
fileInputStream=new FileInputStream("D:/Test/Test.txt");
bos = new ByteArrayOutputStream();
byte[] bytes=new byte[102400];
int x=0;
while ((x=fileInputStream.read(bytes))!= -1){
bos.write(bytes,0,x);
}
byte[] data = bos.toByteArray();
org.apache.http.entity.ByteArrayEntity byteArrayEntity=new ByteArrayEntity(data);
int contentLength=data.length;
} catch (Exception e) {
e.printStackTrace();
}
正如卢兆兴上面所说,我们可以使用Java SDK来实现这一点,这里有使用Java SDK的demo供大家引用:
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.net.URISyntaxException;
import java.security.InvalidKeyException;
import com.microsoft.azure.storage.CloudStorageAccount;
import com.microsoft.azure.storage.blob.CloudBlobClient;
import com.microsoft.azure.storage.blob.CloudBlobContainer;
import com.microsoft.azure.storage.blob.CloudBlockBlob;
import com.microsoft.azure.storage.blob.ListBlobItem;
public class Main {
public static final String ConnString="DefaultEndpointsProtocol=https;AccountName=xxxxxxxxb;AccountKey=O7xxxx8e86XQSy2vkvSi/x/e9l9FhLqxxxxjkly1DsQPYY5dF2JrAVxxxxo29ZrrGJA==;EndpointSuffix=core.windows.net";
public static void main(String[] args) {
// TODO Auto-generated method stub
uploadBlob("mycontainer","TechTalk.pptx","E:\\Test\\TechTalk.pptx");
System.out.println("Success");
}
public static void uploadBlob(String containerName, String blobName,String filePath) {
CloudStorageAccount account = null;
CloudBlobContainer container = null;
try {
account = CloudStorageAccount.parse(ConnString);
CloudBlobClient client = account.createCloudBlobClient();
container = client.getContainerReference(containerName);
container.createIfNotExists();
CloudBlockBlob cloudBlockBlob = container.getBlockBlobReference(blobName);
FileInputStream fileinputStream=new FileInputStream(filePath);
cloudBlockBlob.upload(fileinputStream, fileinputStream.available());
}catch(Exception ex) {
ex.printStackTrace();
}
}
}
我们可以通过以下地址获取 Java SDK:Java SDK
关于java - 用于 block Blob 的 Azure 存储服务 REST API : Content Length Issue,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51256040/
我找到了以下代码片段: length = length and length or len(string) 在我看来,这应该等同于: length = length or len(string) 我能
当我使用 numpy.shape() 检查数组的形状时,我有时会得到 (length,1) 有时会得到 (length,)。看起来区别在于列向量与行向量......但它似乎并没有改变数组本身的任何内容
我正在学习 Java,有一个简单的问题。 在设置类的示例中,我看到了这一点: length >= 0 ? length : length * -1 这是什么意思? 谢谢。 最佳答案 这是一种骇人听闻的
我在阅读有关在 Ruby 中重新定义方法有多么容易的文章时遇到了以下问题: class Array alias :old_length :length def length old_l
例如在下面的代码中a和b和c是相等的。 EditText editText; editText = (EditText) findViewById(R.id.edttxt); editText.set
在昨天教授我的 JavaScript 类(class)时,我和我的学生遇到了一些有趣的功能,我认为这些功能可能值得在一个问题和我得出的答案中捕捉到。 在 Chrome 的 JS 控制台中输入 Arra
这个问题在这里已经有了答案: How can I get the size of an array, a Collection, or a String in Java? (3 个回答) 3年前关闭。
这个问题在这里已经有了答案: length and length() in Java (8 个答案) 关闭 6 年前。 我注意到在计算数组的长度时,你会这样写: arrayone.length; 但
console.log(this.slides.length()); 打印 Cannot read property 'length' of undefined.在 setTimeout 为 100
在搜索stackoverflow问题时,我发现了此链接: Error in file.download when downloading custom file。 但是,我的情况有些不同(我认为):
这个问题已经有答案了: Why does R use partial matching? (1 个回答) 已关闭 8 年前。 大家。我刚刚开始使用 swirl 学习 R 编程。 我刚刚了解到seq 。
这个问题已经有答案了: Why does R use partial matching? (1 个回答) 已关闭 8 年前。 大家。我刚刚开始使用 swirl 学习 R 编程。 我刚刚了解到seq 。
这个问题已经有答案了: How can I get the size of an array, a Collection, or a String in Java? (3 个回答) 已关闭 9 年前。
我有一个大数组,其中包含所有类型( bool 值,数组,null,...),并且我正在尝试访问它们的属性arr[i].length,但有些其中显然没有长度。 我不介意那些缺少长度的人是否返回未定义(我
我在对象的属性中有一些文本。我正在测试对象的属性中是否有要显示的文本;如果没有,那么我显示“-”而不是空白。看起来没有什么区别: if (MyObject.SomeText && MyObject.S
这个问题在这里已经有了答案: 关闭 10 年前。 Possible Duplicate: Why is String.length() a method? Java - Array's length
这个问题在这里已经有了答案: obj.length === +obj.length in javascript (4 个答案) 关闭 9 年前。 我一直在读underscore.js源代码并在 _.
#include using std::cout; using std::cin; using std::string; int main(){ cout > name; cout
我正在细读 underscore.js annotated source当我遇到这个时: if (obj.length === +obj.length) {...} 我现在从this stackove
我正在查看 dotnet 运行时中的一些代码,我注意到不是这样写的: if (args.Length > 0) 他们使用这个: if (args is { Length: > 0}) 你知道用第二种方
我是一名优秀的程序员,十分优秀!