2

我正在開發基於Scala的Apache Spark實現,用於將數據從遠程位置導入HDFS,然後將數據從HDFS導入到Hive表。fs.rename(新路徑(rawFileName),新路徑(processFileName))不起作用

用我的第一次火花的工作,我已經onboarded數據/文件到HDFS在一個位置說 -

HDFS://sandbox.hortonworks.com:8020 /數據/分析/生/文件夾

讓我們考慮一下,在上載CT_Click_Basic.csv和CT_Click_Basic1.csv.gz文件後,我在HDFS中有以下文件[在共享位置的文件名將是文件夾名稱,其內容將存在於部分xxxxx文件中]:

[根@沙箱〜]#HDFS DFS -ls /數據/分析/原料/ */ 實測值3項

-rw-R - R-- 3個chauhan.bhupesh HDFS 0 2017年7月27日15:02 /data/analytics/raw/CT_Click_Basic.csv/_SUCCESS

-rw-r - r-- 3 chauhan.bhupesh hdfs 8383 2017-07-27 15:02/data/analytics/raw/CT_Click_Basic的.csv /部分-00000

-rw-R - R-- 3個chauhan.bhupesh HDFS 8395 2017年7月27日15時02 /data/analytics/raw/CT_Click_Basic.csv/part-00001

找到2項目

-rw-R - R-- 3個chauhan.bhupesh HDFS 0 2017年7月27日15時02 /data/analytics/raw/CT_Click_Basic1.csv.gz/_SUCCESS

-rw-R-- R-- 3 chauhan.bhupesh HDFS 16588 2017年7月27日15:02 /data/analytics/raw/CT_Click_Basic1.csv.gz/part-00000

現在用我的另一個星火工作,我想移動這些文件是從/raw文件夾到/進程,然後最後到/歸檔文件根據在每個階段執行的任務在HDFS中的文件夾。

對於這樣做,我使用下面的代碼首先獲取所有存在的文件列表下方/生文件夾:

def listAllFilesFolderInDir(filePath:String,recursiveTraverse:Boolean,filePaths: ListBuffer[Path]) : ListBuffer[Path] = { 
val files = GlobalContext.hdfs.listStatus(new Path(filePath)) 
files.foreach { fileStatus => { 
      if(!fileStatus.isDirectory()) { 
       filePaths+=fileStatus.getPath()  
      } 
      else { 
       listAllFilesFolderInDir(fileStatus.getPath().toString(), recursiveTraverse, filePaths) 
      } 
     } 
    } 
    filePaths 
} 

,然後使用代碼以下行,我試圖重命名/移動文件在/原始文件夾到/處理文件夾:

var inputDir = "/data/analytics/raw" 
var outputDir = "/data/analytics/process" 
var filePaths = new ListBuffer[Path]() 
var pathArray = listAllFilesFolderInDir(inputDir, true, filePaths) 
val fs= <Getting hdfs FileSystem Instance Here> 
for(path<-pathArray){ 
    var pathSplit = path.toString().split("/") 
    var pathSplitSize = pathSplit.size 
    val rawFileName = inputDir + "/" + pathSplit(pathSplitSize-2) + "/" + pathSplit(pathSplitSize-1) 
    val processFileName = outputDir + "/" + pathSplit(pathSplitSize-2) + "/" + pathSplit(pathSplitSize-1) 
    fs.rename(new Path(rawFileName), new Path(processFileName)) 
} 

但我無法使用上面的書面代碼移動/重命名這些文件。我試着調試代碼,發現fs.rename()返回「false」。

請注意:我能夠實現文件重命名/移動,當我在/數據/分析/原始文件夾前CT.csv [或任何其他文件]手動複製任何文件 ,然後運行fs.rename ()但它不適用於Part-xxxxx文件。

有什麼我失蹤了嗎?

任何快速幫助將不勝感激。

問候, 布佩希

回答

0

最後,我有這個問題。實際上,我試圖將文件從/data/analytics/raw/folder.csv/part-xxxxx重命名爲/data/analytics/process/folder.csv/part-xxxxx,其中/ data/analytics/process在HDFS中存在,但「 folder.csv「不存在;因此在重命名時它會讓我失望。我在代碼中添加了以下行,並且對我來說工作得很好

var inputDir = "/data/analytics/raw" 
var outputDir = "/data/analytics/process" 
var filePaths = new ListBuffer[Path]() 
var pathArray = listAllFilesFolderInDir(inputDir, true, filePaths) 
val fs= <Getting hdfs FileSystem Instance Here> 
for(path<-pathArray){ 
    var pathSplit = path.toString().split("/") 
    var pathSplitSize = pathSplit.size 

    val rawFileName = inputDir + "/" + pathSplit(pathSplitSize-2) + "/" + pathSplit(pathSplitSize-1) 

    var processFolderName = outputDir + "/" + pathSplit(pathSplitSize-2) 
    var processFolderPath = new Path(processFolderName) 
    if(!(fs.exists(processFolderPath))) 
     fs.mkdirs(processFolderPath) 
    val processFileName = processFolderName + "/" + pathSplit(pathSplitSize-1) 
    fs.rename(new Path(rawFileName), new Path(processFileName)) 
} 
0

重命名可以返回false如果新路徑(rawFileName)不存在。
之前fs.rename做檢查文件是否存在:

if (fs.exists(somePath)) { 
fs.rename... 
} 

另一個原因可能是您嘗試重命名使用的人該文件。或者如果您嘗試重命名目錄中的某些文件可以被某人使用。
要確保這是根本原因嘗試在你的代碼重命名別的文件:

var inputDir = "/data/analytics/raw" 
var outputDir = "/data/analytics/process" 
var filePaths = new ListBuffer[Path]() 
var pathArray = listAllFilesFolderInDir(inputDir, true, filePaths) 
val fs= <Getting hdfs FileSystem Instance Here> 
for(path<-pathArray){ 
    var pathSplit = path.toString().split("/") 
    var pathSplitSize = pathSplit.size 
    val rawFileName = inputDir + "/" + pathSplit(pathSplitSize-2) + "/" + pathSplit(pathSplitSize-1) 
    val processFileName = outputDir + "/" + pathSplit(pathSplitSize-2) + "/" + pathSplit(pathSplitSize-1) 
    fs.rename(new Path("**/TESTDIR1**"), new Path("**/TESTDIR2**")) 
} 

如果此重命名將是成功的根本原因是真正的比賽狀態。