2017-07-10 51 views
2

我嘗試遍歷文件夾並根據文件擴展名創建文件夾,然後在該文件夾中複製所有相關文件。但出於意想不到的原因,只有一個文件被複制,並在下一個文件切換腳本。我認爲基礎很好,因爲文件夾已正確創建並且一個文件被複制。那麼爲什麼所有其他人都不復制?爲什麼不是在創建文件夾後複製的所有文件

有人可以幫我弄清楚爲什麼?

import os 
import shutil 

dir = "/home/user/Documents/utils/testFindAndCopy" 
target = "/home/user/Documents/utils/result" 

def createDir(target): 
    os.makedirs(str(target)) 

def copyFiles(file, target): 
    shutil.copy2(file, target) 


for subdir, dirs, files in os.walk(dir): 
    for file in files: 
     filepath = subdir + os.sep + file 
     folderName = file.split('.') 
     targetDir = target + '/' + str(folderName[1]) 
     try: 
      if os.path.exists(str(folderName)): 
       print(folderName[1]) 
       print(targetDir) 
       print(filepath) 
       copyFiles(filepath, targetDir) 
      else: 
       createDir(str(targetDir)) 
       copyFiles(filepath, targetDir) 
       print(folderName[1]) 
       print(targetDir) 
       print(filepath) 
     except OSError, e: 
      if e.errno != 17: 
       raise 
       # time.sleep might help here 
      pass 
+0

copyFiles可能會覆蓋現有文件。你爲什麼不使用'os.rename'? –

+0

@COLDSPEED我需要複製源目錄中的所有文件。並且所有文件都有不同的名稱 – charter77

+0

@COLDSPEED'os.rename'相當於bash中的'mv',只是移動文件,不是? – cmaher

回答

1

這裏有幾個錯誤。文件和目錄操作很棘手,你需要非常小心。

您應該使用os.path.join來構建文件路徑。

在「。」上分割文件名時,返回的值是一個列表,而不是一個字符串。這是你的變數folderName - 不是一個精心挑選的名字。您的表達式os.path.exists(str(folderName))將始終爲False,因爲str()函數不會重構列表中的簡單字符串。

文件名可以包含多個點。當你使用folderName[1]作爲你的目錄名時,你假設你的情況下沒有這樣的文件名。 如果您使用folderName[-1],您將始終獲得文件名的最後一部分。

如果您在已存在的目錄上調用mkdir/makedirs,則會在此時引發OSError異常。然後沒有文件複製發生。

shutil.copy2複製一個文件,即使您通過名爲copyFiles的函數調用它。

你抓到一個OSError,但除非它是17,否則不要做任何事情。所以你不會知道你的腳本是否捕捉錯誤。

您希望您的主循環是這樣的:

for subdir, dirs, files in os.walk(dir): 
    for file in files: 
     filepath = os.path.join(subdir, file) 
     folderName = file.split('.') 
     targetDir = os.path.join(target, folderName[-1]) 
     try: 
      print(targetDir, filepath, os.path.exists(targetDir)) 
      if not os.path.exists(targetDir): 
       createDir(targetDir) 
      shutil.copy2(filepath, targetDir) 
+0

感謝您的回答,它非常清晰。我理解所有觀點,並且瞭解我的錯誤很有幫助。我應用了你的建議,它的工作正常! 非常感謝! – charter77

+0

很高興爲你效勞。如果您不介意,請接受答案。 –

+0

完成和thx再次 – charter77

1

使用shutil.copytree(src, dst)

你甚至不需要用它走過文件樹。只需將頂級目錄設置爲源。

docs

遞歸複製在SRC紮根整個目錄樹,返回的目標目錄。由dst命名的目標目錄不能存在;它將被創建以及丟失的父目錄。使用copystat()複製目錄的權限和時間,使用shutil.copy2()複製單個文件。

相關問題