FileManager.default.contentsOfDirectory 在 swift 3 中失败

Posted

技术标签:

【中文标题】FileManager.default.contentsOfDirectory 在 swift 3 中失败【英文标题】:FileManager.default.contentsOfDirectory fail in swift 3 【发布时间】:2017-01-17 14:03:23 【问题描述】:

我在目标 -c 中有代码,如下所示:

- (NSArray *)PDFInDirectory:(NSString *)directoryPath

    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSArray *dirContents = [fileManager contentsOfDirectoryAtPath:directoryPath
                                                            error:nil];
    return [dirContents filteredArrayUsingPredicate:self.pdfPredicate];

我想以这种方式翻译成swift 3:

func PDFInDirectory(directoryPath: String) -> NSArray 
     let dirContents = try? FileManager.default.contentsOfDirectory(atPath: directoryPath) as NSArray
     return dirContents!.filtered(using: ppdfPredicate()) as NSArray

但是当我运行它时失败:

let dirContents = try? FileManager.default.contentsOfDirectory(atPath: directoryPath) as NSArray

这里是所有代码:

import UIKit

class PdfFilePicker: UITableViewController 
    // Variable 
    var NNOTIFICATION_NAME_SELECTED_PDF = "VSSelectedPDFFile"
    var documentsDirectory = ""
    var inboxDirectory = ""
    var pdfPredicate: NSPredicate?
    var pdfFiles: NSMutableArray = []
    func ddocumentsDirectory() -> String 
        if self.documentsDirectory == "" 
        let paths = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true) as NSArray
            self.documentsDirectory = paths.object(at: 0) as! String
        
        print("Document directory call")
    return documentsDirectory
    

    func ppdfPredicate() -> NSPredicate 

        if self.pdfPredicate == nil 
            self.pdfPredicate = NSPredicate(format: "self ENDSWITH '.pdf'")
        
        return pdfPredicate!
    
    func ppdfFiles() -> NSMutableArray 
        if self.pdfFiles == [] 
            self.pdfFiles = [20]
        
        return  pdfFiles
    
    func PDFInDirectory(directoryPath: String) -> NSArray 
        // Here is the probelm.
        print("My dir is \(directoryPath)")
        do 
            let dirContents = try? FileManager.default.contentsOfDirectory(atPath: directoryPath) as NSArray
            print("my dirContents \(dirContents)")
            return dirContents!.filtered(using: ppdfPredicate()) as NSArray
         catch 
            print("my dirPath \(directoryPath)")
        
        return []
    
    func populateAllPdfsFromDocumentsAndInboxDirectory() 
        self.ppdfFiles().removeAllObjects()
        self.populatePDFfilesInFolder(path: self.ddocumentsDirectory())
        let inboxDirectory : String = URL(fileURLWithPath: self.ddocumentsDirectory()).appendingPathComponent("Inbox").absoluteString
        self.populatePDFfilesInFolder(path: inboxDirectory)
        self.sortPdfFilesArray()
    
    // Finished until here. // Checkif it crash probably yes
    func populatePDFfilesInFolder(path: String) 
        var isDir: ObjCBool = false
        let fileManager = FileManager.default
        let isExist = fileManager.fileExists(atPath: path, isDirectory: &isDir)
        if isExist == false   
            print("Read file manager successfully")
            let array = self.PDFInDirectory(directoryPath: path)
            print("PDF Steve")
            if array.count > 0 
                for fileName: String in array as! Array 
                    let test : String = URL(fileURLWithPath: path).appendingPathComponent(fileName).absoluteString
                    self.ppdfFiles().adding(test)
                
            
        
    
    // Can be crash in closure
    func sortPdfFilesArray() 
        if self.ppdfFiles().count > 0 
            self.ppdfFiles().sort(comparator: ( a: Any, b: Any) -> ComparisonResult in
                if !(a is String) || !(b is String) 
                  return ((a as! String).compare(b as! String))
                 else 
                    let aString: String? = (a as? String)
                    let bString: String? = (b as? String)
                    return (aString?.compare(bString!, options: .caseInsensitive))!
                
            )
        
    
    override func viewDidLoad() 
        super.viewDidLoad()
        self.title = NSLocalizedString("SELECT_PDF", comment: "")
    
    override func didReceiveMemoryWarning() 
        super.didReceiveMemoryWarning()
    
    override func viewWillAppear(_ animated: Bool) 
        super.viewWillAppear(animated)
        self.populateAllPdfsFromDocumentsAndInboxDirectory()
    
    // Steve Note: Table view data source
    override func numberOfSections(in tableView: UITableView) -> Int 
        return 1
    
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
        return self.ppdfFiles().count
    
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
        var cell  = tableView.dequeueReusableCell(withIdentifier: "Cell")
        if cell == nil 
            cell = UITableViewCell(style: .default, reuseIdentifier: "Cell")
        
        // steve note Not sure about object
        cell?.imageView?.image = UIImage(named: "Icon-PDF.png")
        cell?.textLabel?.text = (self.ppdfFiles().object(at: indexPath.row) as AnyObject).lastPathComponent
        return cell!
    
    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) 
        NotificationCenter.default.post(name: Notification.Name(rawValue: NNOTIFICATION_NAME_SELECTED_PDF), object: self.ppdfFiles().object(at: indexPath.row))
    
    override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) 
        if editingStyle == .delete 
            self.deleteFile(atPath: self.ppdfFiles().object(at: indexPath.row) as! String)
            self.ppdfFiles().removeObject(at: indexPath.row)
            self.tableView.reloadData()
        
    
    func deleteFile(atPath path: String) 
        let fileManager = FileManager.default
        if fileManager.fileExists(atPath: path, isDirectory: nil) 
            do 
                try fileManager.removeItem(atPath: path)
             catch 
                print("File Manager Remove Item at Path crash")
            
        
    

任何帮助表示赞赏。

【问题讨论】:

错误是什么? 您可能传递了无效的路径字符串。你可以发布你正在使用的路径吗? 嗨@LeoDabus,我只是在下面发布所有代码。 ***.com/a/27722526/2303865 问题是您使用 absoluteString 来获取 fileURL 路径。将.absoluteString 更改为.path 【参考方案1】:

更新示例

您需要捕获在使用“try”时可能产生的异常 这是我在当前项目中使用的示例。我有许多文件存储在一个名为 templates 的文件夹中,这段代码确实返回了一个文件名数组 - 只要那里实际上已经有一些东西

    let dirPaths = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)
    let documentDirectory = dirPaths[0]
    let folder = documentDirectory.appending("/templates")

    do
    
        let fileList = try FileManager.default.contentsOfDirectory(atPath: folder)
        for file in fileList
        
            fileListArray.append(file)
        
        return fileListArray
    
    catch
    
        addLogText(error.localizedDescription)
        return []
    

可能值得检查您是否将文件写入您正在从中读取文件的同一目录 - 您是否尝试过确认文件已创建然后立即读取它们?

【讨论】:

以上是关于FileManager.default.contentsOfDirectory 在 swift 3 中失败的主要内容,如果未能解决你的问题,请参考以下文章