文件的安全流更新 [英] Safe stream update of file

查看:101
本文介绍了文件的安全流更新的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们通过编写新的记录到一个临时文件,然后使用临时文件替换旧文件执行大的文本文件的更新。一个沉重简化版本:

  VAR tpath = Path.GetTempFileName();
尝试
{
    使用(VAR SF =新的StreamReader(源路径))
    使用(VAR TF =新的StreamWriter(tpath))
    {
        串线;
        而((行= sf.ReadLine())!= NULL)
            tf.WriteLine(UpdateLine(线));
    }

    File.Delete(源路径);
    File.Move(tpath,源路径);
}
抓住
{
    File.Delete(tpath);
    扔;
}
 

如果什么抛出异常(文件未找到,没有权限),原始文件保持不变,这正是我们想要的。

然而,code具有以下问题:

  1. 有一个现实世界的情况下的删除作品,但移动失败?这将删除原有的和更新的数据。这将是坏的。

  2. 最常见的故障是源文件是从其他应用程序中打开,而删除失败。这意味着所有的更新工作将被丢弃。有没有一种方法,如果源文件是可删除的开始,放弃更新,如果不呢?

  3. 我们让用户把Windows资源管理器摘要属性,如标题或意见,对文件。这些被丢弃的时候,我们删除该文件。有没有一种方法,以旧文件的摘要属性复制到一个新的文件?如果我们做到这一点?

解决方案

很多好的建议。我是能够解决的问题:

  VAR sInfo =新的FileInfo(SOURCEPATH);
如果(sInfo.IsReadOnly)
    抛出新IOException异常(文件'+ sInfo.FullName +'为只读。);

变种tPath = Path.GetTempFileName();
尝试
{
    //这将引发SOURCEPATH不存在,打开,或无法读取。
    使用(VAR SF = sInfo.OpenText())
    使用(VAR TF =新的StreamWriter(tPath))
    {
        串线;
        而((行= sf.ReadLine())!= NULL)
            tf.WriteLine(UpdateLine(线));
    }

    字符串backupPath = sInfo.FullName +名为.bak;
    如果(File.Exists(backupPath))
        File.Delete(backupPath);

    File.Move(tPath,backupPath);
    tPath = backupPath;
    File.Replace(tPath,sInfo.FullName,NULL);
}
赶上(例外前)
{
    File.Delete(tPath);
    抛出新的IOException异常(文件+ sInfo.FullName +'不能被覆盖。,前);
}
 

OpenText公司抛出,如果源文件是打开或无法读取,并且更新不这样做。如果有的话抛出,原来的文件保持不变。 替换复制旧文件摘要属性的新文件。这个工程即使源文件是不同的卷的临时文件夹。

We perform updates of large text files by writing new records to a temp file, then replacing the old file with the temp file. A heavily abbreviated version:

var tpath = Path.GetTempFileName();
try
{
    using (var sf = new StreamReader(sourcepath))
    using (var tf = new StreamWriter(tpath))
    {
        string line;
        while ((line = sf.ReadLine()) != null)
            tf.WriteLine(UpdateLine(line));
    }

    File.Delete(sourcepath);
    File.Move(tpath, sourcepath);
}
catch
{
    File.Delete(tpath);
    throw;
}

If anything throws an exception (file not found, no permission), the original file is left untouched, which is what we want.

However, the code has the following problems:

  1. Is there a real-world situation where the Delete works but the Move fails? This would delete the original and updated data. This would be bad.

  2. The most common failure is the source file being open from another application, and the Delete fails. This means all the Update work is discarded. Is there a way to see if the source file is deletable at the start, and abandon the update if not?

  3. We have users putting Windows Explorer Summary properties, like Title or Comments, on files. These are discarded when we delete the file. Is there a way to copy the old file's Summary properties to a new file? Should we do this?

解决方案

Lots of good suggestions. I was able to solve the problems with:

var sInfo = new FileInfo(sourcePath);
if (sInfo.IsReadOnly)
    throw new IOException("File '" + sInfo.FullName + "' is read-only.");

var tPath = Path.GetTempFileName();
try
{
    // This throws if sourcePath does not exist, is opened, or is not readable.
    using (var sf = sInfo.OpenText())
    using (var tf = new StreamWriter(tPath))
    {
        string line;
        while ((line = sf.ReadLine()) != null)
            tf.WriteLine(UpdateLine(line));
    }

    string backupPath = sInfo.FullName + ".bak";
    if (File.Exists(backupPath))
        File.Delete(backupPath);

    File.Move(tPath, backupPath);
    tPath = backupPath;
    File.Replace(tPath, sInfo.FullName, null);
}
catch (Exception ex)
{
    File.Delete(tPath);
    throw new IOException("File '" + sInfo.FullName + "' could not be overwritten.", ex);
}

OpenText throws if the source file is open or not readable, and the update is not done. If anything throws, the original file is left unchanged. Replace copies the old files' Summary properties to the new file. This works even if the source file is on a different volume than the temp folder.

这篇关于文件的安全流更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆