Hadoop雲盤系統(轉載)
阿新 • • 發佈:2018-12-31
總體概況
專案名稱: 《Hadoop雲盤系統》
Ø專案開發環境:Linux下Hadoop分散式系統
Ø專案開發環境:Ubuntu11.04+Hadoop0.20.2+JDK1.6+Eclipse3.3.2。
Ø使用技術:Hadoop + Java
Ø作品描述:1、個人獨立完成,課餘興趣作品。包含全部設計、分析、編碼、優化。
2、功能實現,檔案上傳、下載、刪除、維護、資料夾的新建、檔案路徑跟蹤、以及個人檔案搜尋功能實現和檔案分類展現等。
3、基於Hadoop開發的分散式雲平臺的檔案管理系統。
一、 概況: 1、這是個人的業餘愛好專案,自己進行了全部的設計、分析、編碼、和優化。
再看個人的《雲盤》
總結:介面設計簡潔,整齊,操作方面,使用者體驗良好。
三、Hadoop叢集主要配置和啟動操作操作過程
1、檢視叢集的主節點配置。先在Linux中啟動Hadoop,如下:檢視現在JPS執行的程序,檢查系統是否正常啟動
2、檢視 core-site.xml檔案檢視主節點的配置。
無誤後,可以利用Eclipse 啟動程式執行程式了。
四、系統部分測試和主要程式碼解析
1、上傳檔案
主要程式碼分析:
[java] view plaincopyprint?- JFileChooser chooser = new JFileChooser();
- chooser.setVisible(true);
- int returnVal = chooser.showOpenDialog(null);
- if (returnVal == JFileChooser.APPROVE_OPTION) {// 為確定或OK是
- String localPath = chooser.getSelectedFile()
- .getPath();
- String filename = chooser.getSelectedFile()
- .getName();
- InputStream in = null;
- try {
- in = new BufferedInputStream(
- new FileInputStream(localPath));//本地檔案輸入流
- } catch (FileNotFoundException e3) {
- e3.printStackTrace();
- }
- OutputStream out = null;
- try {
- out = hdfs.create(new Path(currentPath
- + "/" + filename),
- new Progressable() {
- publicvoid progress() {
- System.out.print(".");
- }
- });//HDFS路徑的輸出流抽象
- } catch (IOException e2) {
- e2.printStackTrace();
- }
- try {
- IOUtils.copyBytes(in, out, 4096, true);//利用IOUtils工具類實現上傳
- } catch (IOException e1) {
- e1.printStackTrace();
- }
- try {
- showTable(currentPath);//上傳完畢就重新整理當前路徑的檔案表格
- } catch (IOException e1) {
- e1.printStackTrace();
- }
- }
JFileChooser chooser = new JFileChooser();
chooser.setVisible(true);
int returnVal = chooser.showOpenDialog(null);
if (returnVal == JFileChooser.APPROVE_OPTION) {// 為確定或OK是
String localPath = chooser.getSelectedFile()
.getPath();
String filename = chooser.getSelectedFile()
.getName();
InputStream in = null;
try {
in = new BufferedInputStream(
new FileInputStream(localPath));//本地檔案輸入流
} catch (FileNotFoundException e3) {
e3.printStackTrace();
}
OutputStream out = null;
try {
out = hdfs.create(new Path(currentPath
+ "/" + filename),
new Progressable() {
public void progress() {
System.out.print(".");
}
});//HDFS路徑的輸出流抽象
} catch (IOException e2) {
e2.printStackTrace();
}
try {
IOUtils.copyBytes(in, out, 4096, true);//利用IOUtils工具類實現上傳
} catch (IOException e1) {
e1.printStackTrace();
}
try {
showTable(currentPath);//上傳完畢就重新整理當前路徑的檔案表格
} catch (IOException e1) {
e1.printStackTrace();
}
}
2、檔案下載分析:從在HDFS中下載到本地檔案系統中, 主要程式碼分析: [java] view plaincopyprint?
- if (e.getSource() == deleItem) {
- int ensuce = JOptionPane.showConfirmDialog(new MainWindow(),
- "確定刪除所選檔案嗎", "確認對話方塊", JOptionPane.YES_NO_OPTION);
- if (ensuce == JOptionPane.NO_OPTION) {
- return;
- }
- if (ensuce == JOptionPane.YES_OPTION) {
- if (fileList.getSelectedRow() >= 0) {
- String temp = currentPath
- + "/"
- + fileList.getValueAt(
- fileList.getSelectedRow(), 0);//獲取要刪掉檔案的路徑
- try {
- hdfs.delete(new Path(temp), true);
- } catch (IOException e1) {
- e1.printStackTrace();
- }
- try {
- showTable(currentPath);
- } catch (IOException e1) {
- e1.printStackTrace();
- }
- }
- }
if (e.getSource() == deleItem) {
int ensuce = JOptionPane.showConfirmDialog(new MainWindow(),
"確定刪除所選檔案嗎", "確認對話方塊", JOptionPane.YES_NO_OPTION);
if (ensuce == JOptionPane.NO_OPTION) {
return;
}
if (ensuce == JOptionPane.YES_OPTION) {
if (fileList.getSelectedRow() >= 0) {
String temp = currentPath
+ "/"
+ fileList.getValueAt(
fileList.getSelectedRow(), 0);//獲取要刪掉檔案的路徑
try {
hdfs.delete(new Path(temp), true);
} catch (IOException e1) {
e1.printStackTrace();
}
try {
showTable(currentPath);
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
3、檔案表格展現 主要程式碼: [java] view plaincopyprint?
- /*-------------------------------------把currentPath路徑下的檔案和資料夾屬性全都顯示錶格中----------------------------------------------------------*/
- privatevoid showTable(String currentPath) throws IOException {
- SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
- Path inputDir = new Path(currentPath);/* 獲取檔案的路徑*/
- /* FileStatue類*/
- FileStatus[] status = hdfs.listStatus(inputDir);/* 得到檔案路徑目錄下檔案列表*/
- DefaultTableModel model = (DefaultTableModel) fileList.getModel(); // 獲取表格模型
- if (fileList.getRowCount() != 0) { // 當表格中有資料
- ((DefaultTableModel) fileList.getModel()).setRowCount(0);// 將表格置空
- }
- for (int i = 0; i < status.length; i++) {
- String filename = null;
- String lenStr = null;
- String modifDate = null;
- filename = status[i].getPath().getName();
- String length = null; // 獲取檔案大小資訊
- DecimalFormat df = new DecimalFormat("#.00");
- if (status[i].isDir()) {
- lenStr = "-";
- } else {
- if (status[i].getLen() > (1024 * 1024 * 1024)) {
- length = df.format(status[i].getLen()
- / (1024.0 * 1024 * 1024));
- lenStr = " " + length + "G";
- } elseif (status[i].getLen() > (1024 * 1024)) {
- length = df.format(status[i].getLen() / (1024.0 * 1024));
- lenStr = " " + length + "M";
- } elseif (status[i].getLen() > 1024) {
- length = df.format(status[i].getLen() / 1024.0);
- lenStr = " " + length + "KB";
- } else {
- length = df.format(status[i].getLen());
- lenStr = " " + length + "B";
- }
- }
- modifDate = sdf.format(status[i].getModificationTime());
- model.addRow(new Object[] { filename, lenStr, modifDate }); // 將檔名、檔案大小、檔案建立日期新增到表格
- }
- }
/*-------------------------------------把currentPath路徑下的檔案和資料夾屬性全都顯示錶格中----------------------------------------------------------*/
private void showTable(String currentPath) throws IOException {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
Path inputDir = new Path(currentPath);/* 獲取檔案的路徑*/
/* FileStatue類*/
FileStatus[] status = hdfs.listStatus(inputDir);/* 得到檔案路徑目錄下檔案列表*/
DefaultTableModel model = (DefaultTableModel) fileList.getModel(); // 獲取表格模型
if (fileList.getRowCount() != 0) { // 當表格中有資料
((DefaultTableModel) fileList.getModel()).setRowCount(0);// 將表格置空
}
for (int i = 0; i < status.length; i++) {
String filename = null;
String lenStr = null;
String modifDate = null;
filename = status[i].getPath().getName();
String length = null; // 獲取檔案大小資訊
DecimalFormat df = new DecimalFormat("#.00");
if (status[i].isDir()) {
lenStr = "-";
} else {
if (status[i].getLen() > (1024 * 1024 * 1024)) {
length = df.format(status[i].getLen()
/ (1024.0 * 1024 * 1024));
lenStr = " " + length + "G";
} else if (status[i].getLen() > (1024 * 1024)) {
length = df.format(status[i].getLen() / (1024.0 * 1024));
lenStr = " " + length + "M";
} else if (status[i].getLen() > 1024) {
length = df.format(status[i].getLen() / 1024.0);
lenStr = " " + length + "KB";
} else {
length = df.format(status[i].getLen());
lenStr = " " + length + "B";
}
}
modifDate = sdf.format(status[i].getModificationTime());
model.addRow(new Object[] { filename, lenStr, modifDate }); // 將檔名、檔案大小、檔案建立日期新增到表格
}
}
4、檔案搜尋功能實現(利用回溯演算法+字元匹配來實現) 先測試一下功能吧!我們輸入“Hadoop”關鍵字搜尋比配的檔案 再入:輸入“數學”搜尋一下結果 主要實現程式碼 [java] view plaincopyprint?
- showAllResult(target);//具體實現
- /*--------------------獲取所有要搜尋到的檔案路徑---------------------------------*/
- private List<String> findAllFile(String target) {
- List<String> result = new ArrayList<String>();
- char[] tar = target.toCharArray();
- int count = 0;
- String findPath = currentPath;//預設搜尋的路徑是目前開啟目錄下為根的目錄樹
- getAllFile(tar, result, findPath, count);
- return result;
- }
- /*-----------------------------回溯檢測樹形下的檔案---------------------------------------------------------*/
- privatevoid getAllFile(char[] tar, List<String> result, String findPath,
- int count) {
- conf = new Configuration();
- try {
- hdfs = FileSystem.get(URI.create(findPath), conf);
- } catch (IOException e) {
- e.printStackTrace();
- }
- try {
- if (hdfs.isFile(new Path(findPath))) {
- String name = hdfs.getFileStatus(new Path(findPath)).getPath()
- .getName();
- if (isFind(tar, name.toCharArray())) {//檢測是否字元匹配,匹配為找到
- result.add(findPath);// 搜尋到加入陣列
- }
- return;
- }
- } catch (IOException e) {
- e.printStackTrace();
- }
- FileStatus[] sta = null;
- try {
- sta = hdfs.listStatus(new Path(findPath));
- } catch (IOException e) {
- e.printStackTrace();
- }
- for (int i = 0; i < sta.length; i++) {//回溯法實現迴圈遞迴遍歷
- getAllFile(tar, result, sta[i].getPath().toString(), count++);
- }
- }
- /*-----------------------檢視字串是否包含--------------------------------------------*/
- privateboolean isFind(char[] tar, char[] sour) {
- int all=0.0;for (int i = 0; i < tar.length; i++) {
- int j = 0;
- for (; j < sour.length; ++j) {
- if (tar[i] == sour[j]) {
- all++;break;
- }
- }
- if (j == sour.length&&all/sour.length<0.75) {//概率匹配
- returnfalse;
- }
- }
- returntrue;
- }
showAllResult(target);//具體實現
/*--------------------獲取所有要搜尋到的檔案路徑---------------------------------*/
private List<String> findAllFile(String target) {
List<String> result = new ArrayList<String>();
char[] tar = target.toCharArray();
int count = 0;
String findPath = currentPath;//預設搜尋的路徑是目前開啟目錄下為根的目錄樹
getAllFile(tar, result, findPath, count);
return result;
}
/*-----------------------------回溯檢測樹形下的檔案---------------------------------------------------------*/
private void getAllFile(char[] tar, List<String> result, String findPath,
int count) {
conf = new Configuration();
try {
hdfs = FileSystem.get(URI.create(findPath), conf);
} catch (IOException e) {
e.printStackTrace();
}
try {
if (hdfs.isFile(new Path(findPath))) {
String name = hdfs.getFileStatus(new Path(findPath)).getPath()
.getName();
if (isFind(tar, name.toCharArray())) {//檢測是否字元匹配,匹配為找到
result.add(findPath);// 搜尋到加入陣列
}
return;
}
} catch (IOException e) {
e.printStackTrace();
}
FileStatus[] sta = null;
try {
sta = hdfs.listStatus(new Path(findPath));
} catch (IOException e) {
e.printStackTrace();
}
for (int i = 0; i < sta.length; i++) {//回溯法實現迴圈遞迴遍歷
getAllFile(tar, result, sta[i].getPath().toString(), count++);
}
}
/*-----------------------檢視字串是否包含--------------------------------------------*/
private boolean isFind(char[] tar, char[] sour) {
int all=0.0;for (int i = 0; i < tar.length; i++) {
int j = 0;
for (; j < sour.length; ++j) {
if (tar[i] == sour[j]) {
all++;break;
}
}
if (j == sour.length&&all/sour.length<0.75) {//概率匹配
return false;
}
}
return true;
}
5、檔案分類實現查詢 a、檔案分類管理檢視,檢視“文件”列出系統中所有的文件 b、“圖片” c、“音樂” 等等 。。。 。。。 6、其他的實現,目錄檔案跟蹤、檔案維護等: *最後說說本系統的資訊處理的實現---MapReduce解決 首先說下其實登陸不只是利用資料庫來實現的,解決方法有如下幾種: 方案一:用另外一臺機器專門用於對資料庫操作的。要是在一個Hadoop中叢集中安裝一個數據庫,我們不應該把資料庫放在namenode中,而是放到另外的一臺機,因 為namenode的任務已經夠多了,安裝在namenode上,多使用者登陸時對資料庫操作會消耗namenode的記憶體,會影響namenode對datanode的管理和排程等。 所以我們應該放到指定的一臺機器上。 方案二:利用利用Hadoop中分散式資料庫HBase解決。這個毫無疑問是最好的解決方案,是針對雲技術分散式的資料庫。不過本人對HBase還是處於瞭解階段,所以沒 有用上它。 最終方案:HBase用不上,不過沒關係,因為現在只是對一個使用者資訊處理實現,業務量很少,我可以仿照Hive那樣,在資料進行的時候轉化為MapReduce進行,利用MapReduce來進行表與表的關聯。 例如如下表: 資訊表: 登陸表: 有待擴充套件的功能模組:我的分享----可以做成分享一個檔案提供所有人下載,也可以做成分享給具體的某個使用者。 實現方式:做一個分享表,記錄了 分享人,被分享人,檔案獲取的路徑(或者獲取檔案所需的引數引數) 如下: 總結:本人學習Hadoop至今快半年,熟悉HDFS、MapReduce開發,有對過Hadoop HDFS部分、MapReduce原始碼深入分析過,特別是MapReduce、做過不少的MapReduce計算實現。對Hadoop雲技術很感興趣,渴望從事於相關的開發工作。