如何将Java请求对象直接转CSV并上传至Google Cloud Storage
解决方案:流式生成CSV并直接上传至Google Cloud Storage
当然可以实现跳过本地文件的流程,核心思路是在内存中生成CSV内容,然后通过流式上传直接发送到GCS,无需落地到本地磁盘。以下是修改后的完整代码:
1. 调整Controller层逻辑
整合CSV生成与上传流程,用内存流替代本地文件操作:
@PostMapping("/upload") // 注意:接收@RequestBody应使用PostMapping,原GetMapping不符合REST规范 public void getTranscriptsByDate(@RequestBody SearchRequest searchRequest) throws Exception{ log.info("Search Request {}", searchRequest); // 直接在内存生成CSV并上传至GCS uploadCsvToGcs(searchRequest); } private void uploadCsvToGcs(SearchRequest searchRequest) throws IOException { String gcsFileName = "myFile" + searchRequest.getConversationDate() + ".csv"; // 使用内存流生成CSV内容 try (ByteArrayOutputStream baos = new ByteArrayOutputStream(); CSVWriter writer = new CSVWriter(new OutputStreamWriter(baos))) { // 写入CSV表头 String[] header = { "ID", "NAME" }; writer.writeNext(header); // 写入数据行 String[] data = new String[2]; data[0] = searchRequest.getId(); data[1] = searchRequest.getName(); writer.writeNext(data); // 刷新Writer确保所有内容写入内存流 writer.flush(); // 将内存流转为InputStream,调用上传方法 try (InputStream inputStream = new ByteArrayInputStream(baos.toByteArray())) { myService.uploadFile(gcsFileName, inputStream); } } }
2. 修改MyService的上传方法
改为支持从InputStream直接上传,不再依赖本地文件路径:
public void uploadFile(String gcsFileName, InputStream inputStream) throws Exception{ // BlobId的第二个参数是GCS中的对象名称,而非本地路径 BlobId blobId = BlobId.of(bucketName, gcsFileName); BlobInfo blobInfo = BlobInfo.newBuilder(blobId).build(); // 直接从InputStream流式上传至GCS storage.createFrom(blobInfo, inputStream); }
关键优化点说明
- 内存流替代本地文件:用
ByteArrayOutputStream在内存中生成CSV,避免磁盘IO开销,提升处理效率。 - 自动资源管理:使用try-with-resources语法,确保流和Writer自动关闭,避免资源泄漏。
- 规范HTTP方法:原代码用
@GetMapping接收请求体不符合REST规范,调整为@PostMapping更合理。 - GCS对象命名:上传时指定的文件名是GCS存储桶中的对象名称,避免传入本地路径导致GCS创建不必要的嵌套目录结构。
内容的提问来源于stack exchange,提问作者Akash Sharma
相关产品推荐
相关产品推荐

