Pregunta

Estoy aprendiendo C # (se han jugueteando con él durante unos 2 días ahora) y he decidido que, para inclinarse propósitos, voy a reconstruir una vieja aplicación que hice en VB6 para la sincronización de archivos (generalmente a través de una red) .

Cuando escribí el código en VB 6, funcionó aproximadamente así:

  1. Crear un Scripting.FileSystemObject
  2. Crear objetos de directorio para la fuente y el destino
  3. Crear archivo de lista de objetos para el origen y el destino
  4. Iterar a través del objeto de origen, y comprobar para ver si existe en el destino
    • si no, crearlo
    • Si es así, comprobar para ver si la versión es más reciente fuente / grande, y si es así, sobrescribir el otro

Hasta ahora, esto es lo que tengo:

private bool syncFiles(string sourcePath, string destPath) {
    DirectoryInfo source = new DirectoryInfo(sourcePath);
    DirectoryInfo dest = new DirectoryInfo(destPath);

    if (!source.Exists) {
        LogLine("Source Folder Not Found!");
        return false;
    }

    if (!dest.Exists) {
        LogLine("Destination Folder Not Found!");
        return false;
    }

    FileInfo[] sourceFiles = source.GetFiles();
    FileInfo[] destFiles = dest.GetFiles();

    foreach (FileInfo file in sourceFiles) {
        // check exists on file
    }

    if (optRecursive.Checked) {
        foreach (DirectoryInfo subDir in source.GetDirectories()) {
            // create-if-not-exists destination subdirectory
            syncFiles(sourcePath + subDir.Name, destPath + subDir.Name);
        }
    }
    return true;
}

He leído ejemplos que parecen abogar por el uso de los objetos FileInfo o DirectoryInfo hacer comprobaciones con el "existe" la propiedad, pero estoy buscando específicamente una forma de buscar una colección / lista existente de archivos, y no vivir cheques a el sistema de archivo para cada archivo, ya que voy a estar haciendo así que a través de la red y en constante que se remonta a un directorio de varios miles de archivos es lento lento lento.

Gracias de antemano.

¿Fue útil?

Solución

El método GetFiles() sólo va a llegar archivos que no existen. No tiene seguridad de archivos al azar que no existe. Así que todo lo que tiene que hacer es comprobar si existe en la otra lista.

Algo en las líneas de esto podría funcionar:

var sourceFiles = source.GetFiles();
var destFiles = dest.GetFiles();

foreach (var file in sourceFiles)
{
    if(!destFiles.Any(x => x.Name == file.Name))
    {
        // Do whatever
    }
}

Nota: Hay, por supuesto, no es garantía de que algo no ha cambiado después de haber hecho las llamadas a GetFiles(). Por ejemplo, un archivo podría haber sido eliminado o cambiado de nombre si se intenta copiar más tarde.


tal vez podría hacer más agradable de alguna manera con la Except método o algo similar. Por ejemplo algo como esto:

var sourceFiles = source.GetFiles();
var destFiles = dest.GetFiles();

var sourceFilesMissingInDestination = sourceFiles.Except(destFiles, new FileNameComparer());

foreach (var file in sourceFilesMissingInDestination)
{
    // Do whatever
}

Cuando el FileNameComparer se lleva a cabo de esta manera:

public class FileNameComparer : IEqualityComparer<FileInfo>
{
    public bool Equals(FileInfo x, FileInfo y)
    {
        return Equals(x.Name, y.Name);
    }


    public int GetHashCode(FileInfo obj)
    {
        return obj.Name.GetHashCode();
    }
}     

No comprobado sin embargo: p

Otros consejos

Un pequeño detalle, en lugar de

 sourcePath + subDir.Name

Me gustaría utilizar

 System.IO.Path.Combine(sourcePath, subDir.Name)

Ruta hace, OS operaciones independientes fiables sobre archivo y de foldernames.

También noto optRecursive.Checked apareciendo de la nada. Como cuestión de buen diseño, hacen que un parámetro:

bool syncFiles(string sourcePath, string destPath, bool checkRecursive)

Y ya que mencionas puede ser utilizado para un gran número de archivos, mantener un ojo hacia fuera para .NET 4, que tiene un reemplazo para IEnumerable GetFiles () que le permitirá procesar esto de una forma de streaming.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top