2014-11-14 107 views
7

我使用的轉換BinaryFiles(JPEG文件)映射器到一個Hadoop序列文件(HSF):如何從Hadoop序列文件獲取最後修改日期?

public void map(Object key, Text value, Context context) 
throws IOException, InterruptedException { 

    String uri = value.toString().replace(" ", "%20"); 
    Configuration conf = new Configuration(); 

    FSDataInputStream in = null; 
    try { 
     FileSystem fs = FileSystem.get(URI.create(uri), conf); 
     in = fs.open(new Path(uri)); 
     java.io.ByteArrayOutputStream bout = new ByteArrayOutputStream(); 
     byte buffer[] = new byte[1024 * 1024]; 

     while(in.read(buffer, 0, buffer.length) >= 0) { 
      bout.write(buffer); 
     } 
     context.write(value, new BytesWritable(bout.toByteArray())); 

我然後有一個第二映射器,其讀取所述HSF,從而:

public class ImagePHashMapper extends Mapper<Text, BytesWritable, Text, Text>{ 

    public void map(Text key, BytesWritable value, Context context) throws IOException,InterruptedException { 
     //get the PHash for this specific file 
     String PHashStr; 
     try { 
      PHashStr = calculatePhash(value.getBytes()); 

和calculatePhash是:

 static String calculatePhash(byte[] imageData) throws NoSuchAlgorithmException { 
     //get the PHash for this specific data 
     //PHash requires inputstream rather than byte array 
     InputStream is = new ByteArrayInputStream(imageData); 
     String ph; 
     try { 
      ImagePHash ih = new ImagePHash(); 
      ph = ih.getHash(is); 
      System.out.println ("file: " + is.toString() + " phash: " +ph); 
     } catch (Exception e) { 
      e.printStackTrace(); 
      return "Internal error with ImagePHash.getHash"; 
     } 

     return ph; 

這一切工作正常,但我想calculatePhash寫出每個JPEG圖像的最後修改日期。我知道我可以使用file.lastModified()獲取文件中的最後修改日期,但是有什麼方法可以在map或calculatePhash中獲取此日期嗎?我是Java的noob。 TIA!

回答

9

嗨,我認爲你要的是每個輸入文件的修改時間進入你的映射器。如果是這樣的話,你只需要幾行添加到mpkorstanje解決方案:

FileSystem fs = FileSystem.get(URI.create(uri), conf); 
long moddificationTime = fs 
    .getFileStatus((FileSplit)context.getInputSplit()) 
    .getPath()).lastModified(); 

有了這幾個變化,你可以得到每個inputSlipt的時間filestatus,你可以爲了以後使用它添加到您的鑰匙在你的過程中,或者使一個多輸出減少並寫入縮小階段的其他地方。

我希望這將是有用的

+2

添加到關鍵字!現在很明顯。謝謝!! – schoon 2014-11-25 11:19:34

5

沒有使用Hadoop的很多,但我不認爲你應該使用file.lastModified()。 Hadoop在某種程度上抽象了文件系統。

您是否嘗試過在map使用FileSystem.getFileStatus(path)?它會爲您帶來一個修改時間爲FileStatus的對象。像

FileSystem fs = FileSystem.get(URI.create(uri), conf); 
long moddificationTime = fs.getFileStatus(new Path(uri)).lastModified(); 
1

東西使用下面的代碼片段,讓你提供在特定目錄路徑修改的所有文件的地圖:

private static HashMap lastModifiedFileList(FileSystem fs, Path rootDir) { 
    // TODO Auto-generated method stub 
    HashMap modifiedList = new HashMap(); 
    try { 

     FileStatus[] status = fs.listStatus(rootDir); 
     for (FileStatus file : status) { 
      modifiedList.put(file.getPath(), file.getModificationTime()); 
     } 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
    return modifiedList; 
} 
0

在Hadoop中的每個文件都包括BLOCK的。 通常Hadoop FileSystem被引用包org.apache.hadoop.fs。 如果輸入文件存在於HDFS意味着你需要導入上述包

FileSystem fs = FileSystem.get(URI.create(uri), conf); 
in = fs.open(new Path(uri)); 

org.apache.hadoop.fs.FileStatus fileStatus=fs.getFileStatus(new Path(uri)); 
long modificationDate = fileStatus.getModificationTime(); 

Date date=new Date(modificationDate); 
SimpleDateFormat df2 = new SimpleDateFormat("dd/MM/yy HH:mm:ss"); 
String dateText = df2.format(date); 

我希望這會幫助你。

+0

工作正常 – Rengasamy 2014-11-25 09:36:32

+2

上述答案和你的答案有什麼不同?看起來兩者都是一樣的。 – Kumar 2014-11-25 09:39:34

相關問題