Hadoop學習筆記(5)
——編寫HelloWorld(2)
前面我們寫了一個Hadoop程序,並讓它跑起來了。但想想不對啊,Hadoop不是有兩塊功能么,DFS和MapReduce。沒錯,上一節我們寫了一個MapReduce的HelloWorld程序,那這一節,我們就也學一學DFS程序的編寫。
DFS是什么,之前已經了解過,它是一個分布式文件存儲系統。不管是遠程或本地的文件系統,其實從接口上講,應該是一至的,不然很難處理。同時在第2節的最后,我們列出了很多一些DFS的操作命令,仔細看一下,這些命令其實跟linux中的文件操作命令很相似,所以說,對於分布式文件系統,我們完全可以用本地文件的方式來理解。
那理一下,一般常用操作有哪些? 當然我們可以從編程角度來:
創建、讀、寫一個文件,列出文件夾中的文件及文件夾列表,刪除文件夾,刪除目錄,移動文件或文件夾,重命名文件或文件夾。
同樣,這里我們就依葫蘆畫瓢跑起個程序來:
啟動eclipse,新建Hadoop項目,名稱MyDFSTest,新建類DFSTest,點擊確定,然后同樣工程屬性Configure BuildPath中把 build/ivy/lib/Hadoop下的所有jar包都引用進來。「這里就不詳細截圖了,可以參考前一節中的內容」
在類中,添加main函數:
public static void main(String[] args) {
}
也可以在添加類時,勾選上創建main,則會自動添加上。
在Main函數中添加以下內容:
try {
Configuration conf = new Configuration();
conf.set("fs.default.name", "hdfs://localhost:9000");
FileSystem hdfs = FileSystem.get(conf);
Path path = new Path("in/test3.txt");
FSDataOutputStream outputStream = hdfs.create(path);
byte[] buffer = " 你好Hello".getBytes();
outputStream.write(buffer, 0, buffer.length);
outputStream.flush();
outputStream.close();
System.out.println("Create OK");
} catch (IOException e) {
e.printStackTrace();
}
直接添加進來會報錯,然后需要添加一些引用才行:
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FSDataOutputStream;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
在沒有錯誤后,點擊工具條上的運行, 但這次跟前次不一樣,選擇Run as Java Application。然后,就可以在輸出框中看到Create OK的字樣了,表明程序運行成功。
這段代碼的意思是在in文件夾下,創建test3.txt,里面的內容是"你好Hello"。 在運行完后,我們可以到eclipse的Project Explorer中查看是否有這文件以及內容。同樣也可以用命令行查看$bin/hadoop fs -ls in。
好了,第一個操作DFS的程序跑起來了,那其它功能只要套上相應的處理類就可以了。
為了方便查找操作,我們列舉了張表:
| 操作說明 |
操作本地文件 |
操作DFS文件 |
| 主要命名空間 |
java.io.File java.io.FileInputStream java.io.FileOutputStream |
org.apache.hadoop.conf.Configuration org.apache.hadoop.fs.FileSystem org.apache.hadoop.fs.Path org.apache.hadoop.fs.FSDataInputStream; org.apache.hadoop.fs.FSDataOutputStream |
| 初使化對象 |
new File(路徑); |
Configuration FileSystem hdfs |
| 創建文件 |
File.createNewFile(); |
FSDataOutputStream = hdfs.create(path) FSDataOutputStream.write( buffer, 0, buffer.length); |
| 創建文件夾 |
File.mkdir() |
hdfs.mkdirs(Path); |
| 讀文件 |
new FileInputStream(); FileInputStream.read(buffer) |
FSDataInputStream = hdfs.open(path); FSDataInputStream.read(buffer); |
| 寫文件 |
FileOutputStream.write( buffer, 0, buffer.length); |
FSDataOutputStream = hdfs.append(path) FSDataOutputStream.write( buffer, 0, buffer.length); |
| 刪除文件(夾) |
File.delete() |
FileSystem.delete(Path) |
| 列出文件夾內容 |
File.list(); |
FileSystem.listStatus() |
| 重命令文件(夾) |
File.renameTo(File) |
FileSystem.rename(Path, Path) |
有了這張表,以后不怕了,代碼搬搬即可。
接下來換個話題。
本人主要從事.net開發的,所以對於java上,還是有點生。所以接下來半章中,簡要的把JAVA的學習列一列。
JAVA和.net現在從語言角度看,的確有很多相似之處。但也有不同之處,這就是我們要學的。
在.Net中,主要有dll和exe, dll為類庫, exe為可執行程序,在exe中有唯一的main函數,作為函數入口。dll 類庫是無法執行的,exe可以雙擊運行,也可以命令行執行。編譯后,.net會把所有定義的類編譯進exe或dll中,一個工程產出文件就是一個。
在JAVA中,jar對應的類庫,可以被別人調用。exe就不存在了。一個工程編譯后,產出物是一堆的.class文件,在開發中每一個定義的類,都會被編譯成這個.class文件。而且一個.java文件中,不能定義多個頂級類(嵌套類是可以的),且文件名與類名必須相同,文件所以的目錄必須和命名空間相同。所以編譯后,可以講一個.java文件將會編譯成一個.class文件,且有與原先的目錄相同。
也就是說,java有點像散裝的一樣,產物就是一堆的.class文件。 那jar文件呢,簡單的說,就是一個zip包,把一堆的.class文件打包成一個壓縮包。
同時,一個工程中,支持多個main函數,即多個入口。
說了一堆,還不如實踐一下:
在eclipse中,創建一個JAVA project 取名為JAVAStudy。
然后創建兩個類,沒有目錄的,ch1 ch2 再創建一個包叫pkg1,在這個包下創建一個類ch3:

然后,每個類下都建一個main函數,內容打印類名:
public static void main(String[] args) {
System.out.println(ch1.class.getName());
}
注意,復制到ch2 ch3中后要改一下里面的類名。
然后每當你切換到一個新的類代碼中,點擊運行,都會提示Run As ,都選Java Application。 然后就可以看到結果了,每個類都可以作為入口執行。
OK,程序好了,如何發布呢,或如何從命令行運行呢?
我們進入目錄先看一下:

進入工程目錄,可以看到有src和bin,進入bin,就可以看到一個個的class文件了,的確跟前面描述一樣,目錄與代碼相同結構。

輸入java ch1 就可以看到結果了。執行ch3時,注意中間不是斜線,而是點,因為這里輸入的是命名空間+類名,而不是class文件的路徑。
如果不在這個目錄執行,看到會報錯,或命名空間輸錯了,也是這個錯。

如果我就在這里想執行呢? 可以這樣:

利用classpath指定class的路徑。
如何打成jar包:
進入bin目錄:
$cd bin
$jar cvf test.jar ch1.class ch2.class pkg1/.class
然后在bin目錄下就可以看到test.jar文件了。
如何執行jar呢,為了防止與里面的class文件沖突,我們將test.jar復制到外面來:
$cp test.jar ../
$cd ..
再執行:
$java –classpath test.jar ch1

同樣,輸入classpath就可以搞定了的。
了解了這些后,我們又可以做個試驗證了。 第一章中我們運行hadoop中Helloword時,是調用了example的jar包。所以這里我們可以把上一章的程序也來打個jar包,試下是否能運行:
$cd ~/workspace/MyHelloWorld //進入HelloWorld代碼目錄
$cd bin
$jar cvf test.jar *.class //打上jar包
$cp test.jar ../../hadoop-0.20.2 //將jar包復制到hadoop目錄下
$cd ../../hadoop-0.20.2
$bin/start-all.sh //啟動hadoop
$bin/hadoop test.jar WordCount in out //運行我們寫的程序
然后就可以看到與之前一樣的結果了。
