jjzjj

c# - 与打开 FileStream 相关的异常问题

coder 2024-05-25 原文

好的,所以我在很多地方都搜索过这个问题的答案,但如果我遗漏了一些明显的东西,我会打开任何链接。

我有兴趣在用户尝试打开特定文件时向用户生成合理的错误消息,但无论出于何种原因程序无法访问该文件。我想区分以下情况:

  • 该文件已被另一个进程锁定,因此该进程无法写入。
  • 用户没有写入文件的适当访问权限(例如,他们的用户权限,如 Windows 资源管理器中文件的“属性”屏幕所示,不授予用户写入权限)
  • 该文件需要“提升”权限才能访问该文件。

我正在使用 FileStream 对象。我看过 msdn documentation for instantiating a FileStream ,我完全不清楚哪个异常对上述内容做了什么,以及如何区分它们。我承认我在 Windows 编程方面的经验有限,所以我可能遗漏了一些明显的东西。如果是这样,我深表歉意。

最佳答案

以下是您可以执行的操作:

1) 您可以在尝试访问您的文件之前测试您是否有权访问该文件。来自 this SO thread ,如果用户有 Write 权限(即当右键单击文件 -> property -> security 时),这里是一个应该返回 true 的方法。这涵盖了您关于不当访问权限的第 (2) 点(请注意,获取此信息可能比下面的代码更可靠/防错):

public static bool HasWritePermissionOnFile(string path)
{
    bool writeAllow = false;
    bool writeDeny = false;

    FileSecurity accessControlList = File.GetAccessControl(path);
    if (accessControlList == null)
    {
        return false;
    }

    var accessRules = accessControlList.GetAccessRules(true, true, typeof(SecurityIdentifier));
    if (accessRules == null)
    {
        return false;
    }

    foreach (FileSystemAccessRule rule in accessRules)
    {
        if ((FileSystemRights.Write & rule.FileSystemRights) != FileSystemRights.Write)
        {
            continue;
        }

        if (rule.AccessControlType == AccessControlType.Allow)
        {
            writeAllow = true;
        }
        else if (rule.AccessControlType == AccessControlType.Deny)
        {
            writeDeny = true;
        }
    }

    return writeAllow && !writeDeny;
}

2) 尝试实例化您的 FileStream,并捕获异常:

try
{
    string file = "...";
    bool hasWritePermission = HasWritePermissionOnFile(file);
    using (FileStream fs = new FileStream(file, FileMode.Open))
    {
    }
}
catch (UnauthorizedAccessException ex)
{
    // Insert some logic here
}
catch (FileNotFoundException ex)
{
    // Insert some logic here
}
catch (IOException ex)
{
    // Insert some logic here
}

在您的情况 (3)(文件需要提升)中,将抛出 UnauthorizedAccessException

在您的情况 (1)(文件被另一个进程锁定)中,IOException 被抛出。然后您可以检查异常的 HRESULT 以获取更多详细信息:

catch (IOException ex)
{
    // Gets the HRESULT
    int hresult = Marshal.GetHRForException(ex);

    // See http://msdn.microsoft.com/en-us/library/windows/desktop/ms681382(v=vs.85).aspx
    // for system error code
    switch (hresult & 0x0000FFFF)
    {
        case 32:    //ERROR_SHARING_VIOLATION
            Console.WriteLine("File is in use by another process");
            break;
    }
}

现在您应该能够区分您的 3 个用例。

关于c# - 与打开 FileStream 相关的异常问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9370509/

有关c# - 与打开 FileStream 相关的异常问题的更多相关文章

  1. ruby - 在 64 位 Snow Leopard 上使用 rvm、postgres 9.0、ruby 1.9.2-p136 安装 pg gem 时出现问题 - 2

    我想为Heroku构建一个Rails3应用程序。他们使用Postgres作为他们的数据库,所以我通过MacPorts安装了postgres9.0。现在我需要一个postgresgem并且共识是出于性能原因你想要pggem。但是我对我得到的错误感到非常困惑当我尝试在rvm下通过geminstall安装pg时。我已经非常明确地指定了所有postgres目录的位置可以找到但仍然无法完成安装:$envARCHFLAGS='-archx86_64'geminstallpg--\--with-pg-config=/opt/local/var/db/postgresql90/defaultdb/po

  2. ruby - 通过 rvm 升级 ruby​​gems 的问题 - 2

    尝试通过RVM将RubyGems升级到版本1.8.10并出现此错误:$rvmrubygemslatestRemovingoldRubygemsfiles...Installingrubygems-1.8.10forruby-1.9.2-p180...ERROR:Errorrunning'GEM_PATH="/Users/foo/.rvm/gems/ruby-1.9.2-p180:/Users/foo/.rvm/gems/ruby-1.9.2-p180@global:/Users/foo/.rvm/gems/ruby-1.9.2-p180:/Users/foo/.rvm/gems/rub

  3. ruby - 使用 Vim Rails,您可以创建一个新的迁移文件并一次性打开它吗? - 2

    使用带有Rails插件的vim,您可以创建一个迁移文件,然后一次性打开该文件吗?textmate也可以这样吗? 最佳答案 你可以使用rails.vim然后做类似的事情::Rgeneratemigratonadd_foo_to_bar插件将打开迁移生成的文件,这正是您想要的。我不能代表textmate。 关于ruby-使用VimRails,您可以创建一个新的迁移文件并一次性打开它吗?,我们在StackOverflow上找到一个类似的问题: https://sta

  4. ruby - 通过 RVM (OSX Mountain Lion) 安装 Ruby 2.0.0-p247 时遇到问题 - 2

    我的最终目标是安装当前版本的RubyonRails。我在OSXMountainLion上运行。到目前为止,这是我的过程:已安装的RVM$\curl-Lhttps://get.rvm.io|bash-sstable检查已知(我假设已批准)安装$rvmlistknown我看到当前的稳定版本可用[ruby-]2.0.0[-p247]输入命令安装$rvminstall2.0.0-p247注意:我也试过这些安装命令$rvminstallruby-2.0.0-p247$rvminstallruby=2.0.0-p247我很快就无处可去了。结果:$rvminstall2.0.0-p247Search

  5. ruby - Fast-stemmer 安装问题 - 2

    由于fast-stemmer的问题,我很难安装我想要的任何ruby​​gem。我把我得到的错误放在下面。Buildingnativeextensions.Thiscouldtakeawhile...ERROR:Errorinstallingfast-stemmer:ERROR:Failedtobuildgemnativeextension./System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/rubyextconf.rbcreatingMakefilemake"DESTDIR="cleanmake"DESTDIR=

  6. ruby-on-rails - Rails - 乐观锁定总是触发 StaleObjectError 异常 - 2

    我正在学习Rails,并阅读了关于乐观锁的内容。我已将类型为integer的lock_version列添加到我的articles表中。但现在每当我第一次尝试更新记录时,我都会收到StaleObjectError异常。这是我的迁移:classAddLockVersionToArticle当我尝试通过Rails控制台更新文章时:article=Article.first=>#我这样做:article.title="newtitle"article.save我明白了:(0.3ms)begintransaction(0.3ms)UPDATE"articles"SET"title"='dwdwd

  7. ruby-on-rails - 相关表上的范围为 "WHERE ... LIKE" - 2

    我正在尝试从Postgresql表(table1)中获取数据,该表由另一个相关表(property)的字段(table2)过滤。在纯SQL中,我会这样编写查询:SELECT*FROMtable1JOINtable2USING(table2_id)WHEREtable2.propertyLIKE'query%'这工作正常:scope:my_scope,->(query){includes(:table2).where("table2.property":query)}但我真正需要的是使用LIKE运算符进行过滤,而不是严格相等。然而,这是行不通的:scope:my_scope,->(que

  8. ruby - #之间? Cooper 的 *Beginning Ruby* 中的错误或异常 - 2

    在Cooper的书BeginningRuby中,第166页有一个我无法重现的示例。classSongincludeComparableattr_accessor:lengthdef(other)@lengthother.lengthenddefinitialize(song_name,length)@song_name=song_name@length=lengthendenda=Song.new('Rockaroundtheclock',143)b=Song.new('BohemianRhapsody',544)c=Song.new('MinuteWaltz',60)a.betwee

  9. ruby - 安装 Ruby 时遇到问题(无法下载资源 "readline--patch") - 2

    当我尝试安装Ruby时遇到此错误。我试过查看this和this但无济于事➜~brewinstallrubyWarning:YouareusingOSX10.12.Wedonotprovidesupportforthispre-releaseversion.Youmayencounterbuildfailuresorotherbreakages.Pleasecreatepull-requestsinsteadoffilingissues.==>Installingdependenciesforruby:readline,libyaml,makedepend==>Installingrub

  10. c# - 如何在 ruby​​ 中调用 C# dll? - 2

    如何在ruby​​中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL

随机推荐