【问题标题】:How to by pass the "Access to path 'F:/System File Volume' is denied" exception?如何绕过“访问路径'F:/系统文件卷'被拒绝”异常?
【发布时间】:2012-04-04 03:29:30
【问题描述】:

我有一个应用程序,它可以读取构建的程序集目录中的所有文件和子文件夹,并使用 datagridview 显示它。但是当我尝试在我的网络驱动器中运行应用程序以尝试扫描该驱动器中的文件时,它会给出异常“访问路径'F:/系统文件卷'被拒绝”,然后应用程序将停止运行。关于如何通过系统文件卷并仍然显示可以访问的文件的任何想法。如果需要,这是我的代码:

        private void Form1_Load(object sender, EventArgs e)
    {

        count = 0;
        timer = new Timer();
        timer.Interval = 1000;
        timer.Tick += new EventHandler(timer1_Tick);
        timer.Start();
        //FileIOPermission permit;

        try
        {   
            s1 = Directory.GetFiles(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "*.*", SearchOption.AllDirectories);
            //permit = new FileIOPermission(FileIOPermissionAccess.AllAccess, s1);
            //permit.AddPathList(FileIOPermissionAccess.AllAccess, s1);
            for (int i = 0; i <= s1.Length - 1; i++)
            {
                if (i == 0)
                {
                    dt.Columns.Add("File_Name");
                    dt.Columns.Add("File_Type");
                    dt.Columns.Add("File_Size");
                    dt.Columns.Add("Create_Date");
                }


                FileInfo info = new FileInfo(s1[i]);
                FileSystemInfo sysInfo = new FileInfo(s1[i]);
                dr = dt.NewRow();

                dr["File_Name"] = sysInfo.Name;
                dr["File_Type"] = sysInfo.Extension;
                dr["File_Size"] = (info.Length / 1024).ToString();
                dr["Create_Date"] = sysInfo.CreationTime.Date.ToString("dd/MM/yyyy");
                dt.Rows.Add(dr);


                if ((info.Length / 1024) > 1500000)
                {
                    MessageBox.Show("" + sysInfo.Name + " had reach its size limit.");
                }
            }

            if (dt.Rows.Count > 0)
            {
                dataGridView1.DataSource = dt;
            }
        }

        catch (UnauthorizedAccessException ex)
        {
            MessageBox.Show("Error : " + ex.Message);
            throw;
        }

    }

    private bool IsIgnorable(string dir)
    {
        if (dir.EndsWith(":System Volume Information")) return true;
        if (dir.Contains(":$RECYCLE.BIN")) return true;
        return false;
    }

    private void timer1_Tick(object sender, EventArgs e)
    {
            count++;
            if (count == 60)
            {
                count = 0;
                timer.Stop();
                Application.Restart();
            }
    }

    public string secondsToTime(int seconds)
    {
         int minutes = 0;
         int hours = 0;

         while (seconds >= 60)
         {
            minutes += 1;
            seconds -= 60;
         }
         while (minutes >= 60)
         {
            hours += 1;
            minutes -= 60;
         }

         string strHours = hours.ToString();
         string strMinutes = minutes.ToString();
         string strSeconds = seconds.ToString();

         if (strHours.Length < 2)
             strHours = "0" + strHours;
         if (strMinutes.Length < 2)
             strMinutes = "0" + strMinutes;
         if (strSeconds.Length < 2)
             strSeconds = "0" + strSeconds;
         return strHours + ":" + strMinutes + ":" + strSeconds;
     }

    private void textBox1_TextChanged(object sender, EventArgs e)
    {
        BindingSource bind = new BindingSource();
        bind.DataSource = dt;
        bind.Filter = string.Format("File_Name like '%{0}%'", textBox1.Text.Trim());
    }

【问题讨论】:

  • 该目录包含还原点,甚至管理员都无法访问它。这会阻止您从根目录使用 SearchOption.AllDirectories。并不是说从非根路径使用它也是安全的,总是可以访问一个不可访问的文件。你必须自己迭代它,使用递归,这样你就可以捕获异常。跳过任何隐藏的目录或系统以避免大多数异常。

标签: c# winforms


【解决方案1】:

您必须在 for 循环内创建一个 try/catch 块并自行处理每个文件的错误,然后您可以继续循环。

我建议用它做一个函数,这里有一些“空气代码”,未经测试,可能语法错误,但我想你明白了:

bool GetFileInformation(File f, out string name)
{
    name=null;
    try
    {
       FileInfo info = new FileInfo(f);
       FileSystemInfo sysInfo = new FileSystemInfo(f);
       name=sysInfo.Name;
    }
    catch(Exception ex)
    {
        return false;
    }
    return true;
}

现在您可以轻松地围绕此构建循环:

 for (int i = 0; i <= s1.Length - 1; i++)
 {
     if (GetFileInformation(s1[i], out name)
     {
        dr = dt.NewRow();
        dr["File_Name"] = name;
        // ....

     }
  } 

【讨论】:

  • 我明白了。理论上我理解这个概念。这意味着我必须单独阅读每个文件,然后那些无法访问的文件,就跳过它吧?但是我如何检查文件是否可以访问??它有什么功能吗?抱歉,我对编程很陌生,尤其是在 c# 环境中。
  • @shahrul1509:如果您尝试通过FileInfo 访问文件并且您的代码抛出异常,这表明您无法访问该文件。使用 FileInfo 将部分重构为单独的方法可能是个好主意。
  • 换一种方法是什么意思?换一种方法有什么区别??
  • 请不要抓到Exception。检查你得到的异常,并抓住它。例如,如果您收到意外的 OutOfMemoryException 而不是您要处理的 IOException,则您真的不应该尝试继续。
  • @DocBrown。我已经尝试过,但是在该行出现错误: FileInfo info = new FileInfo(f); // 参数 '1':无法从 'System.IO.File' 转换为 'string' FileSystemInfo sysInfo = new FileSystemInfo(f);Error 3 无法创建抽象类或接口 'System.IO.FileSystemInfo' 的实例
猜你喜欢
  • 2018-11-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-05
  • 1970-01-01
  • 2019-03-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多