복붙노트

[HADOOP] FSDataInputStream에서 FileInputStream으로 변환

HADOOP

FSDataInputStream에서 FileInputStream으로 변환

저는 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을 반환한다.

문제는 내가 HDData에서 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을 사용하기 때문입니다. FileChannel은 파일에서 데이터를 읽는 효율을 높일 것으로 추정됩니다.

누군가가 FSDataInputStream을 FileInputStream으로 변환 할 수있는 방법을 보여줄 수 있습니까?

해결법

  1. ==============================

    1.그것을 InputStream으로 사용하십시오.

    그것을 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;
    }
    

    이 경우가 아닙니다. DirectByteBuffer를 사용하는 경우 데이터를 다른 채널에 복사하는 경우에만 효율성이 향상됩니다. 여기에서와 같이 데이터를 처리하는 경우 아무런 차이가 없습니다. 읽기는 여전히 읽기입니다.

  2. ==============================

    2.FSDataInputStream을 일반 InputStream으로 사용하고이를 Channels.newChannel에 전달하여 FileChannel 대신 ReadableByteChannel을 얻을 수 있습니다. 다음은 업데이트 된 버전입니다.

    FSDataInputStream을 일반 InputStream으로 사용하고이를 Channels.newChannel에 전달하여 FileChannel 대신 ReadableByteChannel을 얻을 수 있습니다. 다음은 업데이트 된 버전입니다.

    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;
    }
    
  3. ==============================

    3.다음과 같은 이유로 과제를 수행 할 수 없습니다.

    다음과 같은 이유로 과제를 수행 할 수 없습니다.

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

    그것이 효과가 있을지 확신하지 못한다.

  4. from https://stackoverflow.com/questions/19099582/converting-from-fsdatainputstream-to-fileinputstream by cc-by-sa and MIT license