Eliminar el archivo especificado del directorio de documentos

111

Quiero eliminar una imagen del directorio de documentos de mi aplicación. El código que he escrito para eliminar la imagen es:

 -(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];
}

Está funcionando parcialmente. Este código elimina el archivo del directorio, pero cuando estoy verificando el contenido en el directorio, todavía muestra el nombre de la imagen allí. Quiero eliminar completamente ese archivo del directorio. ¿Qué debo cambiar en el código para hacer lo mismo? Gracias


fuente
4
Es probable que arroje un error que ignoró, agregue la instancia NSError y verifíquela después de removeItemAtPath
Dmitry Shevchenko
1
use - (BOOL) fileExistsAtPath: (NSString *) ruta; para verificar si la imagen existe, si devuelve SÍ, significa que no se pudo eliminar
Guo Luchuan
Simplemente lo probé y definitivamente se eliminará y la eliminación se refleja en contentsOfDirectoryAtPath(es decir, no hay almacenamiento en caché de directorio involucrado aquí). Por lo tanto, debe tener algún error simple en el juego que debería ser evidente cuando mira el NSErrorcontenido.
Rob

Respuestas:

238

Revisé tu código. Me está funcionando. Verifique cualquier error que reciba usando el código modificado a continuación

- (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]);
  }
}
Anil Varghese
fuente
Puedo crear un archivo en el directorio de documentos, pero siempre obtengo un error cuando intento eliminarlo. ¿Tienes alguna idea?
Vadim
Lo resolví. El problema fue: creé un archivo nuevo sin ningún atributo y, según tengo entendido, le dio un atributo predeterminado NSFileImmutable YES. O algo así. Lo siento, no puedo mostrar las fuentes ahora. Pero el problema era trivial.
Vadim
¿Existe el archivo de verificación o no es necesario?
Sangram Shivankar
elimina el archivo del directorio pero aún muestra la imagen en las fotos del simulador
Sagar koyani
55

Swift 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)
  }}

Gracias a @Anil Varghese, escribí un código muy similar en 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)
  }
}
Roman Barzyczak
fuente
¿Por qué hacer que la función sea estática?
CalZone
Tu decides. No es necesario
Roman Barzyczak
¿Hay alguna manera de verificar si el archivo todavía existe antes / después de llamar a la función para asegurarse de que se haya eliminado?
Lucas
1
sí, claro: deje fileManager = FileManager.default si fileManager.fileExists (atPath: filePath!) {print ("ARCHIVO DISPONIBLE")} else {print ("ARCHIVO NO DISPONIBLE")}
Roman Barzyczak
11

Swift 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")
            }
        }
    }
}
FreeGor
fuente
8

En Swift tanto 3 como 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)
    }
    }

o este método puede eliminar todos los archivos locales

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)")
        }
    }
Sai Kumar Reddy
fuente
2
Agregue lo siguiente en la última línea en lugar de intentarlo directamente. do {try filemanager.removeItem (atPath: destinationPath) print ("Deleted")} catch {print ("Not Deleted")}
Abhirajsinh Thakore
5

En lugar de establecer el error en NULL, configúrelo en

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

esto le dirá si realmente está eliminando el archivo

Chris Loonam
fuente
3

Quiero eliminar mi sqlite db del directorio de documentos. Elimino el sqlite db con éxito mediante la siguiente respuesta

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");
    }
}
usuario3182143
fuente
2
    NSError *error;
    [[NSFileManager defaultManager] removeItemAtPath:new_file_path_str error:&error];
    if (error){
        NSLog(@"%@", error);
    }
Alex Spencer
fuente
1

Versión FreeGor convertida a 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")
            }
        }
    }
}
Andrea Leganza
fuente
0

Puede proteger dos veces la eliminación de su archivo con NSFileManager.defaultManager (). IsDeletableFileAtPath (PathName) A partir de ahora DEBE usar do {} catch {} ya que los métodos de error antiguos ya no funcionan. isDeletableFileAtPath () no es un "throws" (es decir, "public func removeItemAtPath (path: String) throws") por lo que no necesita el do ... catch

let killFile = NSFileManager.defaultManager()

            if (killFile.isDeletableFileAtPath(PathName)){


                do {
                  try killFile.removeItemAtPath(arrayDictionaryFilePath)
                }
                catch let error as NSError {
                    error.description
                }
            }
Hombre Montaña
fuente
0

Si está interesado en la forma api moderna, evitando NSSearchPath y filtrando archivos en el directorio de documentos, antes de la eliminación, puede hacer lo siguiente:

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)")
   }
}
Azon
fuente