Search code examples
c#.netfile-iobit-manipulationbitmask

FileAttributes and bitmask problems


For some reason, when I try to check a file against FileAttributes.Normal, it seems like almost none of my files are showing up in my search. According to the API, that's because some other attributes are set. That's OK, I'll just need to search by what I don't want. This is where the problem comes in.

I'm incredibly rusty on my bitwise operator math, especially when it comes to checking multiple things at once. I'm trying to figure out how to get an if statement to return false if any of a certain number of file attributes are present (i.e. NONE of the specified attributes can be found if it wants to pass through my search). Here's what I've written so far:

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

I'm thinking that it should take the conglomerate of all the different attributes and compare them to the original attributes of the file. If any match is found, the entire thing is rendered zero. However, this doesn't seem to be working as intended. Should I have used a different operator than the bitwise and (&)?

Thanks!

Update:

It appears that it wasn't the bitmask logic that was the problem, but rather FileAttributes.Archive. For some reason my files were nearly all marked with this flag (perhaps indicating that they are destined for backup?). At least now I know, and knowing is half the battle. :)


Solution

  • If you want the files with only the Normal attribute set then

    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 means The file is normal and has no other attributes set. This attribute is valid only if used alone.

    After some research I think that the problem lies in the Archive attribute. Would you like to test with this simple code?

    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());
            }
        }
    }