从fsdatainputstream到fileinputstream的转换

hkmswyz6  于 2021-06-03  发布在  Hadoop
关注(0)|答案(3)|浏览(814)

我对hadoophdfs有点陌生,对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 问题是我只能得到一个 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

rkue9o1l

rkue9o1l1#

你可以用 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;
}
z8dt9xmd

z8dt9xmd2#

把它当作 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.` 如果你像这里一样处理数据,这没有任何区别。读书还是读书。
vbkedwbf

vbkedwbf3#

无法执行该任务,因为:
java.lang.object对象
由java.io.inputstream扩展
由java.io.filterinputstream扩展
由java.io.datainputstream扩展
由org.apache.hadoop.fs.fsdatainputstream扩展
fsdatainputstream不是fileinputstream。
也就是说从fsdatainputstream转换为fileinputstream,
您可以使用fsdatainputstream filedescriptors根据api创建fileinputstream

new FileInputStream(hdfsDIS.getFileDescriptor());

我不确定能不能用。

相关问题