2014-11-14 11 views
7

Sto usando un mapper che converte BinaryFiles (jpeg) ad una sequenza di file Hadoop (HSF):Come ottengo la data dell'ultima modifica da un file di sequenza 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())); 

Ho poi hanno una seconda mapper che legge il HSF, in tal modo:

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

e 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; 

Questo tutto funziona benissimo, ma voglio calculatePhash di scrivere data dell'ultima modifica di ogni jpeg. So che posso usare file.lastModified() per ottenere l'ultima data di modifica in un file, ma c'è un modo per ottenere questo in una mappa o in un calcoloPhash? Sono un noob in Java. TIA!

risposta

9

Ciao io credo che si vuole è l'ora di modifica di ogni file di input che entra nel tuo mapper. Se è il caso basta aggiungere alcune righe alla soluzione mpkorstanje:

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

Con queste poche modifiche è possibile ottenere il fileStatus di ogni inputSlipt ed è possibile aggiungere alla vostra chiave al fine di utilizzare in seguito nel tuo processo o fai un output multiplo riduci e scrivi da qualche altra parte nella tua fase di riduzione.

Spero che questo sarà utile

+2

Aggiungilo alla chiave! Così ovvio ora. Grazie!! – schoon

5

Non ho usato molto Hadoop ma non penso che dovresti usare file.lastModified(). Hadoop ha in qualche modo astratto il file system.

Hai provato a utilizzare FileSystem.getFileStatus(path) in map? Ottiene un oggetto FileStatus con un tempo di modifica. Qualcosa di simile

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

Utilizzare il seguente frammento di codice per ottenere Mappa di tutti i file modificati con particolare percorso di directory forniti:

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

In Hadoop ogni file sono costituiti da BLOCK. Generalmente Hadoop FileSystem si riferisce al pacchetto org.apache.hadoop.fs. Se i file di input sono presenti in HDFS significa che è necessario importare il pacchetto di cui sopra

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); 

Spero che questo vi aiuterà.

+0

Ha funzionato bene – Rengasamy

+2

Qual è la differenza tra le risposte di cui sopra e le tue? Sembra che entrambi siano uguali. – Kumar