<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
hadoop
服務已經啟動windows
環境,需要本地設定下hadoop
的環境變數本地設定hadoop的環境變數:
使用idea快速構建一個springoot的工程:
<dependency> <groupId>org.apache.hadoop</groupId> <artifactId>hadoop-client</artifactId> <version>3.1.3</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>1.7.30</version> </dependency>
為方便輸出紀錄檔,在springoot工程的resources目錄下新增一個log4j.properties 檔案
log4j.rootLogger=INFO, stdout log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m%n log4j.appender.logfile=org.apache.log4j.FileAppender log4j.appender.logfile.File=target/spring.log log4j.appender.logfile.layout=org.apache.log4j.PatternLayout log4j.appender.logfile.layout.ConversionPattern=%d %p [%c] - %m%n
以上所有的前置準備和程式碼執行環境就準備完畢了,下面就開始具體的API編碼操作hdfs檔案
public class HdfsClientTest { static Configuration configuration = null; static FileSystem fs = null; static { configuration = new Configuration(); configuration.set("dfs.client.use.datanode.hostname", "true"); try { fs = FileSystem.get(new URI("hdfs://IP:9000"), configuration, "hadoop"); } catch (IOException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } catch (URISyntaxException e) { e.printStackTrace(); } } /** * 建立目錄 */ public static void mkDir(String dirName){ try { fs.mkdirs(new Path(dirName)); } catch (IOException e) { e.printStackTrace(); } } public static void main(String[] args) throws Exception { //建立檔案目錄 mkDir("/songguo"); fs.close(); } }
執行這段程式,然後去web頁面觀察是否建立成功
/** * 上傳檔案到hdfs */ public static void uploadFile(String localPath,String hdfsPath){ try { fs.copyFromLocalFile(new Path(localPath), new Path(hdfsPath)); } catch (IOException e) { e.printStackTrace(); } } public static void main(String[] args) throws Exception { //建立檔案目錄 //mkDir("/songguo"); //上傳檔案到hdfs uploadFile("E:\haha.txt", "/songguo"); fs.close(); }
/** * 從hdfs上面下載檔案到本地 */ public static void loadFileFromDfs(String localPath,String hdfsPath){ try { fs.copyToLocalFile(false,new Path(hdfsPath),new Path(localPath),false); } catch (IOException e) { e.printStackTrace(); } } public static void main(String[] args) throws Exception { //建立檔案目錄 //mkDir("/songguo"); //上傳檔案到hdfs //uploadFile("E:\haha.txt", "/songguo"); //從hdfs上面下載檔案到本地 loadFileFromDfs("E:\haha_1.txt","/songguo/haha.txt"); fs.close(); }
執行這段程式,觀察E槽下是否成功下載到haha_1.txt
檔案
/** * 刪除hdfs檔案 * @param hdfsPath 檔案路徑 * @param recuDelete 是否遞迴刪除 */ public static void deleteFile(String hdfsPath,boolean recuDelete){ try { fs.delete(new Path(hdfsPath),recuDelete); } catch (IOException e) { e.printStackTrace(); } } public static void main(String[] args) throws Exception { //刪除檔案 deleteFile("/songguo/haha.txt",false); fs.close(); }
執行程式,觀察web介面的 /songguo目錄下檔案是否被刪除
/** * 檔案重新命名 * @param sourceFilePath * @param targetFilePath */ public static void renameFile(String sourceFilePath,String targetFilePath){ try { fs.rename(new Path(sourceFilePath),new Path(targetFilePath)); } catch (IOException e) { e.printStackTrace(); } } public static void main(String[] args) throws Exception { //檔案重新命名 renameFile("/qinguo/haha.txt","/qinguo/haha_rename.txt"); fs.close(); }
在 /qinguo 目錄下有一個haha.txt檔案,我們對它進行重新命名操作,執行上面的程式碼
這個和上面的API一樣,仍然使用rename
即可,比如將/songuo/haha_rename.txt
移動到 /sanguo目錄下 ,只需要在傳入的引數上面更改即可
//檔案重新命名 renameFile("/qinguo/haha_rename.txt","/sanguo/haha.txt");
上面是目錄下的具體檔案的更名和移動操作,對hdfs檔案目錄同樣適用
檢視檔案目錄:
public static void main(String[] args) throws Exception { RemoteIterator<LocatedFileStatus> files = fs.listFiles(new Path("/"), true); while (files.hasNext()){ //迭代目錄下的具體的檔案資訊 LocatedFileStatus fileStatus= files.next(); System.out.println(" ============== 檢視file的相關資訊 =============="); System.out.println("檔案路徑 : "+ fileStatus.getPath() ); System.out.println("檔案路徑名稱:" + fileStatus.getPath().getName()); System.out.println("檔案的許可權:" + fileStatus.getPermission()); System.out.println("檔案的用有人:" + fileStatus.getOwner()); System.out.println("檔案所在組資訊:" + fileStatus.getGroup()); System.out.println("檔案大小:" + fileStatus.getLen()); System.out.println("檔案修改時間:" + fileStatus.getModificationTime()); System.out.println("檔案副本資訊:" + fileStatus.getReplication()); System.out.println("檔案副本資訊:" + fileStatus.getReplication()); System.out.println("檔案塊大小:" + fileStatus.getBlockSize()); } fs.close(); }
當然,關於檔案資訊,hdfs還有更加豐富的資訊展示,有興趣的同學可以參考官網資料檢視
從目前對hdfs
的瞭解,我們知道檔案和資料夾是有區別的,下面來看如何使用api來進行判斷
public static void main(String[] args) throws Exception { FileStatus[] fileStatuses = fs.listStatus(new Path("/")); for (FileStatus fileStatus : fileStatuses) { boolean directory = fileStatus.isDirectory(); if(directory){ System.out.println(fileStatus.getPath().getName() + "是檔案目錄"); } boolean file = fileStatus.isFile(); if(file){ System.out.println(fileStatus.getPath().getName() + "是檔案"); } } fs.close(); }
可以看到,在根目錄下有3個目錄,和一個檔案,執行這段程式,看是否能給出正確的判斷呢
通過以上內容,我們基本上了解了如何基於JavaAPI 對hdfs檔案系統的常用操作,也是工作中經常會打交道的內容之一,更多的內容可以在此基礎上繼續深究
事實上,真正在idea中編寫程式碼實現的時候,並非這麼順利,遇到了不少坑,下面分享幾個本次編寫程式碼過程的幾個坑點,希望看到的同學可以合理規避開
解決方案:
1.在configuration那裡的地址,一定要確認和hdfs裡面的 dataNode
的那裡的設定保持一致
2.如果使用的是阿里雲或騰訊雲,那麼在 hdfs-site下面這裡,填上內網地址吧【生產環境下不建議這麼做】,反正我是碰到了
上傳檔案到hdfs目錄下,能上傳,但是上傳上去的檔案為空,並且控制檯報錯
報錯資訊如下:
其中比較關鍵的錯誤內容是下面這行:
org.apache.hadoop.ipc.RemoteException(java.io.IOException): File /songguo/haha.txt could only be written to 0 of the 1 minReplication nodes. There are 1 datanode(s) running and 1 node(s) are excluded in this operation.
at org.apache.hadoop.hdfs.server.blockmanagement.BlockManager.chooseTarget4NewBlock(BlockManager.java:2205)
網上給出了很多解答,但是基本上都是千篇一律,讓重新執行格式化命令,刪除namenode和datanode,然後重啟服務,其實只需要在程式碼中的configuration
那裡新增下面一行程式碼設定即可
configuration.set("dfs.client.use.datanode.hostname", "true");
直接給出我們的分析結果:
NameNode節點存放的是檔案目錄,也就是資料夾、檔名稱,本地可以通過公網存取 NameNode,所以可以進行資料夾的建立,當上傳檔案需要寫入資料到DataNode時,NameNode 和DataNode 是通過區域網進行通訊,NameNode返回地址為 DataNode 的私有 IP,本地無法存取
返回的IP地址無法返回公網IP,只能返回主機名,通過主機名與公網地址的對映便可以存取到DataNode
節點,問題將解決。
由於程式碼的設定的優先順序為最高,所以直接進行程式碼的設定
到此這篇關於Java操作hdfs檔案系統過程的文章就介紹到這了,更多相關Java操作hdfs檔案系統內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45