2015-11-16 72 views
2

我想從java代碼運行一個命令兩個合併到文件! 的命令是:從Java代碼運行Linux Hadoop fs命令

hadoop fs -cat /user/clouder/Index_1/part-r-00000 /user/cloudera/Index_2/part-r-00000 | hadoop fs -put - /user/cloudera/mergedfile 

該命令運行完全上Cloudera的終端,但是當我運行從Java代碼是相同的,它顯示在控制檯上的合併的內容,但不創建在HDFS指定路徑mergedfile。如果mergedfile已經存在,那麼它輸出文件的早期數據,但不輸出新合併的數據,如果文件不存在,則不會創建新文件。在終端上運行的上述命令創建新文件的情況下,如果不存在,則會導致文件錯誤存在。

我的Java代碼如下:

process p; 

try{ 

     p =Runtime.getRuntime().exec("hadoop fs -cat /user/cloudera/Index_1/part-r-00000 /user/cloudera/Index_2/part-r-00000 | hadoop fs -put - /user/cloudera/mergedfile"); 
     BufferredReader br=new BufferedReader(new InputStreamReader(p.getInputStream())); 

     while(s=br.readLine())!=null) 
     { 
      System.out.println(s); 
     } 
    } 

catch(Exception e) 
    { 
     System.out.println(e.getMessage()); 
    } 

我的目的是替代,如果有一個現有的文件,或如果不從Java代碼中存在的創建一個新的文件。

+0

你爲什麼不使用[HDFS API(https://hadoop.apache.org/docs/r2.6.2/ API /組織/阿帕奇/的Hadoop/FS/FileSystem.html)? – gerosalesc

回答

1

要用Java運行HDFS命令,您應該使用HDFS Java API。下面是如何用它來合併此文件code sample from javased.com

/** 
* @param inputFiles a glob expression of the files to be merged 
* @param outputFile a destination file path 
* @param deleteSource delete source files after merging 
* @return 
* @throws IOException 
*/ 
private static Path mergeTextFiles(String inputFiles,String outputFile,boolean deleteSource,boolean deleteDestinationFileIfExist) throws IOException { 
    JobConf conf=new JobConf(FileMerger.class); 
    FileSystem fs=FileSystem.get(conf); 
    Path inputPath=new Path(inputFiles); 
    Path outputPath=new Path(outputFile); 
    if (deleteDestinationFileIfExist) { 
    if (fs.exists(outputPath)) { 
     fs.delete(outputPath,false); 
     sLogger.info("Warning: remove destination file since it already exists..."); 
    } 
    } 
else { 
    Preconditions.checkArgument(!fs.exists(outputPath),new IOException("Destination file already exists...")); 
    } 
    FileUtil.copyMerge(fs,inputPath,fs,outputPath,deleteSource,conf,FILE_CONTENT_DELIMITER); 
    sLogger.info("Successfully merge " + inputPath.toString() + " to "+ outputFile); 
    return outputPath; 
} 

我這種情況下,你將需要複製你要合併到1個目錄事先使用FileUtil class的文件。後來你會採取這樣的目錄路徑,並把它作爲了inputFiles參數:

JobConf conf=new JobConf(FileMerger.class); 
FileSystem fs=FileSystem.get(conf); 
String tmpDir = "/user/cloudera/tmp_dir"; 
Path[] paths = {new Path("/user/clouder/Index_1/part-r-00000"), new Path("/user/clouder/Index_2/part-r-00000")}; 
Path pathToInputs = FileUtil.copy(fs, paths, fs, new Path(tmpDir)); 
mergeTextFiles(tmpDir, "/user/cloudera/mergedfile", false, true); 
+0

感謝Rosales,我正在尋找同樣的東西,千萬不要在java中使用HDFS API!我現在就試試這個,謝謝你的代碼。 – A8H1