c++ 操作HDFS

     如果由於業務需求無法用python、java以及命令行來操作HDFS,需要用c++的話,不用着急,libhdfs將是爲你帶來方便。Libhdfs是專門爲c以及c++開發者提供的操作HDFS的API庫,下面就是兩個demo的介紹:

  1. 向HDFS的文件中寫數據
  2. 從HDFS的文件中讀數據

向HDFS的文件中寫數據

     代碼如下:

#ifndef WRITE_H
#define WRITE_H
 
#include <iostream>
#include "hdfs.h"
#include <stdlib.h>
#include <string.h>
 
using namespace std;
 
class WriteData{
public:
    WriteData(){
    }
    virtual ~WriteData(){
    }
 
    void writeData(char* writepath, char* data){
        //連接HDFS
        hdfsFS fs = hdfsConnect("default", 8080);
        if (!fs){
            cout <<"cannot connect to HDFS"<<endl;
            exit(1);
        }
        cout <<"connect success!" <<endl;
        //檢查寫入的文件是否存在
        int a = hdfsExists(fs,writepath);
        cout <<a<<endl;
        hdfsFile writeFile;
        if (a == 0){
            //如果文件存在,打開文件,並且設置項文件中追加數據
            writeFile = hdfsOpenFile(fs, writepath, O_WRONLY|O_APPEND, 0, 0, 0);
        }else{
            //如果文件不存在,則創建文件,並將數據寫入
            writeFile = hdfsOpenFile(fs, writepath, O_WRONLY|O_CREAT, 0, 0, 0);
        }
        if (!writeFile){
            cout <<"Faile to open the file"<<endl;
            exit(1);
        }
        //將數據寫入到HDFS中
        tSize num_written_bytes = hdfsWrite(fs, writeFile, (void*)data, strlen(data)+1);
        if (hdfsFlush(fs, writeFile)) {
            cout << "Failed to flush" << endl;
            exit(1);
        }
        //關閉連接
        hdfsCloseFile(fs, writeFile);
    }
};
 
#endif

     整體流程主要分爲三步:

  1. 連接HDFS:主要的方法接口爲:hdfsFS hdfsConnect(const char* host, tPort port)    其中參數爲:hdfs的主機IP以及端口號。

     2.  打開HDFS文件:主要的方法接口爲:hdfsFile hdfsOpenFile(hdfsFS fs, const char* path, int flags, int bufferSize, short replication, tSize blocksize)    其中參數依次爲:連接HDFS的Handle,文件的位置,文件的操作設置(如只讀、讀寫、追加、創建新的文件等),如果文件在HDFS上的話,後三個參數可以忽略直接設置爲0。

     3.  寫文件:主要的方法接口爲:tsize hdfsWrite(hdfsFS fs, hdfsFile file, const void* buffer, tSize length)    其中參數依次爲:連接HDFS的Handle,文件的Handle,寫入的data,寫入數據的長度。

從HDFS的文件中讀數據

代碼如下:

#ifndef READ_H
#define READ_H
 
#include <iostream>
#include "hdfs.h"
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
 
using namespace std;
 
class ReadData{
public:
    ReadData(){
    }
    virtual ~ReadData(){
    }
    int readData(char* getpath, char* buffer, tSize bufferSize){
        //連接到HDFS
        hdfsFS fs = hdfsConnect("default",8080);
        if (!fs){
            cout <<"cannot connect to HDFS"<<endl;
            exit(1);
        }
        cout <<"connect success!"<<endl;
        //以讀文件的方式打開文件
        hdfsFile readFile = hdfsOpenFile(fs, getpath, O_RDONLY, 0, 0, 0);
        if (!readFile){
            cout <<"Faile to open the file"<<endl;
            exit(1);
        }
        if(buffer == NULL){
            cout <<"buffer is null"<< endl;
        }
        //讀取文件中的數據到buffer中
        tSize result = hdfsRead(fs, readFile, (void*)buffer, bufferSize);
        if (result < 0){
            cout << "hdfsRead faile!" << endl;
        }
        cout <<result<< endl;
        //關閉連接
        hdfsCloseFile(fs,readFile);
        return result;
    }
};
 
#endif

同樣,他也主要分爲三部分:連接到HDFS、打開HDFS文件、讀取文件。

     其中讀取文件的主要方法接口爲:tSize hdfsRead(hdfsFS fs, hdfsFile file, void* buffer, tSize length).   其中參數依次爲:連接HDFS的Handle,文件的Handle,讀取的數據存放的buffer,buffer的大小

     在運行與make的時候請注意:由於libhdfs是依賴Java的,所以要將JAVA_HOME、JRE_HOME配置進去,同樣也需要將其所依賴的Hadoop的包配置進去。以下是我的運行腳本作爲參考:

#!/bin/bash
 
#配置參數
CLASSPATH=${JAVA_HOME}/lib:${JRE_HOME}/lib
CLASSPATH=${CLASSPATH}":"`find ${HADOOP_HOME}/share/hadoop | awk '{path=path":"$0}END{print path}'`
export CLASSPATH
 
rm ./test
 
#c++make指令
g++ *.cpp -I${HADOOP_HOME}/include -L${HADOOP_HOME}/lib/native -lhdfs -Wl,-rpath=${HADOOP_HOME}/lib/native -L${JRE_HOME}/lib/amd64/server -ljvm -Wl,-rpath=${JRE_HOME}/lib/amd64/server -o test
 
 
hdfs dfs -rm /tmp/testlibhdfs.txt
 
#寫入的示例指令
./test write /tmp/testlibhdfs.txt "beautiful girl"
 
#讀取的示例指令
./test read /tmp/testlibhdfs.txt 100

由於是第一次寫c++,如有不對的地方,還請大神指正。






發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章