【问题标题】:FileAttributes and bitmask problemsFileAttributes 和位掩码问题
【发布时间】:2023-03-26 11:54:01
【问题描述】:

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

我对我的位运算符数学非常生疏,尤其是在一次检查多个事物时。我试图弄清楚如果存在一定数量的文件属性中的任何一个(即,如果它想通过我的搜索,则找不到指定的属性),如何让 if 语句返回 false。以下是我目前所写的:

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

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

谢谢!

更新:

看来问题不是位掩码逻辑,而是 FileAttributes.Archive。出于某种原因,我的文件几乎都标有这个标志(也许表明它们注定要备份?)。至少现在我知道了,知道是成功的一半。 :)

【问题讨论】:

  • 澄清一下,设计的目的是如果存在任何属性,则 if 语句将失败。
  • 如果我注释掉 if 语句,它会返回所有文件(包括我想隐藏的文件)。但是由于某种原因,当我添加这个 if 语句时,几乎没有文件出现。我认为文件被标记为不应该被标记的东西。
  • '如果找到任何匹配项,则将整个事物呈现为零。'不是这种情况。如果文件具有与您指定的属性匹配的任何属性,则它将为非零。

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


【解决方案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 MSDNFileAttributes.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());
        }
    }
}

【讨论】:

  • 这似乎应该可行,但正如我在上面的解释中指出的那样,它似乎过滤掉了我所有的文件。一定是设置了一些晦涩的属性,导致它不是“正常”。这就是为什么我决定明确说明我不想显示哪些属性。
  • 在我的机器上使用示例目录进行测试按预期工作,然后切换到另一个执行定期备份的目录,结果发现存档属性破坏了对 FileAttributes.Normal 的简单测试。添加了用于测试文件夹的代码。
  • 我也只是独立地意识到它是存档属性。但感谢您证实了我的怀疑。
  • 没错。试图重置存档属性(attrib -a filename on dos window)恢复了 FileAttributes.Normal 的工作
【解决方案2】:

这样做只是为您提供您选择的那些属性。

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

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

【讨论】:

  • 是的,但如果这些属性存在,我不希望结果为零吗? IE。如果存在这些属性,则 if 语句失败。
  • 您说:“我正在尝试弄清楚如果存在一定数量的文件属性中的任何一个,如何让 if 语句返回 true。”这就是它的作用。如果设置了任何标志,它的计算结果为 true 并且 if 语句运行。你的评论说你想要相反的东西。那么,它是什么?
  • 如果属性存在,绝对希望它返回 false。将编辑我的原始帖子以澄清这一点。所以听起来我的代码应该已经可以工作了?然后我想我有比位掩码更大的问题。 :(
  • 毕竟是存档标志。但是感谢您鼓励我去检查。
  • 没问题,我很高兴你明白了 :)
【解决方案3】:

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

示例:

一场比赛: 0101000 & 0100000 = 0100000 != 0

不匹配: 0101000 & 0010000 = 0000000

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-20
    • 1970-01-01
    • 1970-01-01
    • 2013-05-21
    相关资源
    最近更新 更多