简体   繁体   English

C#将文件从本地计算机复制到远程共享失败

[英]C# Copying files from local machine to remote share failed

I'm copying xml files from local machine to remote share with simple way 我以简单的方式将xml文件从本地计算机复制到远程共享

DataTable dt = new DataTable();

// composing dt

string file = "test.xml";
string path = Path.Combine(@"C:\local\path", file);
string path2 = Path.Combine(@"\\path\to\remote\share", file);

if (File.Exists(path2)) File.Delete(path2);
dt.WriteXml(path);
File.Copy(path, path2);

I've noticed that sometimes copying unexpectedly ends in the middle of the file. 我注意到有时复制意外结束于文件中间。 So I have to compare source and target file to be sure that it has been fully copied. 因此,我必须比较源文件和目标文件,以确保它已被完全复制。

How to force successful copying without such comparing? 没有这样的比较,如何强制成功复制?

General causes in file copy is a timeout, access deny or network outage. 文件复制的一般原因是超时,拒绝访问或网络中断。 Put a try-catch around copy operation 1st to identify the reason behind in-between stopping. 尝试在复制操作1周围进行尝试捕获,以识别两次停止之间的原因。 If you can do the same operation to another local folder, and then successfully start copy to network, the only reason can be network instability. 如果您可以对另一个本地文件夹执行相同的操作,然后成功启动复制到网络,则唯一的原因可能是网络不稳定。 Try with a very small size file (some KBs) to see if the operation is successful. 尝试使用一个很小的文件(一些KB)来查看操作是否成功。 This will try to address the timeout issue due to file size. 这将尝试解决由于文件大小而引起的超时问题。

For very large files, you have to setup a sender and reciever apps. 对于非常大的文件,您必须设置一个发件人和收件人的应用程序。 You can use WCF Chunking or Streaming as described in this MSDN post https://blogs.msdn.microsoft.com/webapps/2012/09/06/wcf-chunking/ 您可以按照此MSDN帖子https://blogs.msdn.microsoft.com/webapps/2012/09/06/wcf-chunking/中的说明使用WCF Chunking或Streaming。

I would suggest comparing the check-sum of source and destination file to know whether the copy was successful or not. 我建议比较源文件和目标文件的校验和,以了解复制是否成功。 If unsuccessful, you may employ different strategies to either retry or fail-fast depending on what is the requirement. 如果不成功,则可以根据要求采用不同的策略重试或快速执行故障转移。

class Program
{
    private string fileName = "myFile.xml";
    private string sourcePath = @"d:\source\" + fileName;        
    private string destinationPath = @"d:\destination\" + fileName;


    static void Main(string[] args)
    {           
        (new Program()).Run();
    }

    void Run()
    {
        PrepareSourceFile();
        CopyFile();
    }

    private void PrepareSourceFile()
    {
        DataTable helloWorldData = new DataTable("HelloWorld");            
        helloWorldData.Columns.Add(new DataColumn("Greetings"));
        DataRow dr = helloWorldData.NewRow();
        dr["Greetings"] = "Ola!";
        helloWorldData.Rows.Add(dr);
        helloWorldData.WriteXml(sourcePath);
    }

    private void CopyFile()
    {
        int numberOfRetries = 3; // I want to retry at least these many times before giving up.
        do
        {   
            try
            {
                File.Copy(sourcePath, destinationPath, true);
            }
            finally
            {
                if (CompareChecksum())
                    numberOfRetries = 0;
            }


        } while (numberOfRetries > 0);
    }


    private bool CompareChecksum()
    {
        bool doesChecksumMatch = false;
        if (GetChecksum(sourcePath) == GetChecksum(destinationPath))
            doesChecksumMatch = true;
        return doesChecksumMatch;
    }

    private string GetChecksum(string file)
    {
        using (FileStream stream = File.OpenRead(file))
        {
            SHA256Managed sha = new SHA256Managed();
            byte[] checksum = sha.ComputeHash(stream);
            return BitConverter.ToString(checksum).Replace("-", String.Empty);
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM