Quarkus上传至Azure Blob Storage异常:文件大小显示为0
问题根源
你遇到的Blob大小为0的问题,核心原因是InputStream只能被读取一次。在本地保存文件的代码块里,你已经把formData.getFile()返回的输入流读完了,流的指针跑到了末尾。后面上传Azure时再用同一个流,已经没有数据可以读取,自然就生成了0字节的文件。
解决办法
这里给你两种可行的修复方案:
方案1:重置输入流(限支持的流类型)
如果formData.getFile()返回的流支持标记和重置(比如ByteArrayInputStream),可以在本地保存后把流指针重置到开头:
try { Log.info("Actual file size: " + formData.file.available()); File localFile = new File("testFiles", uniqueFileName); try (FileOutputStream out = new FileOutputStream(localFile)) { BinaryData binaryData = BinaryData.fromStream(formData.getFile(), formData.getFileSize()); byte[] bytes = binaryData.toBytes(); out.write(bytes); // 重置流指针到起始位置 formData.getFile().reset(); } Log.info("File saved locally: " + localFile.getAbsolutePath()); } catch (IOException e) { Log.error("Failed to save file locally", e); }
⚠️ 注意:不是所有InputStream都支持reset(),如果运行时抛出IO异常,说明这个流不支持该操作,换方案2就行。
方案2:提前缓存文件字节数组(通用可靠)
先把文件内容一次性读取到字节数组里,本地保存和Azure上传都复用这个数组,彻底避免流只能读一次的问题:
byte[] fileBytes = null; try { Log.info("Actual file size: " + formData.file.available()); // 把流内容全读到字节数组 fileBytes = formData.getFile().readAllBytes(); File localFile = new File("testFiles", uniqueFileName); try (FileOutputStream out = new FileOutputStream(localFile)) { out.write(fileBytes); } Log.info("File saved locally: " + localFile.getAbsolutePath()); } catch (IOException e) { Log.error("Failed to save file locally", e); } Mono<BlockBlobItem> blockBlobItem = blobServiceAsyncClient.createBlobContainerIfNotExists("images") .map(blobContainerAsyncClient -> blobContainerAsyncClient.getBlobAsyncClient(uniqueFileName)) .flatMap(blobAsyncClient -> { // 用缓存的字节数组创建BinaryData BinaryData binaryData = BinaryData.fromBytes(fileBytes); Log.info(binaryData.getLength()); return blobAsyncClient.upload(binaryData); });
这个方案适用于所有场景,不管流类型是什么都能正常工作。
额外提醒
如果上传的文件很大,直接把所有内容读到字节数组可能会占用过多内存。这种情况下可以先把文件写到本地临时文件,然后上传的时候从本地文件读取流,或者用ByteArrayOutputStream分批读取流内容。
内容的提问来源于stack exchange,提问作者ManuelP
相关产品推荐
相关产品推荐

