2 votes

System.IO.File.Copy() produit System.IO.IOException: Le nom de réseau spécifié n'est plus disponible

J'ai un service Windows (C# .Net 3.5) qui récupère des données à partir d'un partage réseau et les copie sur l'hôte du service.

La taille des données copiées varie de 50 Ko à 750 Mo, et le nombre de fichiers copiés varie. Dans environ 20% des copies, j'obtiens une System.IO.IOException : Le nom du réseau spécifié n'est plus disponible.

Ma google-fu échoue à trouver une réponse sur ce qui pourrait causer cela lors d'une File.Copy. Quelqu'un a-t-il déjà vu/résolu cela auparavant ?

Voici la méthode récursive qui effectue la copie. L'exception se produit à la ligne File.Copy(fromFile, toFile, overwrite);

private static int RecursiveCopyDirectory(string from, string to, bool merge, bool overwrite, int depth)
    {
        depth++;

        if (!from.EndsWith(Path.DirectorySeparatorChar.ToString()))
        {
            to += Path.DirectorySeparatorChar;
        }
        if (!to.EndsWith(Path.DirectorySeparatorChar.ToString()))
        {
            to += Path.DirectorySeparatorChar;
        }

        System.Diagnostics.Debug.WriteLine(string.Format("RecursiveDirectoryCopy( {0}, {1}, {2} )", from, to, merge));
        if (Directory.Exists(to))
        {
            if (!merge)
            {
                return (int)EventEnum.FileSystemError_DirectoryAlreadyExists;
            }
        }
        else
        {
            Directory.CreateDirectory(to);
        }

        string[] directories = Directory.GetDirectories(from);

        foreach (string fromDirectory in directories)
        {
            string[] fromDirectoryComponents = fromDirectory.Split(Path.DirectorySeparatorChar);
            string toDirectory = to + fromDirectoryComponents[fromDirectoryComponents.Length - 1];
            RecursiveCopyDirectory(fromDirectory, toDirectory, merge, overwrite, depth);
        }

        string[] files = Directory.GetFiles(from);

        foreach (string fromFile in files)
        {
            string fileName = Path.GetFileName(fromFile);
            //System.Diagnostics.Debug.WriteLine(string.Format("Name: {0}", to + fileName));    
            string toFile = to + fileName;

            File.Copy(fromFile, toFile, overwrite);
        }

        return (int)EventEnum.GeneralSuccess;
    }

4voto

Priyank Points 4927

File.Copy() ouvre des flux soulignés. Vous avez peut-être perdu la connexion pendant que File.Copy() est en cours. Ainsi, il ne peut pas vider et fermer le flux.

Une possibilité de récupération consiste à utiliser la classe FileStream et à appeler Win32 API CloseHandle lorsque cette exception se produit, cela libérera la poignée de fichier OS afin que vous puissiez rouvrir le fichier.

[ DllImport("Kernel32") ]
public static extern bool CloseHandle(IntPtr handle);

FileStream fs;
try {
...
}

catch(IOException)
{
// Si la ressource n'est plus disponible, ou impossible d'écrire à.....
if(...)
CloseHandle(fs.Handle);
}

Aussi, MSDN recommande de ne pas se fier à overwrite. Essayez de supprimer le fichier existant et de créer un nouveau lors de leur copie.

File.Copy(..., ..., TRUE) ne fonctionne pas correctement.

Soyez très prudent avec cette méthode, car Overwrite = True ne fonctionne PAS correctement.

J'avais un fichier de destination existant qui contenait des informations à l'intérieur qui ont été étrangement préservées et transférées vers le fichier source censé les copier. Cela devrait être impossible, mais je l'ai confirmé moi-même.

1voto

Chris Snowden Points 2851

L'erreur semble indiquer que la connexion au réseau est perdue en cours de route et n'a probablement rien à voir avec le code lui-même. Si la copie du même dossier réussit parfois et échoue d'autres fois, cela confirmerait que ce n'est pas le code à blâmer et que cela doit être un problème d'accès aux ressources.

1voto

JMorgan Points 555

Il s'avère que le client qui utilisait ce logiciel exécutait deux instances simultanément, contre le même jeu de données. Une fois l'instance redondante arrêtée, l'erreur a été résolue. Merci à tous ceux qui ont répondu.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X