C# - 不时地检查文件是否存在,并从中读取(C# - from time to time chec

2019-07-31 21:28发布

我创建这将不定期检查,如果有一定的存在窗口服务,如果确实如此,那么从中读取,将数据发送到服务器和文件移动到另一个文件夹。 文件的大小约为1-3 MB。

我想我会用System.Threading.Timer这里来检查文件是否存在。 你怎么看呢?

而另一个问题。 如果一个文件被复制,然后我的应用程序不能读取它。 应该等到复制完成。 只有在此之后,必须从中读取并执行其他活动。

所以问题:

1)是一个正确的决定使用System.Threading.Timer

2)我如何检查文件被复制并等待它完成?

3)我必须使用多线程?

Answer 1:

我用通常的方法是监视文件夹/ s的FileSystemWatcher的(或相关的API如果不是.NET托管),并尝试以确保操作只有在源/目标文件夹进行的移动/文件夹重命名之间在同一个物理驱动器上,并删除。 如果你想添加一个文件,打开/写/平/关闭它ITO目标文件系统驱动器上的临时文件夹,然后才移动/重命名文件夹被监视。 至关重要的是,临时文件夹是在同一个物理驱动器作为目标文件夹,以便它可以是移动/无数据复制重命名。

这适用于非管理系统,而不是试图在C#中,但看不出有任何理由不上班确定。

涉及持续轮询和/或检查文件大小的其他解决方案都只是不方便,不灵活,浪费,混乱和延迟缠身的最好的。

多线程 - 任何远程文件系统或许是肯定的。 网络文件调用往往对unrechability等很长的超时等阻塞调用者什么似乎像永远发出错误/异常之前。 如果你想获得什么都做,你应该线头脱落了很多,除非你的用户可以容忍“沙漏应用”,与Windows变得反应迟钝,消失到后,让灰色显示和操作系统提供关闭它们。

哦,还有另一件事 - 最好在启动时去清洗。 东西可以在任何时候出问题了,所以跑起来时从清理临时文件夹等任何挥之不去的垃圾。



Answer 2:

我想我会用System.Threading.Timer这里来检查文件是否存在。 你怎么看呢?

我想你不妨来看看在FileSystemWatcher类文件创建时将通知您,并使用定时器,将不断为文件是否存在轮询引发事件,而不是你。



Answer 3:

定时器是非常昂贵的。 您可以使用FileSystemWatcher侦听文件系统更改通知,并当目录或文件目录中,变化引发事件。

// Create a new FileSystemWatcher and set its properties.
    FileSystemWatcher watcher = new FileSystemWatcher();
    watcher.Path = /*path*/
    /* Watch for changes in LastAccess and LastWrite times, and
       the renaming of files or directories. */
    watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite
       | NotifyFilters.FileName | NotifyFilters.DirectoryName;
    // Only watch text files.
    watcher.Filter = "*.txt";

    // Add event handlers.
    watcher.Changed += new FileSystemEventHandler(OnChanged);
    watcher.Created += new FileSystemEventHandler(OnChanged);
    watcher.Deleted += new FileSystemEventHandler(OnChanged);
    watcher.Renamed += new RenamedEventHandler(OnRenamed);

    // Begin watching.
    watcher.EnableRaisingEvents = true;

那么这将是OnChanged方法:

    //This method is called when a file is created, changed, or deleted.
    private static void OnChanged(object source, FileSystemEventArgs e)
    {
        //Show that a file has been created, changed, or deleted.
        WatcherChangeTypes wct = e.ChangeType;
        Console.WriteLine("File {0} {1}", e.FullPath, wct.ToString());
    }

参考: http://devproconnections.com/net-framework/how-build-folder-watcher-service-c



Answer 4:

我不会使用FileSystemWatcher的它太片状

FileSystemWatcher的没有从Windows服务中创建的文件工作

我会用定时器设定一个合理的蜱期间,你应该没问题。

一些示例代码

Timer_TicK()
{
 // remove tick event handler

 // do your processing

 // add back tick event handler
}

这将保持多蜱的活动从,如果你有一个相当大的加工量做的事情。 我不会多线程,直到你找到你需要用它由于性能问题。

在C#中,如果你尝试读取文件,而它的由文件系统,你会得到一个异常复制。 您需要检查是否有异常或检查文件(大小等)的属性,当它这样做就知道了。



Answer 5:

全定时器例如,当我开始每间隔发生时(你没有,但它是一个很好的做法),它去,并检查该文件是否存在,并读取它,并删除它,如果它是新主题:

using System;
using System.ServiceProcess;
using System.Threading;
using System.Timers;
using System.IO;

namespace MyNamespace
{
    public partial class Service1:  ServiceBase
    {
        Thread syncThread = null;
        System.Timers.Timer timer1;
        string filePath = @"C:\myfile.txt";
        int interval = 60000;  // 1 min -- adjust as necessary

        public Service1()
        {
           InitializeComponent();             
        }

        protected override void OnStart(string[] args)
        {
            timer1 = new System.Timers.Timer();
            timer1.Interval = interval;
            timer1.Enabled = true;
            timer1.Elapsed += new ElapsedEventHandler(timer1_Elapsed);
            timer1.Start();
        }
        protected override void OnStop()
        {
            syncThread.Abort();
            timer1.Stop();
        }
        protected void timer1_Elapsed(object sender, ElapsedEventArgs e)
        {
            syncThread = new Thread(new ThreadStart(doThread));
            syncThread.Start();
        }
        protected void doThread()
        {
            // whatever you put here, it will
            // run for each timer interval that elapses
            // in a separate thread, and each thread will
            // end when the processing in this function ends

            string fileContent = String.Empty;      

            if (File.Exists(filePath)
            {
                FileStream fs = new FileStream(filePath, FileMode.Open);
                StreamReader sr = new StreamReader(fs);
                fileContent = sr.ReadToEnd();
                sr.Close();
                fs.Close();
            } 

            if (fileContent != String.Empty)
            {
               // File was present... process the content...

               // Then I do this...
               File.Delete();
            }
        } 
    }
}

我已经没有任何问题跑了。 我更愿意开始新的线程,每个时间间隔,因此不会造成问题,如果以前的运行还没有完成。 走这条路,你有控制,可以决定你的时间间隔是什么,以及你的进程并不总是要去 - 仅仅是服务。 另一条路线,与FileSystemWatcher ,它总是观察和运行时,它可以和你不能调整的时间间隔,比如你可以用一个定时器,以保持下来的事件数/处理事情,例如当/如果文件创建,然后迅速修改和保存。

唯一的缺点我看到的是有来检查文件属性自己,但这些都是很容易的进行检查,以。 如果你File.Delete()处理之后像我这样做,你只有File.Exists(filePath)做,以找出是否该文件已被重新创建。 如果你有检查修改,你只是检查DateTime lastModifed = File.GetLastWriteTime(filePath) (见http://www.csharp-examples.net/file-creation-modification-time/ )针对当前时间+您的间隔(这将是DateTime lastRun = DateTime.Now.AddMilliseconds(interval) )。 如果lastRun > lastModified ,你必须处理它。



文章来源: C# - from time to time check if a file exists and read from it