我是Google Cloud Platform的新手。我正在尝试逐行读取Google Cloud Storage(通过服务帐户密钥访问的非公共存储桶)中存在的CSV文件,该文件大约为1GB。
我找不到任何选项来逐行读取Google Cloud Storage(GCS)中存在的文件。我只看到按块大小/字节大小读取选项。由于我正在尝试读取CSV,因此我不希望使用按块大小读取,因为它可能会在读取时拆分记录。
到目前为止已尝试的解决方案: 尝试将GCS中存在的CSV文件中的内容复制到临时本地文件中,并使用以下代码读取临时文件。下面的代码按预期工作,但我不想将大文件复制到本地实例。相反,我想从GCS逐行读取。
StorageOptions options =
StorageOptions.newBuilder().setProjectId(GCP_PROJECT_ID)
.setCredentials(gcsConfig.getCredentials()).build();
Storage storage = options.getService();
Blob blob = storage.get(BUCKET_NAME, FILE_NAME);
ReadChannel readChannel = blob.reader();
FileOutputStream fileOuputStream = new FileOutputStream(TEMP_FILE_NAME);
fileOuputStream.getChannel().transferFrom(readChannel, 0, Long.MAX_VALUE);
fileOuputStream.close();
请提出方法。
答案 0 :(得分:2)
最简单的方法之一可能是使用google-cloud-nio
软件包,它是您已经在使用的google-cloud-java库的一部分:https://github.com/googleapis/google-cloud-java/tree/v0.30.0/google-cloud-contrib/google-cloud-nio
它将Google Cloud Storage集成到Java的NIO中,因此一旦启动并运行,就可以像引用文件或URI一样引用GCS资源。例如:
Path path = Paths.get(URI.create("gs://bucket/lolcat.csv"));
try (Stream<String> lines = Files.lines(path)) {
lines.forEach(s -> System.out.println(s));
} catch (IOException ex) {
// do something or re-throw...
}
答案 1 :(得分:2)
布兰登·雅伯(Brandon Yarbrough)是对的,在回答中补充:
如果您使用gcloud登录并使用自己的凭据登录,那么Brandon的代码将起作用:google-cloud-nio
将使用您的登录信息来访问文件(即使它们不是公开的,也可以使用)。
如果您希望通过软件完成全部操作,则可以使用以下代码从本地文件读取凭据,然后从Google Cloud访问文件:
String myCredentials = "/path/to/my/key.json";
CloudStorageFileSystem fs =
CloudStorageFileSystem.forBucket(
"bucket",
CloudStorageConfiguration.DEFAULT,
StorageOptions.newBuilder()
.setCredentials(ServiceAccountCredentials.fromStream(
new FileInputStream(myCredentials)))
.build());
Path path = fs.getPath("/lolcat.csv");
List<String> lines = Files.readAllLines(path, StandardCharsets.UTF_8);
edit:您不想一次读取所有行,因此不要使用realAllLines
,但是一旦拥有Path
,就可以使用上面讨论的任何其他技术来读取仅需要文件的一部分:您可以一次读取一行或获取一个Channel
对象。
答案 2 :(得分:1)
由于我正在执行批处理,因此我在ItemReader的init()方法中使用以下代码,该代码以@PostConstruct进行批注。在我的ItemReader的read()中,我正在构建一个列表。列表的大小与块大小相同。这样,我可以基于我的chunkSize读取行,而不是一次读取所有行。
StorageOptions options =
StorageOptions.newBuilder().setProjectId(GCP_PROJECT_ID)
.setCredentials(gcsConfig.getCredentials()).build();
Storage storage = options.getService();
Blob blob = storage.get(BUCKET_NAME, FILE_NAME);
ReadChannel readChannel = blob.reader();
BufferedReader br = new BufferedReader(Channels.newReader(readChannel, "UTF-8"));