Question Changing File Attributes (BitWise)

JuggaloBrotha

VB.NET Forum Moderator
Staff member
Joined
Jun 3, 2004
Messages
4,530
Location
Lansing, MI; USA
Programming Experience
10+
m_ArchiveBoolean, m_HiddenBoolean, m_ReadOnlyBoolean, m_IndexedBoolean, m_CompressedBoolean are all form level booleans that's set from their appropriate Checkboxes on the form before this code runs in a BackgroundWorker.

Why is it that this code works:
VB.NET:
                    Try
                        Dim fi As New FileInfo(element)
                        With fi
                            If m_ArchiveBoolean = False Then
                                If (.Attributes And IO.FileAttributes.Archive) = IO.FileAttributes.Archive Then .Attributes = .Attributes Xor IO.FileAttributes.Archive 'Turn off
                            Else
                                .Attributes = .Attributes Or IO.FileAttributes.Archive
                            End If
                            If m_HiddenBoolean = False Then
                                If (.Attributes And IO.FileAttributes.Hidden) = IO.FileAttributes.Hidden Then .Attributes = .Attributes Xor IO.FileAttributes.Hidden 'Turn off
                            Else
                                .Attributes = .Attributes Or System.IO.FileAttributes.Hidden
                            End If
                            If m_ReadOnlyBoolean = False Then
                                If (.Attributes And IO.FileAttributes.ReadOnly) = IO.FileAttributes.ReadOnly Then .Attributes = .Attributes Xor IO.FileAttributes.ReadOnly 'Turn off
                            Else
                                .Attributes = .Attributes Or System.IO.FileAttributes.ReadOnly
                            End If
                            If m_IndexedBoolean = True Then
                                If (.Attributes And IO.FileAttributes.NotContentIndexed) = IO.FileAttributes.NotContentIndexed Then .Attributes = .Attributes Xor IO.FileAttributes.NotContentIndexed 'Turn off
                            Else
                                .Attributes = .Attributes Or System.IO.FileAttributes.NotContentIndexed
                            End If
                            If m_CompressedBoolean = False Then
                                If (.Attributes And IO.FileAttributes.Compressed) = IO.FileAttributes.Compressed Then .Attributes = .Attributes Xor IO.FileAttributes.Compressed 'Turn off
                            Else
                                .Attributes = .Attributes Or System.IO.FileAttributes.Compressed
                            End If
                        End With
                        fi = Nothing
                    Catch : End Try
Where as this code doesn't:
VB.NET:
                    Try
                        Dim fi As New FileInfo(element)
                        With fi
                            .Attributes = If(m_ArchiveBoolean = False AndAlso (.Attributes And IO.FileAttributes.Archive) = IO.FileAttributes.Archive, .Attributes Xor IO.FileAttributes.Archive, .Attributes Or IO.FileAttributes.Archive)
                            .Attributes = If(m_HiddenBoolean = False AndAlso (.Attributes And IO.FileAttributes.Hidden) = IO.FileAttributes.Hidden, .Attributes Xor IO.FileAttributes.Hidden, .Attributes Or IO.FileAttributes.Hidden)
                            .Attributes = If(m_ReadOnlyBoolean = False AndAlso (.Attributes And IO.FileAttributes.ReadOnly) = IO.FileAttributes.ReadOnly, .Attributes Xor IO.FileAttributes.ReadOnly, .Attributes Or IO.FileAttributes.ReadOnly)
                            .Attributes = If(m_IndexedBoolean = True AndAlso (.Attributes And IO.FileAttributes.NotContentIndexed) = IO.FileAttributes.NotContentIndexed, .Attributes Xor IO.FileAttributes.NotContentIndexed, .Attributes Or IO.FileAttributes.NotContentIndexed)
                            .Attributes = If(m_CompressedBoolean = False AndAlso (.Attributes And IO.FileAttributes.Compressed) = IO.FileAttributes.Compressed, .Attributes Xor IO.FileAttributes.Compressed, .Attributes Or IO.FileAttributes.Compressed)
                        End With
                        fi = Nothing
                    Catch : End Try
In this 2nd one attributes are being changed, but they're the wrong ones and I can't pinpoint it right off hand.

Edit: What the overall goal of this is that if the user has the attribute checkbox checked then the file needs to have it set, other wise the attribute (if it's present) needs to be unset.
 
Ok, never mind, I realize now that it'll add the attribute if the attribute isn't already there and if the user doesn't want it to be there.

Which means I could do this really easily if VB only had the Nor bitwise operator but it doesn't so I'll have to stick with the top piece of code until the language (if ever) supports Nor as well as Xor.
 
You can simplify this code using "And Not" operator to turn off the flag.
VB.NET:
If m_ArchiveBoolean Then
   .Attributes = .Attributes Or IO.FileAttributes.Archive 'set
Else
   .Attributes = .Attributes And Not IO.FileAttributes.Archive 'remove
End If
 
Not sure if I understand the bitwise logic myself, though it reads well in code. Jmc told me about this a few years ago.
 
Not sure if I understand the bitwise logic myself, though it reads well in code. Jmc told me about this a few years ago.

1100 OR
1001 =
1101

-

1100 AND NOT
1001 =

1100 AND
0110 =

0100


For flags attributes you'd expect only one bit to be set:

ReadOnly, Archive, Hidden, Sytem =
1111

So Readonly is 1000, Archive is 0100, Hidden is 0010, System is 0001 (for example)
Hence why flags enums have 1 2 4 8 16 as their values, written in binary:

VB.NET:
<Flags()>
Enum
  ReadOnly = 1000, '8
  Archive = 0100, '4
etc...


This file is nothing (nothing set):

0000

To turn on read only:

0000 OR
1000 =

1000


To turn off read only:

1000 AND NOT
1000 =

1000 AND
0111 =

0000

-

(The not is evaluated first, and flips all the bits from 1000 to 0111, then it is anded which turns off the read only bit but leaves all other bits alone)
 
cjard said:
The not is evaluated first, and flips all the bits from 1000 to 0111, then it is anded
I see, that makes sense.
 
It never hurts to have a thread like this for direct reference, the thing that had me stuck was all the reference material found in google searches that kept mentioning 'Nor' and as I was looking for a vb.net equivalent, I just wasn't coming to the 'And Not' equivalent, but since JohnH pointed it out, it's clicked in my mind why I should have thought of that given the nature of the And and the Not operators.
 
Back
Top