Frage zu Kombination von FileAttributes Enum bzw. andere ähnliche Enums

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 38 Antworten in diesem Thema. Der letzte Beitrag () ist von ErfinderDesRades.

    So, hab mal ne Nacht drüber geschlafen und kann wieder klar denken... :)

    Die Enums haben ja folgende Werte:

    Directory= 16 ^= 00010000
    ReadOnly = 1 ^= 00000001
    System = 4 ^= 00000100
    Hidden = 2 ^= 00000010

    attributes.HasFlag(IO.FileAttributes.Directory) gibt mir dann True zurück, wenn das 4. Bit auf 1 gesetzt ist.
    attributes.HasFlag(IO.FileAttributes.ReadOnly) gibt mir dann True zurück, wenn das 1. Bit auf 1 gesetzt ist.

    Und so kann ich dann schön mit den bitweisen Opratoren arbeiten.

    Ist das so korrekt?

    kafffee schrieb:

    Ist das so korrekt?
    Funktioniert es?
    Also ja.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    kafffee schrieb:

    einen Ordner in Windows 10 auf ReadOnly zu setzen.
    Wenn es mit einer Datei geht, sollte das doch genügen.
    System-Ordner sind auch nicht readonly, sie brauchen restriktivere Zugriffsrechte,
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Ich lass das ungern wirklich ungetestet, kennste ja bestimmt, auch wenn man sich noch so sicher ist dass was funktioniert, kann es gut sein, dass da irgendwo was net stimmt...

    Gibt es vielleicht irgend einen Windows-Ordner, der von Haus aus schreibgeschützt ist?

    Wenn nicht, kann mir jemand sagen ob das hier...:

    VB.NET-Quellcode

    1. If (attributes.HasFlag(IO.FileAttributes.ReadOnly Or IO.FileAttributes.Hidden Or IO.FileAttributes.System) And IO.FileAttributes.Directory) Then


    ...aufs Gleiche rauskommt wie das hier?:

    VB.NET-Quellcode

    1. If (attributes.HasFlag(IO.FileAttributes.ReadOnly) Or attributes.HasFlag(IO.FileAttributes.Hidden) Or attributes.HasFlag(IO.FileAttributes.System)) And attributes.HasFlag(IO.FileAttributes.Directory)

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „kafffee“ ()

    Die Klammer hab ich wohl übersehen.
    Option Strict On kompiliert das auch nicht.
    Und Strict Off ist es immer falsch, weil ein Boolean nie 16 ist.

    Du willst Pfade, die schreibschutz, system oder versteckt sind? Dann bist du aufm Holzweg

    VB.NET-Quellcode

    1. If attributes.HasFlag(FileAttributes.Directory) Then
    2. If attributes.HasFlag(FileAttributes.ReadOnly) OrElse attributes.HasFlag(FileAttributes.Hidden) OrElse attributes.HasFlag(FileAttributes.System)
    3. End If
    4. End If

    Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von „Haudruferzappeltnoch“ ()

    @Haudruferzappeltnoch

    Okay das sieht so aus als ob's definitiv funktioniert.

    Option Strict Off hätte ich noch bemerkt, ich mach grundsätzlich nie was Option Strict Off, außer ich muss was probieren....

    Mit dem Ausprobieren erst mal super Idee, hab mir schon Gedanken gemacht wie ich das ausführen könnte... Aber da müsste ich die Werte dann ja auch erst setzen, um sie dann abfragen zu können, und das geht ja glaub ich auch bloß z.B. so:

    VB.NET-Quellcode

    1. Public Enum Pfadtypen
    2. Ordner = 0
    3. ReadOnly = 1
    4. System = 2
    5. Versteckt = 4
    6. End Enum
    7. Public Objekt As Pfadtypen = Pfadtypen.ReadOnly And Pfadtypen.Versteckt


    Und wenn ich da noch unsicher bin, dann bringt mich das nicht weiter. Oder kann man da die Bits auch anders setzen, einen eingebauten Konverter in z.B. einem Byte als String zu Integer gibt es ja meines Wissens nicht...

    Edit: Es sei denn ich überleg mir wie das Byte aussehen muss und übersetz es dann händisch in ein Integer und setze diesen Wert....

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „kafffee“ ()

    Jo Option Strict Off zum Lernen/Probieren ausmachen, ist ne noch schlechtere Idee als allgemein, weil Option Strict Off ja Dinge tut, die man gar nicht sieht.

    Ein Flag-Enum ist hier grundlegender Unterschied.

    VB.NET-Quellcode

    1. <Flags()>
    2. Public Enum Pfadtypen
    3. None = 0
    4. [ReadOnly] = 1
    5. System = 2
    6. Versteckt = 4
    7. Ordner = 8
    8. All = 15
    9. End Enum
    10. Dim MeinAttribut = PfadTypen.ReadOnly ' = 1
    11. Dim MeineAttribute1 = PfadTypen.ReadOnly Or Pfadtypen.Versteckt ' = 5
    12. Dim MeineAttribute2 = PfadTypen.All And Not Pfadtypen.Ordner ' = 7

    Mit den Bit-Operatorn solltest du dich gesondert nochmal auseinandersetzen. Das ist nicht intuitiv.

    VB.NET-Quellcode

    1. Dim MeineAttribute1 = PfadTypen.ReadOnly xOr Pfadtypen.Versteckt ' = 5
    2. Dim MeineAttribute2 = PfadTypen.All xOr Pfadtypen.Ordner ' = 7
    ist in diesem Beispiel dasselbe, aber nicht generell.

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „Haudruferzappeltnoch“ ()

    VaporiZed schrieb:


    Zum Thema binäres Rechnen: guckst Du hier

    IMO ist das der entscheidende Hinweis.
    Im verlinkten Post ist die Logik der bitweisen Operatoren grundsätzlich nachvollziehbar erklärt.
    Alternativ guck im Löffelmann-Buch 2005 - insbesondere von dessen Enum-Kapitel bin ich regelrecht begeistert.

    Ich rate dir dringend, den Umgang mit bitweisen Operatoren vollständig zu erlernen - das gehört zum Programmierer-1*1.
    Es gibt auch MS-Learn-Artikel zu - suche: "bitweise Operatoren".
    Spontan fallen mir deren drei ein: And, Or und Xor.
    Enum.HasFlag() ist ein bischen extra, aber ja - ist auch ein bitweiser Operator - halt für Enums. (Ich hab mir übrigens eine Extension geschrieben, die das auch mit Integer kann)

    Das hier:

    kafffee schrieb:


    VB.NET-Quellcode

    1. Public Enum Pfadtypen
    2. Ordner = 0
    3. ReadOnly = 1
    4. System = 2
    5. Versteckt = 4
    6. End Enum
    7. Public Objekt As Pfadtypen = Pfadtypen.ReadOnly And Pfadtypen.Versteckt
    ist murx.
    Guck dir nochmal den von vpz verlinkten Post an, wie da die Binär-Werte untereinander stehen, und was da bei AND herauskommt.

    Quellcode

    1. 0001 (a)
    2. AND 0100 (b)
    3. = 0000 (ergebnis)
    Beim AND-Operator ist dasjenige Ergebnis-Bit gesetzt, welches sowohl in a als auch in b gesetzt ist.
    Also ist das ergebnis 0, und das ist in deim PfadTypen-Enum grad PfadTypen.Ordner - wie gesagt: murx.
    Daran siehst du auch gleich, wenn du ein Enum definierst, mit dem du Bit-Operationen vorhast: der Wert 0 sollte entweder nicht vorkommen, oder .UnDef bedeuten oder sowas.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „ErfinderDesRades“ ()

    kafffee schrieb:

    VB.NET-Quellcode

    1. If (attributes.HasFlag(IO.FileAttributes.ReadOnly Or IO.FileAttributes.Hidden Or IO.FileAttributes.System) And IO.FileAttributes.Directory) Then
    kannst Du mal verbal beschreiben, was Du hier erreichen willst?
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    @Haudruferzappeltnoch

    Jou die ​All = 15 kannst du dir also auch sparen oder? Weil man das ja aus den anderen Werten errechnen kann.

    Bitweise Operatoren hab ich mir gestern Abend auch nochmal angeschaut, das ist easy. Aber eine Frage bleibt da noch offen: Gibts sowas wie ne Punkt-vor-Strich-Regel? ALso wenn ich hab BedingungA Or BedingingB And BedingungC wird dann zuerst BedingungA Or BedingungB aufgelöst oder BedingingB And BedingungC?

    ErfinderDesRades schrieb:

    IMO ist das der entscheidende Hinweis.

    Jou das hab ich gelesen und verstanden.

    ErfinderDesRades schrieb:

    ist murx

    Allein wegen des Ordner = 0?

    ErfinderDesRades schrieb:

    Also ist das ergebnis 0, und das ist in deim PfadTypen-Enum grad PfadTypen.Ordner - wie gesagt: murx.

    Okay auch verstanden :)

    RodFromGermany schrieb:

    kannst Du mal verbal beschreiben, was Du hier erreichen willst?


    Jo wie oben schon erwähnt, es soll True rauskommen, wenn das Objekt, also der Pfad, ein Ordner ist und eines oder mehrere dieser Flags hat: ReadOnly, Hidden, System.
    Moin moin

    ​Gibts sowas wie ne Punkt-vor-Strich-Regel?


    Also wenn ich das richtig verstehe: ​hat der Operator [b]AND[/b] eine höhere Priorität als der Operator [b]OR[/b].

    Aber man kann wohl mit den richtig gesetzen ​( ) die Auswertung steuern.

    Zuerst die AND ...

    VB.NET-Quellcode

    1. ​If a = 1 Or b = 2 And c = 3 Then

    Zuerst die OR in der Klammer ...

    VB.NET-Quellcode

    1. ​If (a = 1 Or b = 2) And c = 3 Then


    Liege ich hier richtig :?:
    Asperger Autistin. Brauche immer etwas um gewisse Sachen zu verstehen. :huh:
    Zur Priorität hast du schon einen Link in Post 16. Das heißt Operatorrangfolge.

    kafffee schrieb:

    Jou die All = 15 kannst du dir also auch sparen oder? Weil man das ja aus den anderen Werten errechnen kann.
    Wenn man für diese Einstellung keinen Shortcut haben möchte, kann man die weglassen. Wenn man viele Bits hat, dann kann das explizite hinschreiben bestimmter "Sammelbegriffe" sehr sinnvoll sein.

    kafffee schrieb:


    Jo wie oben schon erwähnt, es soll True rauskommen, wenn das Objekt, also der Pfad, ein Ordner ist und eines oder mehrere dieser Flags hat: ReadOnly, Hidden, System.
    Post 28

    post28 schrieb:


    VB.NET-Quellcode

    1. If attributes.HasFlag(FileAttributes.Directory) Then
    2. If attributes.HasFlag(FileAttributes.ReadOnly) OrElse attributes.HasFlag(FileAttributes.Hidden) OrElse attributes.HasFlag(FileAttributes.System)
    3. End If
    4. End If

    Kann man vereinfachen:

    VB.NET-Quellcode

    1. if (FileAttributes.ReadOnly or FileAttributes.Hidden or FileAttributes.System or FileAttributes.Directory) and attributes > FileAttributes.Directory Then
    2. 'lesbarer:
    3. dim bitMask = FileAttributes.ReadOnly or FileAttributes.Hidden or FileAttributes.System or FileAttributes.Directory
    4. if bitMask and attributes > FileAttributes.Directory Then
    Das ist keine Vereinfachung. Bzw. ist das doch nicht wirklich nachvollziehbarer. Und dann gehts auch gerade weil Directory > als System, Hidden und ReadOnly ist.
    Wenn man sich das als Muster merkt, dann wundert man sich beim nächsten Enum warum es nicht geht.

    Und irgendwie gibts noch andere Kombinationen, die bei dir auch durchkommen und bei mir nicht. Zum Beispiel die 128 (Normal) geht einfach so durch...

    Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von „Haudruferzappeltnoch“ ()

    Haudruferzappeltnoch schrieb:

    Zum Beispiel die 128 (Normal) geht einfach so durch...

    Mist! bin ich auch auf den blöden Operator-Vorrang reingefallen. Muss heissen:

    VB.NET-Quellcode

    1. Dim attributes = FileAttributes.Normal
    2. Dim bitMask = FileAttributes.ReadOnly Or FileAttributes.Hidden Or FileAttributes.System Or FileAttributes.Directory
    3. Dim bitmapMatches = (bitMask And attributes) > FileAttributes.Directory '=False
    Jo, ist eine starke Vereinfachung, die auch noch ausnutzt, dass FileAttributes.Directory den grössten Wert hat von diesen allen.
    Ohne das ausnutzen nähern wir uns wieder an:

    VB.NET-Quellcode

    1. Dim bitMask = FileAttributes.ReadOnly Or FileAttributes.Hidden Or FileAttributes.System
    2. Dim matching = attributes.HasFlag(FileAttributes.Directory) andalso (bitMask And attributes) > 0

    Ich wollte jdfs. zeigen, wie man mit einer Bitmaske arbeiten kann - etwa mehrere BitPositionen gleichzeitig abprüfen.
    Wobei das nur eine Anwendung von Bitmasken ist.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „ErfinderDesRades“ ()