如何从Hadoop序列文件中获取最后修改日期?

时间:2014-11-14 18:52:14

标签: java date hadoop mapreduce

我正在使用将BinaryFiles(jpegs)转换为Hadoop序列文件(HSF)的映射器:

    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的菜鸟。 TIA!

4 个答案:

答案 0 :(得分:10)

您好我认为您想要的是输入映射器中输入的每个输入文件的修改时间。如果是这种情况,您只需在mpkorstanje解决方案中添加几行:

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

通过这些少量更改,您可以获取每个inputSlipt的fileStatus,并且可以将其添加到您的密钥中,以便稍后在您的流程中使用,或者在reduce阶段减少并写入其他地方。

我希望这会有用

答案 1 :(得分: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();

答案 2 :(得分:1)

使用以下代码段获取在您提供的特定目录路径下修改的所有文件的Map:

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

答案 3 :(得分: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);

我希望这会对你有所帮助。