FileAttributes和bitmask问题

时间:2012-06-19 22:26:17

标签: c# .net file-io bit-manipulation bitmask

出于某种原因,当我尝试针对FileAttributes.Normal检查文件时,似乎我的搜索中几乎没有任何文件出现。根据API,这是因为设置了一些其他属性。没关系,我只需要按照想要的东西进行搜索。这就是问题所在。

对于我的按位运算符数学,我非常生气,尤其是在一次检查多个事物时。我试图弄清楚如果存在任何特定数量的文件属性,如何使if语句返回false(即如果想要通过我的搜索,则可以找到指定属性的NONE)。这是我到目前为止所写的内容:

if ((File.GetAttributes(stringFileName) &
   (FileAttributes.System | FileAttributes.Hidden | FileAttributes.Archive |
    FileAttributes.Encrypted | FileAttributes.Temporary)) == 0)

我认为它应该将所有不同属性的集合体并将它们与文件的原始属性进行比较。如果找到任何匹配,则整个事物呈现为零。但是,这似乎没有按预期工作。我应该使用与按位和(&)相同的运算符吗?

谢谢!

更新

看起来问题不是位掩码逻辑,而是FileAttributes.Archive。由于某种原因,我的文件几乎都标有此标志(可能表明它们的目的是备份?)。至少现在我知道了,知道是成功的一半。 :)

3 个答案:

答案 0 :(得分:1)

这样做只会为您提供所选的属性。

if ((File.GetAttributes(stringFileName) &
    (FileAttributes.System | FileAttributes.Hidden | FileAttributes.Archive |
    FileAttributes.Encrypted | FileAttributes.Temporary)) != 0)

在那里,只是将平等换成不平等。这样,如果存在任何这些属性,则最终结果将为非零。

答案 1 :(得分:1)

如果您想要仅设置Normal属性的文件,则

if (File.GetAttributes(stringFileName) == FileAttributes.Normal)
    // True, file with only Normal attribute
else
    // False, file with some attributes but not the Normal one

According to MSDN FileAttributes.Normal表示The file is normal and has no other attributes set. This attribute is valid only if used alone.

经过一番研究后,我认为问题在于Archive属性。 你想用这个简单的代码测试吗?

using System;
using System.IO;
using System.Collections.Generic;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            if (args.Length != 1)
            {
                Console.WriteLine("Usage: CheckAllAtt <directoryName>");
                return;
            }
            var files = Directory.GetFiles(args[0]);
            foreach (string fileName in files)
            {
                FileAttributes att = File.GetAttributes(fileName);
                DumpAttr(fileName, att);
            }
        }
        private static void DumpAttr(string fileName, FileAttributes att)
        {
            StringBuilder sb = new StringBuilder("File: " + fileName);
            if ((att & FileAttributes.Archive) == FileAttributes.Archive)
                sb.Append(" Archive,");
            if ((att & FileAttributes.Compressed) == FileAttributes.Compressed)
                sb.Append(" Compressed,");
            if ((att & FileAttributes.Device) == FileAttributes.Device)
                sb.Append(" Device,");
            if ((att & FileAttributes.Directory) == FileAttributes.Directory)
                sb.Append(" Directory,");
            if ((att & FileAttributes.Encrypted) == FileAttributes.Encrypted)
                sb.Append(" Encrypted,");
            if ((att & FileAttributes.Hidden) == FileAttributes.Hidden)
                sb.Append(" Hidden,");
            if ((att & FileAttributes.Normal) == FileAttributes.Normal)
                sb.Append(" Normal,");
            if ((att & FileAttributes.NotContentIndexed) == FileAttributes.NotContentIndexed)
                sb.Append(" Normal,");
            if ((att & FileAttributes.Offline) == FileAttributes.Offline)
                sb.Append(" Offline,");
            if ((att & FileAttributes.ReadOnly) == FileAttributes.ReadOnly)
                sb.Append(" ReadOnly,");
            if ((att & FileAttributes.ReparsePoint) == FileAttributes.ReparsePoint)
                sb.Append(" ReparsePoint,");
            if ((att & FileAttributes.SparseFile) == FileAttributes.SparseFile)
                sb.Append(" SparseFile,");
            if ((att & FileAttributes.System) == FileAttributes.System)
                sb.Append(" System,");
            if ((att & FileAttributes.Temporary) == FileAttributes.Temporary)
                sb.Append(" Temporary,");

            sb.Length -= 1;
            Console.WriteLine(sb.ToString());
        }
    }
}

答案 2 :(得分:0)

你的逻辑是倒退的。如果找到任何匹配,则按位和(&amp;)的结果为非零。

<强>示例:

匹配: 0101000&amp; 0100000 = 0100000!= 0

不匹配: 0101000&amp; 0010000 = 0000000