当前位置: 首页 > 知识库问答 >
问题:

使用Java将文件写入Google云存储后,不会删除临时文件

井旺
2023-03-14

我正在使用Hadoop GCS Connector 3-2.2.2和google云存储版本1.113.14将数据写入谷歌云存储上的文件。

我有一个文件类,它有一个写方法,返回一个输出流如下使用hadoop类:

protected FileSystem fs;
protected Path path;

public File(String path) {
    this.path = new Path(path);
    Configuration conf = new Configuration();
    conf.set("fs.defaultFS", fsURL);
    conf.setBoolean("dfs.support.append", true);
    conf.setInt("ipc.client.connect.max.retries.on.timeouts", 2);
    this.fs = FileSystem.newInstance(conf);
}

@Override
public OutputStream write(boolean overwriteIfExists) throws IOException {
    return fs.create(path, overwriteIfExists);
}

FS是org.apache.hadoop.fs.FileSystem的实例;path是导入org.apache.hadoop.fs.Path的实例;

我甚至尝试使用谷歌云存储sdk来实现我的写方法:

@Override
public OutputStream write(boolean overwriteIfExists, boolean create) throws IOException {
    if (!overwriteIfExists && exists()) {
        throw new IOException("File already exists");
    }

    if (overwriteIfExists && exists()) {
        delete();
    } // If will write it will mean a new file

    BlobId blobId = BlobId.of(bucketName, objectName);
    BlobInfo blobInfo = BlobInfo.newBuilder(blobId).build();
    
    WriteChannel writeChannel = storage.writer(blobInfo);
    writeChannel.setChunkSize(64 * 1024 * 1024);

    return Channels.newOutputStream(writeChannel);
}

我的应用程序的其他部分可以创建我的文件类的实例并写入OutputStream,下面是如何测试/模拟写入的示例:

public void write() {
try {
  File file = File.newInstance("dir/someFileName");
  try (DataOutputStream os = new DataOutputStream(new BufferedOutputStream(file.write(true), this.bufferSize))) {
    long i;
    for (i = 0L; i < 4096; i++) {
      os.write(String.format("some arbitrary string %d\n", new Object[] { Long.valueOf(i) }).getBytes());
    } 
  } catch (Throwable t) {
    System.out.println("Couldn't write file");
  } 
} catch (IOException e) {
  System.out.println("Couldn't write file");
} 

}

写入后,当我使用gsutil ls dir/检查写入的文件时,我希望只找到我刚才创建的一个文件,但我得到了两个本应删除的额外临时文件(具有GCS\u SYNCABLE\u TEMPFILE前缀)

gs://dir/\u GCS\u SYNCABLE\u TEMPFILE\u someFileName。txt。0.24fccb78-8cea-45fd-852d-ed9385e4246b gs://dir/\u GCS\u SYNCABLE\u TEMPFILE\u someFileName。txt。0.cf132710-9d71-4939-a5d8-02b0279cdf3c gs://dir/someFileName。文本

我是否需要进行一些配置,或者为什么不删除这些临时文件?

或者这可能是任何相关jar中的不兼容?我正在使用以下版本的谷歌相关依赖项:

  • 组:'组织。阿帕奇。hadoop',名称:'hadoop common',版本:'3.2.0'
  • 组:'组织。阿帕奇。hadoop',名称:'hadoop hdfs',版本:'3.2.0'
  • 组:'组织。阿帕奇。hadoop,名称:“hadoop hdfs客户端”,版本:“3.2.0”
  • 组:'com.google.云bigdataoss,名称:“gcs连接器”,版本:“hadoop3-2.2.2”
  • 组:'com.google.api客户端,名称:“谷歌api客户端”,版本:“1.31.3”
  • 组:'com.google.云,名称:“谷歌云核心”,版本:“1.93.4”
  • 组:'com.google.云,名称:“谷歌云核心http”,版本:“1.93.4”
  • 组:'com.google.云,名称:“谷歌云存储”,版本:“1.106.0”
  • 组:'com.google.http客户端,名称:“谷歌http客户端”,版本:“1.38.0”
  • 组:'com.google.http客户端,名称:“google-http-client-jackson2”,版本:“1.38.0”

共有1个答案

应俭
2023-03-14
  • OutputStream在GitHub链接中提供的源代码中公开提供
  • 临时文件的行为是客户端库的属性,而不是直接由GCS决定
  • 随附的文档链接提供了详细信息,但总体概述如下:

在第一次调用hsync()、sync()或close()之前,此通道的行为与基本的不可同步通道相同,直接写入目标文件。在第一次调用hsync()/sync()时,将提交目标文件,并使用隐藏文件前缀(下划线)创建一个新的临时文件,该文件带有一个附加后缀,该后缀对于序列中的每个后续临时文件都不同;在此期间,读取器可以读取提交到目标文件的数据,但不能读取自上次hsync()调用以来写入临时文件的字节。在每次后续的hsync()/sync()调用中,临时文件关闭(),组成目标文件,然后删除,并以新文件名打开一个新的临时文件以供进一步写入。警告:每个hsync()/sync()都需要许多顺序发生的底层读取和变异请求,因此预期延迟相当高。

如果中途发生错误,可能有一个或多个临时文件未能被清理,并且需要人工干预来发现和删除任何此类未使用的文件。在这种情况下,在最近成功的hsync()之前写入的数据是持久和安全的。

文件未关闭的可能原因是您未关闭代码库中的流或出现错误。一步一步地调试代码,检查流是否正确关闭,文件是否被删除,如图所示

注意:由于代码是异步的,您需要确保执行删除的线程正在运行。

 类似资料:
  • 我正在尝试建立一个基于python的基本谷歌应用引擎站点,允许用户将文件上传到谷歌云存储(主要是图像) 我已经阅读了JSON API和GCS客户端库概述(以及blobstore等)的文档,但仍然没有很好地了解哪种方法是最好的以及它们之间的关系。如果有人能概述一下,或者给我指出一些我可以查看的资源,那就太好了 此外,任何相关的示例代码都会非常有用。我已经能够在此处运行上载示例,但不确定它们是否对应用

  • 问题内容: 我正在使用FileWriter写入文件,并注意到即使删除了文件(进程外),FileWriter也不会引发任何异常。 这正常吗? 问题答案: 这取决于您的操作系统: 在Windows上,通常无法删除打开的文件。 在Unix上,完全可以接受删除打开的文件并继续写入(或从中读取)文件。删除文件后,它将不再具有目录条目。但是,其内容将继续存在于磁盘上,直到关闭该文件。一旦所有引用该文件的打开句

  • 如何删除azure blob存储中的文件夹。当我试图删除文件夹时,我看到以下错误: com.azure.storage.blob.models.BloStorageExctive:状态代码409,"在非空目录上不允许进行此操作。请求ID:195b3f66-601e-0071-2edb-094790000000时间:2022-01-15T06:47:55.8443865Z" 在sun.reflect

  • 我正在尝试使用pyspark来分析我在数据砖笔记本上的数据。Blob 存储已装载到数据砖群集上,在分析后,希望将 csv 写回 blob 存储。由于 pyspark 以分布式方式工作,csv 文件被分解为小块并写入 Blob 存储。如何克服这个问题,并在我们使用pyspark进行分析时在blob上编写为单个csv文件。谢谢。

  • 我已经使用谷歌云控制台将几个文件上传到了谷歌云存储的同一个文件夹中。我现在想把几个文件移动到谷歌云存储中的一个新创建的文件夹中,但我无法通过谷歌云控制台看到如何做到这一点。我通过上的命令提示符指令找到了移动文件的说明。但是,我对命令行界面不满意,并且无法在我的机器上使用。 有没有办法通过谷歌云控制台将谷歌云存储中的文件从一个文件夹移动到另一个文件夹?

  • 我有一个要求,我需要上传文件到谷歌云存储(他拥有并完全维护它)桶。 这个谷歌云存储桶是由我的客户创建的。 我是谷歌云的新手,有亚马逊S3的经验。我在服务器上运行SSI,以将事务数据加载到平面文件。 我为谷歌云创建了一个示例帐户,并安装了谷歌SDK。我可以通过gsutil手动上传文件。 我的问题是 > 我应该如何建议我的客户共享凭据? 我如何连接到谷歌云存储与提供凭据独立? 如何通过以上两个步骤将文