今天在學習如何從hadoop中讀取資料時,寫了一個簡單的方法,測試時,卻報以下錯誤:
以下是讀取hadoop中檔案并寫入本地磁盤的代碼:
<a href="http://my.oschina.net/itblog/blog/337235#">?</a>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<code>package</code> <code>hdfs;</code>
<code>import</code> <code>java.io.bufferedreader;</code>
<code>import</code> <code>java.io.filewriter;</code>
<code>import</code> <code>java.io.inputstream;</code>
<code>import</code> <code>java.io.inputstreamreader;</code>
<code>import</code> <code>java.net.url;</code>
<code>import</code> <code>org.apache.hadoop.io.ioutils;</code>
<code>public</code> <code>class</code> <code>hdfs {</code>
<code> </code><code>public</code> <code>static</code> <code>void</code> <code>main(string[] args) </code><code>throws</code> <code>exception {</code>
<code> </code><code>inputstream inputstream = </code><code>null</code><code>;</code>
<code> </code><code>filewriter writer = </code><code>null</code><code>;</code>
<code> </code><code>try</code> <code>{</code>
<code> </code><code>url url = </code><code>new</code> <code>url(</code><code>"hdfs://localhost:9000/input.txt"</code><code>);</code>
<code> </code><code>inputstream = url.openstream();</code>
<code> </code><code>writer = </code><code>new</code> <code>filewriter(</code><code>"/home/wxl/桌面/tmp.txt"</code><code>);</code>
<code> </code><code>inputstreamreader reader = </code><code>new</code> <code>inputstreamreader(inputstream);</code>
<code> </code><code>bufferedreader bufferedreader = </code><code>new</code> <code>bufferedreader(reader);</code>
<code> </code><code>string line = </code><code>null</code><code>;</code>
<code> </code><code>while</code><code>((line = bufferedreader.readline()) != </code><code>null</code><code>) {</code>
<code> </code><code>writer.write(line);</code>
<code> </code><code>}</code>
<code> </code><code>} </code><code>finally</code> <code>{</code>
<code> </code><code>ioutils.closestream(inputstream);</code>
<code> </code><code>if</code><code>(writer != </code><code>null</code><code>) {</code>
<code> </code><code>writer.close();</code>
<code> </code><code>}</code>
<code> </code><code>}</code>
<code>}</code>
幾經周折,在《hadoop權威指南》中找到這樣的結果:
"there’s a little bit more work required to make java recognize hadoop’s hdfs url scheme. this is achieved by calling the seturlstreamhandlerfactory method on url with an instance of fsurlstreamhandlerfactory . this method can be called only once per jvm, so it is typically executed in a static block."
意即:“讓java程式能夠識别hadoop的hdfs url方案還需要一些額外的工作,這裡采用的方法是通過fsurlstreamhandlerfactory執行個體調用url中的seturlstreamhandlerfactory方法。由于java虛拟機隻能調用一次上述方法,是以通常在靜态方法中調用上述方法。”
于是,在類中加入靜态執行塊:
<code>static</code> <code>{</code>
<code> </code><code>// this method can be called at most once in a given jvm.</code>
<code> </code><code>url.seturlstreamhandlerfactory(</code><code>new</code> <code>fsurlstreamhandlerfactory());</code>
是以代碼變成了下面這樣:
32
33
34
35
36
37
38
39
<code>import</code> <code>org.apache.hadoop.fs.fsurlstreamhandlerfactory;</code>
<code> </code>
<code> </code><code>static</code> <code>{</code>
<code> </code><code>// this method can be called at most once in a given jvm.</code>
<code> </code><code>url.seturlstreamhandlerfactory(</code><code>new</code> <code>fsurlstreamhandlerfactory(););</code>
<code> </code><code>public</code> <code>static</code> <code>void</code> <code>main(string[] args) </code><code>throws</code> <code>exception {</code>
ok,不再報錯,成功運作。