如何从文件中删除单个属性(例如 ReadOnly) ?

假设一个文件具有以下属性: ReadOnly, Hidden, Archived, System如何只删除一个 Attribute? (例如 ReadOnly)

如果我使用以下命令,它会删除所有属性:

IO.File.SetAttributes("File.txt",IO.FileAttributes.Normal)
100470 次浏览

Answering on your question in title regarding ReadOnly attribute:

FileInfo fileInfo = new FileInfo(pathToAFile);
fileInfo.IsReadOnly = false;

To get control over any attribute yourself you can use File.SetAttributes() method. The link also provides an example.

From MSDN: You can remove any attribute like this

(but @sll's answer for just ReadOnly is better for just that attribute)

using System;
using System.IO;
using System.Text;
class Test
{
public static void Main()
{
string path = @"c:\temp\MyTest.txt";


// Create the file if it exists.
if (!File.Exists(path))
{
File.Create(path);
}


FileAttributes attributes = File.GetAttributes(path);


if ((attributes & FileAttributes.ReadOnly) == FileAttributes.ReadOnly)
{
// Make the file RW
attributes = RemoveAttribute(attributes, FileAttributes.ReadOnly);
File.SetAttributes(path, attributes);
Console.WriteLine("The {0} file is no longer RO.", path);
}
else
{
// Make the file RO
File.SetAttributes(path, File.GetAttributes(path) | FileAttributes.Hidden);
Console.WriteLine("The {0} file is now RO.", path);
}
}


private static FileAttributes RemoveAttribute(FileAttributes attributes, FileAttributes attributesToRemove)
{
return attributes & ~attributesToRemove;
}
}

Use this:

private static FileAttributes RemoveAttribute(FileAttributes attributes, FileAttributes attributesToRemove)

Read detail here in MSDN: http://msdn.microsoft.com/en-us/library/system.io.file.setattributes.aspx

string file = "file.txt";
FileAttributes attrs = File.GetAttributes(file);
if (attrs.HasFlag(FileAttributes.ReadOnly))
File.SetAttributes(file, attrs & ~FileAttributes.ReadOnly);

For a one line solution (provided that the current user has access to change the attributes of the mentioned file) here is how I would do it:

VB.Net

Shell("attrib file.txt -r")

the negative sign means to remove and the r is for read-only. if you want to remove other attributes as well you would do:

Shell("attrib file.txt -r -s -h -a")

That will remove the Read-Only, System-File, Hidden and Archive attributes.

if you want to give back these attributes, here is how:

Shell("attrib file.txt +r +s +h +a")

the order does not matter.

C#

Process.Start("cmd.exe", "attrib file.txt +r +s +h +a");

References

/// <summary>
/// Addes the given FileAttributes to the given File.
/// It's possible to combine FileAttributes: FileAttributes.Hidden | FileAttributes.ReadOnly
/// </summary>
public static void AttributesSet(this FileInfo pFile, FileAttributes pAttributes)
{
pFile.Attributes = pFile.Attributes | pAttributes;
pFile.Refresh();
}


/// <summary>
/// Removes the given FileAttributes from the given File.
/// It's possible to combine FileAttributes: FileAttributes.Hidden | FileAttributes.ReadOnly
/// </summary>
public static void AttributesRemove(this FileInfo pFile, FileAttributes pAttributes)
{
pFile.Attributes = pFile.Attributes & ~pAttributes;
pFile.Refresh();
}


/// <summary>
/// Checks the given File on the given Attributes.
/// It's possible to combine FileAttributes: FileAttributes.Hidden | FileAttributes.ReadOnly
/// </summary>
/// <returns>True if any Attribute is set, False if non is set</returns>
public static bool AttributesIsAnySet(this FileInfo pFile, FileAttributes pAttributes)
{
return ((pFile.Attributes & pAttributes) > 0);
}


/// <summary>
/// Checks the given File on the given Attributes.
/// It's possible to combine FileAttributes: FileAttributes.Hidden | FileAttributes.ReadOnly
/// </summary>
/// <returns>True if all Attributes are set, False if any is not set</returns>
public static bool AttributesIsSet(this FileInfo pFile, FileAttributes pAttributes)
{
return (pAttributes == (pFile.Attributes & pAttributes));
}

Example:

private static void Test()
{
var lFileInfo = new FileInfo(@"C:\Neues Textdokument.txt");
lFileInfo.AttributesSet(FileAttributes.Hidden | FileAttributes.ReadOnly);
lFileInfo.AttributesSet(FileAttributes.Temporary);
var lBool1 = lFileInfo.AttributesIsSet(FileAttributes.Hidden);
var lBool2 = lFileInfo.AttributesIsSet(FileAttributes.Temporary);
var lBool3 = lFileInfo.AttributesIsSet(FileAttributes.Encrypted);
var lBool4 = lFileInfo.AttributesIsSet(FileAttributes.ReadOnly | FileAttributes.Temporary);
var lBool5 = lFileInfo.AttributesIsSet(FileAttributes.ReadOnly | FileAttributes.Encrypted);
var lBool6 = lFileInfo.AttributesIsAnySet(FileAttributes.ReadOnly | FileAttributes.Temporary);
var lBool7 = lFileInfo.AttributesIsAnySet(FileAttributes.ReadOnly | FileAttributes.Encrypted);
var lBool8 = lFileInfo.AttributesIsAnySet(FileAttributes.Encrypted);
lFileInfo.AttributesRemove(FileAttributes.Temporary);
lFileInfo.AttributesRemove(FileAttributes.Hidden | FileAttributes.ReadOnly);
}
if ((oFileInfo.Attributes & FileAttributes.ReadOnly) == FileAttributes.ReadOnly)
oFileInfo.Attributes ^= FileAttributes.ReadOnly;

Lots of code in these examples, if you want a simple solution(without Shell):

File.SetAttributes(filepath, ~FileAttributes.ReadOnly & File.GetAttributes(filepath));