从FSDataInputStream转换为FileInputStream

时间:2013-09-30 16:50:52

标签: java hadoop hash

我是Hadoop HDFS的新手,而且Java非常生疏,我需要一些帮助。我正在尝试从HDFS读取文件并计算此文件的MD5哈希值。一般的Hadoop配置如下。

private FSDataInputStream hdfsDIS;
private FileInputStream FinputStream;
private FileSystem hdfs;
private Configuration myConfig;

myConfig.addResource("/HADOOP_HOME/conf/core-site.xml");
myConfig.addResource("/HADOOP_HOME/conf/hdfs-site.xml");

hdfs = FileSystem.get(new URI("hdfs://NodeName:54310"), myConfig);

hdfsDIS = hdfs.open(hdfsFilePath);

函数hdfs.open(hdfsFilePath)返回FSDataInputStream

问题是我只能从HDFS中获得FSDataInputStream,但我希望得到FileInputStream

下面的代码执行散列部分,并根据我在StackOverflow上找到的东西进行改编(现在似乎无法找到它的链接)。

FileInputStream FinputStream = hdfsDIS;   // <---This is where the problem is
MessageDigest md;
    try {
        md = MessageDigest.getInstance("MD5");  
        FileChannel channel = FinputStream.getChannel();
        ByteBuffer buff = ByteBuffer.allocate(2048);

        while(channel.read(buff) != -1){
            buff.flip();
            md.update(buff);
            buff.clear();
        }
        byte[] hashValue = md.digest();

        return toHex(hashValue);
    }
    catch (NoSuchAlgorithmException e){
        return null;
    } 
    catch (IOException e){
        return null;
    }

我需要FileInputStream的原因是因为执行散列的代码使用FileChannel,这可能会提高从文件中读取数据的效率。

有人可以告诉我如何将FSDataInputStream转换为FileInputStream

3 个答案:

答案 0 :(得分:2)

将其用作InputStream:

MessageDigest md;
try {
    md = MessageDigest.getInstance("MD5");  
    byte[] buff = new byte[2048];
    int count;

    while((count = hdfsDIS.read(buff)) != -1){
        md.update(buff, 0, count);
    }
    byte[] hashValue = md.digest();

    return toHex(hashValue);
}
catch (NoSuchAlgorithmException e){
    return null;
} 
catch (IOException e){
    return null;
}
  

执行散列的代码使用FileChannel,据说可以提高从文件中读取数据的效率

不是这种情况。如果你只是将数据复制到另一个频道,它只会提高效率,如果你使用DirectByteBuffer.如果你正在处理数据,就像这里一样,它没有任何区别。读取仍然是读取。

答案 1 :(得分:0)

您可以将FSDataInputStream仅用作常规InputStream,并将其传递给Channels.newChannel以取回ReadableByteChannel而不是FileChannel。这是一个更新版本:

InputStream inputStream = hdfsDIS;
MessageDigest md;
try {
    md = MessageDigest.getInstance("MD5");  
    ReadableByteChannel channel = Channels.newChannel(inputStream);
    ByteBuffer buff = ByteBuffer.allocate(2048);

    while(channel.read(buff) != -1){
        buff.flip();
        md.update(buff);
        buff.clear();
    }
    byte[] hashValue = md.digest();

    return toHex(hashValue);
}
catch (NoSuchAlgorithmException e){
    return null;
} 
catch (IOException e){
    return null;
}

答案 2 :(得分:-1)

你不能这样做,因为:

java.lang.Object
  由java.io.InputStream扩展       由java.io.FilterInputStream扩展
          由java.io.DataInputStream扩展               由org.apache.hadoop.fs.FSDataInputStream扩展

FSDataInputStream不是FileInputStream。

那说要从FSDataInputStream转换为FileInputStream,

您可以根据Api用户FSDataInputStream FileDescriptors创建FileInputStream

new FileInputStream(hdfsDIS.getFileDescriptor());

不确定它是否有效。