Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (WinAPI, Konsole) » GetFileAttributes und logische Verknüpfung

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 < [ 2 ]
000
09.03.2008, 18:21 Uhr
gipfelstuermer



Hallo,
ich habe eine Frage zu der Windows-API Funktion GetFileAttributes.

C++:
DWORD Attrib;
Attrib=GetFileAttributes(irgdeneineDatei);

if(Attrib & FILE_ATTRIBUTE_READONLY)
...


Kann mit jemand sagen, was genau Attrib & FILE_ATTRIBUTE_READONLY bedeuten soll? Diese logische UND-Verknüpfung verstehe ich nicht...
if(Attrib & FILE_ATTRIBUTE_READONLY) ist ja eine Abfrage, ob diese Datei schreibgeschützt ist oder nicht. Also das Resultat ist mir klar, aber den Weg zu diesem Resultat verstehe ich nicht.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
09.03.2008, 19:54 Uhr
Hans
Library Walker
(Operator)


Hi,

Zitat von gipfelstuermer:

Kann mit jemand sagen, was genau Attrib & FILE_ATTRIBUTE_READONLY bedeuten soll? Diese logische UND-Verknüpfung verstehe ich nicht...

da stellt sich die Frage, ob Du die logische UND-Verknüpfung überhaupt verstanden hast, oder eher nicht.


Zitat:
if(Attrib & FILE_ATTRIBUTE_READONLY) ist ja eine Abfrage, ob diese Datei schreibgeschützt ist oder nicht. Also das Resultat ist mir klar, aber den Weg zu diesem Resultat verstehe ich nicht.

Nun ja, FILE_ATTRIBUTE_READONLY ist die Bezeichnung für ein bestimmtes Bit in einem DWORD, in dem Dir Windows die Informationen über die Dateiattribute liefert. Und die UND-Verknüpfung sorgt einfach dafür, dass genau dieses (und kein anderes) Bit überprüft wird.

Hans
--
Man muss nicht alles wissen, aber man sollte wissen, wo es steht. Zum Beispiel hier: Nachdenkseiten oder Infoportal Globalisierung.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
09.03.2008, 23:36 Uhr
gipfelstuermer



Hi,
und wie wird das gemacht? Bei einer logischen UND-Verknüpfung werden zwei Bit-Wörter derselben Länge verknüpft( a=1101 und b=1010 und a&b=1000). Wenn man das streng sieht müsste FILE_ATTRIBUTE_READONLY ebenfalls ein DWORD sein, sonst könnte man es mit Attrib nicht verknüpfen. Ist für mich ein bisschen verwirrend.

Dieser Post wurde am 09.03.2008 um 23:37 Uhr von gipfelstuermer editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
10.03.2008, 00:21 Uhr
Hans
Library Walker
(Operator)


Hi,

okay, habe Dein Problem verstanden. FILE_ATTRIBUTE_READONLY ist kein DWORD, sondern ein symbolischer Name für ein einzelnes Bit in einem DWORD. Wenn Du die *.h - Dateien mal danach durchsuchst, findest Du in der Datei winnt.h folgende Zeile:

C++:
#define FILE_ATTRIBUTE_READONLY             0x00000001  

Das bedeutet, das der Bezeichnung FILE_ATTRIBUTE_READONLY der Wert 0x00000001 oder einfach 1 zugewiesen wird.
Deshalb kann man in der Abfrage oben anstatt

C++:
if(Attrib & FILE_ATTRIBUTE_READONLY) ...
auch
C++:
if(Attrib & 1) ...

schreiben. Das hätte die gleiche Funktion, und wird im übersetzten Programm auch im Prinzip so stehen. Aber die Bedeutung erschliesst sich einem nicht gleich, wenn man das so im Programmtext liesst.

Hans
--
Man muss nicht alles wissen, aber man sollte wissen, wo es steht. Zum Beispiel hier: Nachdenkseiten oder Infoportal Globalisierung.

Dieser Post wurde am 10.03.2008 um 00:23 Uhr von Hans editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
10.03.2008, 00:36 Uhr
gipfelstuermer




Zitat von Hans:
Hi,

okay, habe Dein Problem verstanden. FILE_ATTRIBUTE_READONLY ist kein DWORD, sondern ein symbolischer Name für ein einzelnes Bit in einem DWORD. Wenn Du die *.h - Dateien mal danach durchsuchst, findest Du in der Datei winnt.h folgende Zeile:

C++:
#define FILE_ATTRIBUTE_READONLY             0x00000001  

Das bedeutet, das der Bezeichnung FILE_ATTRIBUTE_READONLY der Wert 0x00000001 oder einfach 1 zugewiesen wird.
Deshalb kann man in der Abfrage oben anstatt

C++:
if(Attrib & FILE_ATTRIBUTE_READONLY) ...
auch
C++:
if(Attrib & 1) ...

schreiben. Das hätte die gleiche Funktion, und wird im übersetzten Programm auch im Prinzip so stehen. Aber die Bedeutung erschliesst sich einem nicht gleich, wenn man das so im Programmtext liesst.

Hans

Achso, Danke. In der API steht das nicht so richtig. Eine Frage noch: Wie kann ich denn, wenn Attribute deaktivieren??
Ich habe da was geschrieben, aber es funktioniert leider nicht. Schreibschutz und Archiv sind Checkboxen. Reicht eine Negation mit anschliessender Oder-Verknüpfung aus, um ein Attribut zu deaktivieren?


C++:
DWORD Flags;
Flags=GetFileAttributes(Dateiname);
if (Schreibschutz->Checked==true)
          SetFileAttributes(Dateiname,Flags | FILE_ATTRIBUTE_READONLY);
        else
          SetFileAttributes(Dateiname,Flags | !FILE_ATTRIBUTE_READONLY);
            
Flags=GetFileAttributes(Dateiname);
if (Archiv->Checked==true)
          SetFileAttributes(Dateiname,Flags | FILE_ATTRIBUTE_ARCHIVE);
           else
           SetFileAttributes(Dateiname,Flags | !FILE_ATTRIBUTE_ARCHIVE);


Was mich verwirrt ist, dass es funktioniert, wenn nur Schreibschut aktivieren/deaktivieren will und den ganzen Kram mt dem dem Archiv auskommentiere im Code. Wenn es so ist, wie im obigen Code, funktioniert das ganze nicht mehr. So lassen sich beide Attribute nicht deaktivieren...
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
10.03.2008, 01:37 Uhr
Hans
Library Walker
(Operator)


Hi,

evtl. solltest Du Deine Überprüfungen erst mal alleine durchführen, und die Ergebnisse in einer Flags-Variablen merken. Wenn Du mit allen Tests fertig bist, setzt Du die Attribute mit einem einzigen Aufruf von SetFileAttributes. Programmmässig könnte das etwa so aussehen:

C++:
DWORD Flags;

Flags = 0;
if (Schreibschutz->Checked==true)
          Flags |= FILE_ATTRIBUTE_READONLY;
   else
          Flags &= !FILE_ATTRIBUTE_READONLY;   // hier logische UND-Verknüpfung!!

if (Archiv->Checked==true)
          Flags |= FILE_ATTRIBUTE_ARCHIVE;
   else
           Flags &= !FILE_ATTRIBUTE_ARCHIVE;   // hier logische UND-Verknüpfung!!

SetFileAttributes(Dateiname, Flags);


Übrigens sollte es auch nicht nötig sein, GetFileAttributes für jede Abfrage neu aufzurufen, weil es einem doch gleich alle Attribute einer Datei liefert.

Ach ja, und der Fehler in dieser Konstruktion SetFileAttributes(Dateiname,Flags | !FILE_ATTRIBUTE_ARCHIVE);
ist folgender: Da die Bezeichnungen wie FILE_ATTRIBUTE_ARCHIVE oder FILE_ATTRIBUTE_READONLY für einzelne Bits stehen werden mit dem ! davor auch nur diese Bits invertiert, alle anderen aber gesetzt. Nehmen wir z.B. mal FILE_ATTRIBUTE_READONLY.
Das steht für den Wert 1, bzw. 0x00000001; durch die Invertierung, also !FILE_ATTRIBUTE_READONLY wird daraus 0xfffffffe. Das heisst, die Datei bekommt alle Attribute zugewiesen, ausser dem READONLY-Attribut. Da sich einige Attribute gegenseitig ausschliessen können, führt das zu Wiedersprüchen, und damit zu Fehlern.

Um gezielt dieses eine Bit zu löschen muss man die Invertierung mit dem logischen UND verbinden, wie ich das oben gemacht habe. Beispiel (mit 8 Bit):
Flags = 0x39 bzw. 00111001 logisch UND verknüpft mit 0xfe bzw. 11111110 ergibt:
00111001
&11111110
----------
00111000

Hans
--
Man muss nicht alles wissen, aber man sollte wissen, wo es steht. Zum Beispiel hier: Nachdenkseiten oder Infoportal Globalisierung.

Dieser Post wurde am 10.03.2008 um 01:44 Uhr von Hans editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
10.03.2008, 10:42 Uhr
Kest
saint


Hi!


Zitat von Hans:
Das steht für den Wert 1, bzw. 0x00000001; durch die Invertierung, also !FILE_ATTRIBUTE_READONLY wird daraus 0xfffffffe.

Invertierung? Nicht Negation?
--
Wenn man einen Hufschlag hört, sollte man >Pferd< denken und nicht >Zebra<.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
007
10.03.2008, 12:23 Uhr
ao

(Operator)



Zitat von Kest:
Hi!


Zitat:
Das steht für den Wert 1, bzw. 0x00000001; durch die Invertierung, also !FILE_ATTRIBUTE_READONLY wird daraus 0xfffffffe.

Invertierung? Nicht Negation?


!FILE_ATTRIBUTE_READONLY hat den Wert 0 (logische Negation von irgendwas, das nicht 0 ist)

~FILE_ATTRIBUTE_READONLY hat den von Hans genannten Wert 0xfffffffe (bitweise Invertierung oder Einerkomplement von 0x00000001).

ao

Dieser Post wurde am 10.03.2008 um 12:24 Uhr von ao editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
008
10.03.2008, 14:04 Uhr
gipfelstuermer



Danke!!
Ich habe es jetzt verstanden und ausprogrammiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
009
11.03.2008, 11:50 Uhr
Hans
Library Walker
(Operator)



Zitat von ao:

!FILE_ATTRIBUTE_READONLY hat den Wert 0 (logische Negation von irgendwas, das nicht 0 ist)

~FILE_ATTRIBUTE_READONLY hat den von Hans genannten Wert 0xfffffffe (bitweise Invertierung oder Einerkomplement von 0x00000001).

Ups! - Da hab ich mich aber vertan,

und jetzt ein Problem: Wenn !WasWeisIch immer den Wert 0 liefert, dann ist ja meine Aussage in Posting 5 komplett falsch. Andererseits lernt man aber doch im Zusammenhang mit den Bitoperatoren, das & , | und ! zur Manipulation einzelner Bits dienen.
Oder hab ich da jetzt die Feinheiten der Bitoperatoren von C nicht richtig präsent??

Beispiel:

C++:
#include <stdio.h>

#define FILE_ATTRIBUTE_READONLY         0x00000001
#define FILE_ATTRIBUTE_ARCHIVE          0x00000020

int main()
{
  unsigned long Flags;

  Flags = 0;
  printf ("\nFlags: %08x\n", Flags);

  Flags |= FILE_ATTRIBUTE_READONLY;
  printf ("Flag ReadOnly set:   %08x\n", Flags);
  
  Flags &= !FILE_ATTRIBUTE_READONLY;   // hier logische UND-Verknüpfung!!
  printf ("Flag ReadOnly reset: %08x\n", Flags);

  Flags=0;
  Flags |= FILE_ATTRIBUTE_READONLY;
  Flags |= 0x3f5a7900;
  printf ("Flags: %08x\n", Flags);

  Flags &= !FILE_ATTRIBUTE_ARCHIVE;   // hier logische UND-Verknüpfung!!
  printf ("Flag Archive reset: %08x\n", Flags);

  return 0;
}


liefert:

Code:
Flags: 00000000
Flag ReadOnly set:   00000001
Flag ReadOnly reset: 00000000


Bis hierher okay, aber

Code:
Flags: 3f5a7901
Flag Archive reset: 00000000


an dieser Stelle hätte ich jetzt 3f5a7900 erwartet. Wo liegt denn da mein Denkfehler???

Hans
--
Man muss nicht alles wissen, aber man sollte wissen, wo es steht. Zum Beispiel hier: Nachdenkseiten oder Infoportal Globalisierung.

Dieser Post wurde am 11.03.2008 um 11:58 Uhr von Hans editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 < [ 2 ]     [ C / C++ (WinAPI, Konsole) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: