2013-06-27 113 views
1

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

//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(); 
    } 
} 

您之前是否遇到过这种情况?

回答

3

显然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(); 
    } 
} 
1

只是好奇,但你如何重新命名一个正式不存在的文件(因为你还在写作)?

解决方法是在文件完成后重命名。也就是说,当你调用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(); 
    } 
} 
+0

它仍然没有工作... – ngrislain

+0

@ngrislain什么不起作用?你在日志中看到异常吗? –

+0

它不移动文件。但我找到了解决方案。在本地FS上,重命名会在中间目录不存在时创建它们。我刚刚添加了一个fileSystem.mkdir()。 – ngrislain

相关问题