【问题标题】:How can I make sure that a file inside a Dropbox is really gone after delete?如何确保 Dropbox 中的文件在删除后真的消失了?
【发布时间】:2016-04-19 02:09:09
【问题描述】:

我正在使用 Dropbox 中的文件在服务器之间进行通信。一段时间后,我意识到在 Dropbox 内的文件上执行基本的File 操作时,每隔一段时间就会出现延迟。

我需要的是这样的:

public class MyFile
{
    const int maxWaitCount = 60;
    //..
    /// <summary>
    /// remove file - also has to work inside Dropbox directory
    /// </summary>
    /// <returns>0 for ok or error code</returns>
    public int rm()
    {
        string name = Os.winInternal(FullName);
        if (File.Exists(name))
        {
            File.Delete(name);
            #region double check if file is gone
            if (Ensure)
                return awaitFileVanishing(name);
            #endregion
        }
        return 0;
    }
    //..
    private int awaitFileMaterializing(string fileName) //..
    private int awaitFileVanishing(string fileName) //..
    /// <summary>
    /// Constructor: auto-ensure mode for file systems that do not synchronously wait for the end of an IO operation i.e. Dropbox
    /// </summary>
    /// <remarks>only use the ensure mode if it has to be guaranteed that the IO operation was completely done
    /// when the method call returns; necessary e.g. for Dropbox directories since (currently) Dropbox first updates the
    /// file in the invisible . folder and then asynchronously updates the visible file and all the remote copies of it</remarks>
    /// <param name="filename"></param>
    public MyFile(string filename)
    {
        Ensure = filename.ToLower().Contains("dropbox");
        // ..
    }
}

因为我需要一个快速的解决方案,所以我想出了一个解决方案,我将在下面给出我自己的问题的答案。但是,我可以很容易地想象你们中的一些人也遇到了这个问题,并找到了一个不同的、可能更引人注目的解决方案。请告诉我。

【问题讨论】:

    标签: c# io dropbox windows-server


    【解决方案1】:

    这是我目前针对awaitFileMaterializingawaitFileVanishing 的解决方案,用作MyFile 的一部分。

        private int awaitFileMaterializing(string fileName)
        {
            int count = 0;
            bool exists = false;
            while (count < maxWaitCount)
            {
                try
                {
                    exists = File.Exists(fileName);
                }
                catch (Exception) { }   // device not ready exception if Win 2003
                if (exists)
                    break;
                Thread.Sleep(5);
                count++;
            }
            if (count >= maxWaitCount)
                throw new FileNotFoundException("ensure failed - timeout.", fileName);
            return -count;
        }
        private int awaitFileVanishing(string fileName)
        {
            int count = 0;
            bool exists = true;
            while (count < maxWaitCount)
            {
                try
                {
                    exists = File.Exists(fileName);
                }
                catch (Exception) { }   // device not ready exception if Win 2003
                if (!exists)
                    break;
                Thread.Sleep(5);
                count++;
            }
            if (count >= maxWaitCount)
                throw new IOException("ensure failed - timeout in deleting " + fileName + ".");
            return -count;
        }
    

    【讨论】:

    • 我认为与其让线程休眠,不如使用异步延迟,这样可以通过做其他事情来充分利用线程。
    【解决方案2】:

    您可以创建一个FileSystemWatcher 来监控您的 Dropbox 文件夹。 FileSystemWatcher 有一个已删除的事件,您可以附加到该事件,该事件会告诉您何时从正在监视的文件夹中删除了文件。

    MSDN Source & Examples

    【讨论】:

    • 听起来你在推荐一种事件驱动的方式来处理它,Dmitry。就我而言,肯定会改变整个编程模型。我希望在这里有更多等待风格的想法或解决方案。
    • 我考虑过 Dmitry,现在我想补充一点:我非常喜欢使用观察者模式来传播更改。但是,在上面引用的上下文中,我只想删除一个文件,并且必须等待它最终完成才能继续执行下一个操作(例如再次创建具有相同名称但内容不同的文件)。所以,我坐在同步位置,等待之前启动的操作完成。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-01
    • 1970-01-01
    • 2015-11-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多