如果由於業務需求無法用python、java以及命令行來操作HDFS,需要用c++的話,不用着急,libhdfs將是爲你帶來方便。Libhdfs是專門爲c以及c++開發者提供的操作HDFS的API庫,下面就是兩個demo的介紹:
- 向HDFS的文件中寫數據
- 從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
整體流程主要分爲三步:
- 連接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++,如有不對的地方,還請大神指正。