繁体   English   中英

使用Java中的Azure函数将文件从浏览器上传到Azure Blob存储

[英]Uploading file from browser to azure blob storage using azure function in java

我正在尝试通过azure函数将文件上传到Azure存储。 我成功上传了纯文本文件,但是其他任何类型的文件都损坏了。 我观察到的是,我收到的字节小于实际大小(bodyLength <contentLength)。

我试图将请求数据类型更改为

HttpRequestMessage<'Optional<'byte[]>>
HttpRequestMessage and Byte[]
字节[]输入中所报告的那样,抛出的错误无法转换为字符串错误#239 [^]

  @FunctionName(“ UploadFile”)\n     公开HttpResponseMessage运行(@HttpTrigger(name =“ req”,方法= {HttpMethod.GET,\n             HttpMethod.POST},authLevel = AuthorizationLevel.FUNCTION)HttpRequestMessage(Optional(String >> request,\n             最终的ExecutionContext上下文)\n             引发InvalidKeyException,URISyntaxException,StorageException,IOException { 

\n\n CloudStorageAccount storageAccount = CloudStorageAccount.parse(_storageConnString); CloudBlobClient blobClient = storageAccount.createCloudBlobClient(); CloudBlobContainer blobContainer = blobClient.getContainerReference(_containerName); CloudBlockBlob blob = blobContainer.getBlockBlobReference(fileName); try { String body = request.getBody().get(); long bodyLength = body.length(); String contentLength = request.getHeaders().get("content-length"); InputStream inputStream = new ByteArrayInputStream(body.getBytes()); blob.upload(inputStream, Integer.parseInt(bodyLength)); } catch (Exception ex) { return request.createResponseBuilder(HttpStatus.BAD_REQUEST).body(ex.getMessage()).build(); } return request.createResponseBuilder(HttpStatus.OK).body("File uploaded successfully").build(); }

我的要求是通过azure函数将大文件上传到存储。 任何帮助,我们将不胜感激。

这似乎是因为您需要将原始流上传到Blob存储。 我以前将其上传到byte [],但也失败了。 我使用了C#,遇到了与您相同的问题。 问题在这里:

String body = request.getBody().get(); 
InputStream inputStream = new ByteArrayInputStream(body.getBytes());
blob.upload(inputStream, Integer.parseInt(bodyLength));

在C#中,我使用blob.UploadFromStreamAsync(req.Body); 然后问题消失了。 您可以检查Java是否具有类似的方法。

经过测试,这是由请求标头引起的。 从这个类似的答案中 ,您可能发现必须发送带有multipart/form-data标头的正文。 如果没有标题,我将得到与您相同的结果。

设置content-type标头后,长度将相同。

在此处输入图片说明

但是,即使长度相等,但是如果您发送的不是txt文件而是pdf或图像等文件,则Java Azure Function会丢失一些字节,这与我回答OP更新时的情况相同参考。

因此,如果您上传其他类型的文件,解决方案是将文件转换为base64字符串,然后发布到Function,然后在函数中转换base64字符串,然后上传到blob。

byte[] scanBytes = Base64.getDecoder().decode(base64 string from request);
blob.UploadFromByteArray(scanBytes , 0, scanBytes.Length);

节点 :如果要发布大文件,应该知道最大请求大小(100MB),并且无法更改。 Github问题 但是在本地环境中最大的声明是10MB〜20MB,我测试本地是否出现此限制。 因此最好不要发布太大的文件。

在此处输入图片说明

检查了官方教程 ,但遗憾的是,没有任何帮助。 该文档太旧,甚至有一些错误。

通过本地测试,我发现即使有时您设置了正确的content-type标头,azure java函数也无法按预期处理不同的内容。

在大多数情况下,它将内容视为纯文本。 在大多数情况下,如果没有不可读的特殊字符,那将没有问题。

但是,对于其他文件,例如:图像文件,二进制文件和其他可能包含不可读特殊字符的文件,Azure函数似乎只是忽略了一些不可读字符。

为了解决这个问题,您可以将请求内容类型标头设置为application/octet-stream ,这表示它是未知格式。 这样,Azure函数将保留所有内容字节。

但是,乔治的方法(使用multipart / form-data)也可以工作。 因为如果content-type是multipart / form-data,则系统还将保留所有内容(这是技巧),因此您可以使用定义的边界字符串获取每个部分。 此方法的使用场景是以http格式上传文件。 您只需要将enctype设置为“ multipart / form-data”

<FORM method="POST" action="....." enctype="multipart/form-data">
    <INPUT type="file" name="pic">
    <INPUT type="submit" value="submit" name="submit">
</FORM>

因此,如果只想通过编程将文件发布到Azure函数,请将内容类型设置为application / octet-stream。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM