Java 在HDFS上重命名文件可以在本地模式下工作,但不能在群集模式下工作

Java 在HDFS上重命名文件可以在本地模式下工作,但不能在群集模式下工作,java,hadoop,hdfs,Java,Hadoop,Hdfs,我有一个对象负责打开HDFS上的文件进行写入。调用close()方法后,此对象将重命名它刚刚编写的文件。 该机制在本地模式下运行时有效,但在群集模式下无法重命名文件 //Constructor public WriteStream() { path = String.format("in_progress/file"); try { OutputStream outputStream = fileSystem.create(new Path(hdfs_path+p

我有一个对象负责打开HDFS上的文件进行写入。调用
close()
方法后,此对象将重命名它刚刚编写的文件。 该机制在本地模式下运行时有效,但在群集模式下无法重命名文件

//Constructor
public WriteStream() {
    path = String.format("in_progress/file");
    try {
        OutputStream outputStream = fileSystem.create(new Path(hdfs_path+path), new Progressable() {public void progress() { System.out.print("."); }
            });
        writer = new BufferedWriter(new OutputStreamWriter(outputStream));
    } catch (IOException e) {
        e.printStackTrace();
    }
}

public void close() {
    String newPath = String.format("%s_dir/%s_file", date, timestamp);
    try {
        fileSystem.rename(new Path(hdfs_path+path), new Path(hdfs_path+newPath));
        writer.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

你以前有过这样的经历吗?

只是好奇,但是你怎么能重命名一个官方不存在的文件(因为你当时还在写)

修复方法是在文件完成后重命名。也就是说,当您调用close方法时

因此,您的代码应该如下所示:

public void close() {
    String newPath = String.format("%s_dir/%s_file", date, timestamp);
    try {
        writer.close();
        fileSystem.rename(new Path(hdfs_path+path), new Path(hdfs_path+newPath));
    } catch (IOException e) {
        e.printStackTrace();
    }
}

只是好奇,但是你怎么能重命名一个官方不存在的文件(因为你当时还在写)

修复方法是在文件完成后重命名。也就是说,当您调用close方法时

因此,您的代码应该如下所示:

public void close() {
    String newPath = String.format("%s_dir/%s_file", date, timestamp);
    try {
        writer.close();
        fileSystem.rename(new Path(hdfs_path+path), new Path(hdfs_path+newPath));
    } catch (IOException e) {
        e.printStackTrace();
    }
}

显然
FileSystem.rename(Path)
在本地模式下执行时会在路径上创建丢失的目录,但在集群模式下运行时不会。 此代码可在两种模式下工作:

public void close() {
    String dirPath = String.format("%s_dir/", date, timestamp);
    String newPath = String.format("%s_dir/%s_file", date, timestamp);
    try {
        fileSystem.mkdir(new Path(hdfs_path+dirPath));
        fileSystem.rename(new Path(hdfs_path+path), new Path(hdfs_path+newPath));
        writer.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

显然
FileSystem.rename(Path)
在本地模式下执行时会在路径上创建丢失的目录,但在集群模式下运行时不会。 此代码可在两种模式下工作:

public void close() {
    String dirPath = String.format("%s_dir/", date, timestamp);
    String newPath = String.format("%s_dir/%s_file", date, timestamp);
    try {
        fileSystem.mkdir(new Path(hdfs_path+dirPath));
        fileSystem.rename(new Path(hdfs_path+path), new Path(hdfs_path+newPath));
        writer.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

@ngrislain什么不起作用?您是否在日志中看到异常?它不会移动文件。但我找到了解决办法。在本地FS上,rename会在中间目录不存在时创建它们。我刚刚添加了一个fileSystem.mkdir()。@ngrislain什么不起作用?您是否在日志中看到异常?它不会移动文件。但我找到了解决办法。在本地FS上,rename会在中间目录不存在时创建它们。我刚刚添加了一个fileSystem.mkdir()。