1

我知道,这个问题已经在很多地方被反复问过了。但我试图用谷歌搜索它并检查这个网站的解决方案,但仍然不足。即使使用了所有建议的解决方案,我仍然遇到这个问题。

基本上,我有两个独立的程序。每个程序的功能如下所示。

  1. ProgramA - 功能:不断更新到源文件(txt)
  2. ProgramB * - 功能:不断将源文件复制到目标位置。

使用 ProgramB,我想模拟做 ctrl+c 操作。因此,我正在尝试存档可以更新文件的位置,操作员也可以复制它。

这是我到目前为止所尝试的。下面是测试功能的示例程序。

程序A

static void Main(string[] args)
{
    // just prepare the data
    List<string> tempList = new List<string>();
    for(int i = 0; i < 50000; i++)
    {
        tempList.Add(string.Format("xxx_{0}", i.ToString()));
    }

    try
    {
        // just to simulate constart update
        for (int j = 0; j < 20000; j++)
        {
            using (FileStream file = new FileStream(tmpFilePath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite))
            {
                using (StreamWriter sw = new StreamWriter(file))
                {
                    foreach (string tmpName in tempList)
                    {
                        sw.WriteLine(tmpName);
                    }
                    sw.Close();
                }
                file.Close();
            }
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex);
        Console.ReadKey();
    }
}

程序B

static void Main(string[] args)
{
    string source = @"C:\temp\test.txt";
    string dest = @"C:\temp\dest\test.txt";
    while (true)
    {
        try
        {
            File.Copy(source, dest, true);
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex);
            Console.ReadKey();
        }
    }
}
4

3 回答 3

2

不要使用File.Copy,而是尝试使用FileStream并自己复制这些位。上面的代码会出错,因为File.Copy没有指定它对文件设置的 FileShare权限。

于 2012-04-16T15:45:00.880 回答
1

这应该是一个评论,但它太长了。它更多的是设计建议,而不是编码答案。

我假设这两个程序都在计时器上,或者在 FileSystemWatcher 上,这意味着缺乏可预测性。您无法保证何时调用程序 A 或何时调用程序 B,这与执行读/写操作所需的时间有关。

换句话说,由于设计中固有的缺乏控制,您无法预测文件何时会被锁定。

如果可能的话,我会把这两个程序结合起来。真的,我假设您想要的是在程序 A 完成写入后立即复制文件(程序 b 功能)。没有(明显的)原因您不能对其进行编码,以便程序 A 在写入文件后立即复制文件。

如果缺乏可预测性是问题的根源,请消除不可预测性。

于 2012-04-16T15:44:26.817 回答
1

如果这两个程序都在同一台机器上运行,您可以在写入和复制文件时使用命名互斥锁和锁定。

所以在程序A中你会添加

using (Mutex m = new Mutex(false,"MyMutex"))
{
    m.WaitOne();
    // Your file writing code
    m.ReleaseMutex();
}

并围绕您的文件复制代码做同样的事情。

于 2012-04-16T15:46:27.010 回答