【问题标题】:Delete specified file from document directory从文档目录中删除指定文件
【发布时间】:2013-02-07 16:48:28
【问题描述】:

我想从我的应用文档目录中删除一张图片。我为删除图像而编写的代码是:

 -(void)removeImage:(NSString *)fileName
{
    fileManager = [NSFileManager defaultManager];
    paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    documentsPath = [paths objectAtIndex:0];
    filePath = [documentsPath stringByAppendingPathComponent:[NSString stringWithFormat:@"%@", fileName]];
    [fileManager removeItemAtPath:filePath error:NULL];
    UIAlertView *removeSuccessFulAlert=[[UIAlertView alloc]initWithTitle:@"Congratulation:" message:@"Successfully removed" delegate:self cancelButtonTitle:@"Close" otherButtonTitles:nil];
    [removeSuccessFulAlert show];
}

它的部分工作。此代码从目录中删除文件,但是当我检查目录中的内容时,它仍然在那里显示图像名称。我想从目录中完全删除该文件。我应该在代码中更改什么来做同样的事情?谢谢

【问题讨论】:

  • 可能会抛出你忽略的错误,添加 NSError 实例并在 removeItemAtPath 之后检查它
  • 使用 - (BOOL)fileExistsAtPath:(NSString *)path;检查图像是否存在,如果返回YES,则表示您的删除失败
  • 刚刚对其进行了测试,它肯定会被删除,并且该删除反映在 contentsOfDirectoryAtPath 中(即此处不涉及目录缓存)。所以你一定有一些简单的错误,当你查看NSError的内容时应该会很明显。

标签: ios objective-c xcode nsdocumentdirectory


【解决方案1】:

我检查了你的代码。它对我有用。使用以下修改后的代码检查您遇到的任何错误

- (void)removeImage:(NSString *)filename
{
  NSFileManager *fileManager = [NSFileManager defaultManager];
  NSString *documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];

  NSString *filePath = [documentsPath stringByAppendingPathComponent:filename];
  NSError *error;
  BOOL success = [fileManager removeItemAtPath:filePath error:&error];
  if (success) {
      UIAlertView *removedSuccessFullyAlert = [[UIAlertView alloc] initWithTitle:@"Congratulations:" message:@"Successfully removed" delegate:self cancelButtonTitle:@"Close" otherButtonTitles:nil];
      [removedSuccessFullyAlert show];
  }
  else
  {
      NSLog(@"Could not delete file -:%@ ",[error localizedDescription]);
  }
}

【讨论】:

  • 我可以在 Document 目录中创建文件,但尝试删除它时总是出错。你有什么想法吗?
  • 我解决了。问题是:我创建了没有任何属性的新文件,据我所知,它提供了一个默认属性 NSFileImmutable YES。或类似的东西。抱歉,现在无法显示来源。但问题是微不足道的。
  • 检查文件是否存在有必要吗?
  • 它从目录中删除文件,但它仍然在模拟器的照片中显示图像
【解决方案2】:

斯威夫特 3.0:

func removeImage(itemName:String, fileExtension: String) {
  let fileManager = FileManager.default
  let nsDocumentDirectory = FileManager.SearchPathDirectory.documentDirectory
  let nsUserDomainMask = FileManager.SearchPathDomainMask.userDomainMask
  let paths = NSSearchPathForDirectoriesInDomains(nsDocumentDirectory, nsUserDomainMask, true)
  guard let dirPath = paths.first else {
      return
  }  
  let filePath = "\(dirPath)/\(itemName).\(fileExtension)"
  do {
    try fileManager.removeItem(atPath: filePath)
  } catch let error as NSError {
    print(error.debugDescription)
  }}

感谢@Anil Varghese,我在 swift 2.0 中编写了非常相似的代码:

static func removeImage(itemName:String, fileExtension: String) {
  let fileManager = NSFileManager.defaultManager()
  let nsDocumentDirectory = NSSearchPathDirectory.DocumentDirectory
  let nsUserDomainMask = NSSearchPathDomainMask.UserDomainMask
  let paths = NSSearchPathForDirectoriesInDomains(nsDocumentDirectory, nsUserDomainMask, true)
  guard let dirPath = paths.first else {
    return
  }
  let filePath = "\(dirPath)/\(itemName).\(fileExtension)"
  do {
    try fileManager.removeItemAtPath(filePath)
  } catch let error as NSError {
    print(error.debugDescription)
  }
}

【讨论】:

  • 为什么要将函数设为静态?
  • 这取决于你。没必要
  • 有没有办法在调用函数之前/之后检查文件是否仍然存在以确保它已被删除?
  • 是肯定的:让 fileManager = FileManager.default if fileManager.fileExists(atPath: filePath!) { print("FILE AVAILABLE") } else { print("FILE NOT AVAILABLE") }
  • Swift 3.0 以上版本在 Swift 5.2 上运行良好。谢谢!
【解决方案3】:

斯威夫特 2.0:

func removeOldFileIfExist() {
    let paths = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask, true)
    if paths.count > 0 {
        let dirPath = paths[0]
        let fileName = "someFileName"
        let filePath = NSString(format:"%@/%@.png", dirPath, fileName) as String
        if NSFileManager.defaultManager().fileExistsAtPath(filePath) {
            do {
                try NSFileManager.defaultManager().removeItemAtPath(filePath)
                print("old image has been removed")
            } catch {
                print("an error during a removing")
            }
        }
    }
}

【讨论】:

    【解决方案4】:

    在 Swift 3 和 4 中

     func removeImageLocalPath(localPathName:String) {
                let filemanager = FileManager.default
                let documentsPath = NSSearchPathForDirectoriesInDomains(.documentDirectory,.userDomainMask,true)[0] as NSString
                let destinationPath = documentsPath.appendingPathComponent(localPathName)
     do {
            try filemanager.removeItem(atPath: destinationPath)
            print("Local path removed successfully")
        } catch let error as NSError {
            print("------Error",error.debugDescription)
        }
        }
    

    此方法可以删除所有本地文件

    func deletingLocalCacheAttachments(){
            let fileManager = FileManager.default
            let documentsURL = fileManager.urls(for: .documentDirectory, in: .userDomainMask)[0]
            do {
                let fileURLs = try fileManager.contentsOfDirectory(at: documentsURL, includingPropertiesForKeys: nil)
                if fileURLs.count > 0{
                    for fileURL in fileURLs {
                        try fileManager.removeItem(at: fileURL)
                    }
                }
            } catch {
                print("Error while enumerating files \(documentsURL.path): \(error.localizedDescription)")
            }
        }
    

    【讨论】:

    • 在最后一行添加以下内容,而不是直接尝试。 do { try filemanager.removeItem(atPath:destinationPath) print("Deleted") } catch { print("Not Deleted") }
    【解决方案5】:

    不要将错误设置为 NULL,而是将其设置为

    NSError *error;
    [fileManager removeItemAtPath:filePath error:&error];
    if (error){
    NSLog(@"%@", error);
    }
    

    这会告诉你它是否真的在删除文件

    【讨论】:

      【解决方案6】:

      我想从文档目录中删除我的 sqlite db。我通过以下答案成功删除了 sqlite db

      NSString *strFileName = @"sqlite";
      NSFileManager *fileManager = [NSFileManager defaultManager];
      NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
      NSString *documentsDirectory = [paths objectAtIndex:0];
      
      NSArray *contents = [fileManager contentsOfDirectoryAtPath:documentsDirectory error:NULL];
      NSEnumerator *enumerator = [contents objectEnumerator];
      NSString *filename;
      while ((filename = [enumerator nextObject])) {
          NSLog(@"The file name is - %@",[filename pathExtension]);
          if ([[filename pathExtension] isEqualToString:strFileName]) {
             [fileManager removeItemAtPath:[documentsDirectory stringByAppendingPathComponent:filename] error:NULL];
              NSLog(@"The sqlite is deleted successfully");
          }
      }
      

      【讨论】:

        【解决方案7】:
            NSError *error;
            [[NSFileManager defaultManager] removeItemAtPath:new_file_path_str error:&error];
            if (error){
                NSLog(@"%@", error);
            }
        

        【讨论】:

          【解决方案8】:

          FreeGor 版本转换为 Swift 3.0

           func removeOldFileIfExist() {
              let paths = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.documentDirectory, FileManager.SearchPathDomainMask.userDomainMask, true)
              if paths.count > 0 {
                  let dirPath = paths[0]
                  let fileName = "filename.jpg"
                  let filePath = NSString(format:"%@/%@", dirPath, fileName) as String
                  if FileManager.default.fileExists(atPath: filePath) {
                      do {
                          try FileManager.default.removeItem(atPath: filePath)
                          print("User photo has been removed")
                      } catch {
                          print("an error during a removing")
                      }
                  }
              }
          }
          

          【讨论】:

            【解决方案9】:

            您可以使用 NSFileManager.defaultManager().isDeletableFileAtPath(PathName) 双重保护您的文件删除到目前为止,您必须使用 do{}catch{},因为旧的错误方法不再有效。 isDeletableFileAtPath() 不是“抛出”(即 “公共 func removeItemAtPath(路径:字符串)抛出”) 所以它不需要 do...catch

            let killFile = NSFileManager.defaultManager()
            
                        if (killFile.isDeletableFileAtPath(PathName)){
            
            
                            do {
                              try killFile.removeItemAtPath(arrayDictionaryFilePath)
                            }
                            catch let error as NSError {
                                error.description
                            }
                        }
            

            【讨论】:

              【解决方案10】:

              如果你对现代 api 方式感兴趣,避免 NSSearchPath 和过滤文档目录中的文件,在删除之前,你可以这样做:

              let fileManager = FileManager.default
              let keys: [URLResourceKey] = [.nameKey, .isDirectoryKey]
              let options: FileManager.DirectoryEnumerationOptions = [.skipsHiddenFiles, .skipsPackageDescendants]
              guard let documentsUrl = fileManager.urls(for: .documentDirectory, in: .userDomainMask).last,
                    let fileEnumerator = fileManager.enumerator(at: documentsUrl,
                                                                includingPropertiesForKeys: keys,
                                                                options: options) else { return }
              
              let urls: [URL] = fileEnumerator.flatMap { $0 as? URL }
                                              .filter { $0.pathExtension == "exe" }
              for url in urls {
                 do {
                    try fileManager.removeItem(at: url)
                 } catch {
                    assertionFailure("\(error)")
                 }
              }
              

              【讨论】:

                猜你喜欢
                • 2023-04-03
                • 2011-08-06
                • 2011-08-14
                • 1970-01-01
                • 2015-10-16
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多