System.IO.File.Copy()生成System.IO.IOException:指定的网络名称不再可用

时间:2011-04-21 14:12:48

标签: c# .net-3.5 .net

我有一个Windows服务(C#.Net 3.5),它从网络共享中获取数据并复制到服务的主机。

复制的数据大小从50KB到750MB不等,复制的文件数也各不相同。在大约20%的副本中我收到System.IO.IOException:指定的网络名称不再可用。

我的google-fu未能在File.Copy中找到可能导致此问题的答案。有没有人见过/解决过这个问题?

这是执行复制的递归方法。在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;
    }

3 个答案:

答案 0 :(得分:4)

File.Copy()打开下划线流。 File.Copy()正在进行时,您可能已丢失连接。因此,它无法刷新和关闭流。

从中恢复的一种可能性是使用FileStream类和 致电Win32 API CloseHandle when such exception occurs,这样做会释放 操作系统文件句柄,以便您可以重新打开该文件。

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

FileStream fs;
try {
...
}

catch(IOException)
{
// If resource no longer available, or unable to write to.....
if(...)
CloseHandle(fs.Handle);
}

此外,MSDN recommends not to rely on overwriteTry deleting existing file and creating new one when copying them.

File.Copy(..., ..., TRUE) does not work properly.

Be very careful with this method, as the Overwrite = True does NOT work properly.

I had an existing destination file that had some information inside it that was somehow preserved and carried over to the source file that was supposed to copy over it.  This should be impossible, but I confirmed it for myself.

答案 1 :(得分:1)

错误似乎表明网络连接中途丢失,可能与代码根本没有关系。如果相同的文件夹副本有时成功并且其他时间失败,那么这将备份它不是责备的代码并且必须是资源访问问题。

答案 2 :(得分:1)

事实证明,正在使用该软件的客户正在针对同一数据集同时运行它的两个实例。一旦冗余实例停止,它就解决了错误。谢谢所有回答的人。