Bitaaðgerðir og skráarvinnsla
Í fyrri köflum kynntumst við bitaaðgerðum sem líkamlegum rafrásum í örgjörvanum, og við höfum lært hvernig Python vinnur með hrá bæti. Í þessum kafla ætlum við að tengja þessa tvo heima saman.
Við munum sjá hvernig við keyrum bitaaðgerðir á heiltölum í Python, hvernig við lesum og skrifum skrár á hráu tvíundarformi (binary mode), og hvers vegna það getur hreinlega skemmt gögnin okkar ef við veljum rangan skráarham.
Bitaaðgerðir í Python
Python styður allar bitaaðgerðir sem við lærðum áður beint á heiltölum (int). Örgjörvinn tekur tölurnar, breytir þeim í bita í gistingunum, framkvæmir aðgerðina í einu örgjörvahlaupi og skilar niðurstöðunni aftur sem heiltölu.
Hér eru bitaaðgerðirnar í Python:
1. AND (Ogun) — Tákn: &
Skilar 1 því aðeins að báðir bitar séu 1:
>>> 12 & 10
8
1100 & 1010 = 1000 sem er 8).
2. OR (Eðun) — Tákn: |
Skilar 1 ef annar eða báðir bitar eru 1:
>>> 12 | 10
14
1100 | 1010 = 1110 sem er 14).
3. XOR (Misgildisaðgerð) — Tákn: ^
Skilar 1 ef bitarnir eru mismunandi:
>>> 12 ^ 10
6
1100 ^ 1010 = 0110 sem er 6).
4. NOT (Neitun) — Tákn: ~
Snýr öllum bitum við. ATH: Vegna þess hvernig tölvur geyma neikvæðar tölur (tvítölu fylli eða two's complement) mun neitun á tölu \(x\) í Python alltaf skila \(-(x + 1)\):
>>> ~12
-13
5. Vinstri stjak (Left Shift) — Tákn: <<
Stjakar bitum til vinstri (margfaldar með 2 í hverju skrefi):
>>> 6 << 2
24
00000110) til vinstri um 2 sæti gefur 24 (00011000)).
6. Hægri stjak (Right Shift) — Tákn: >>
Stjakar bitum til hægri (deilir með 2 og rúnasar niður í hverju skrefi):
>>> 24 >> 2
6
Mjög mikilvægt: Bitaaðgerðir vs. Röklegar aðgerðir
Þetta er algeng gildra sem forritarar falla í! Í Python höfum við bæði bitaaðgerðir og röklegar aðgerðir (e. logical operators). Þær hljóma svipað en virka á algjörlega ólíkan hátt.
- Bitaaðgerðir (
&,|): Vinna bita fyrir bita á heiltölum og skila nýrri tölu. - Röklegar aðgerðir (
and,or): Vinna á sannleiksgildum (bool) og eru notaðar í skilyrðissetningum (t.d.iflykkjum).
Sjáðu muninn:
# Bitaaðgerð: Ber saman bitana í 1 og 2
>>> 1 & 2
0
# Skýring: `01 & 10 = 00` (núll)
# Rökleg aðgerð: Er 1 satt og er 2 satt?
>>> 1 and 2
2
# Skýring: Í Python teljast allar tölur aðrar en 0 vera "sannar" (True).
# Röklegar aðgerðir skila því gildi sem ákvarðar niðurstöðuna.
Skráarvinnsla í Python
Tölvur geyma skrár á harða disknum sem langar runur af bætum. Til að vinna með þessar skrár í Python þurfum við að opna þær.
Innbyggða fallið open(filename, mode) er okkar aðal tól:
* filename: Nafnið á skránni (t.d. "gogn.bin").
* mode: Hamurinn sem við opnum skrána í (lesa, skrifa, bæta við o.fl.).
Tvíundahamur vs. Textahamur (Binary vs. Text Mode)
Þegar þú opnar skrá í Python verðurðu að velja á milli tveggja heima:
- Textahamur (
"r"eða"w"): Þetta er sjálfgefni hamurinn. Hann er hannaður fyrir textaskrár (t.d..txteða.html). Þegar þú opnar skrá í textaham mun Python reyna að lesa bætinfylkið sem UTF-8 strengi og breyta sjálfkrafa línulokum (t.d. breytir Windows línulokum\r\nyfir í\ní Linux). - Tvíundahamur (
"rb"eða"wb"): Bókstafurinnbstendur fyrir binary. Þessi hamur er hannaður fyrir hrá gögn (t.d. myndir, dulkóðaðar skrár eða keyranleg forrit). Í þessum ham gerir Python nákvæmlega engar breytingar á bætunum. Þú færð eða skrifar hrábytesbeint.
Hvers vegna rangur hamur skemmir gögn
Ef þú opnar .png myndaskrá í textaham ("w"), og skrifar einhver bæti í hana, mun Python reyna að breyta ákveðnum bætum (eins og \x0a sem er ný lína) yfir í línulok stýrikerfisins þíns (t.d. \r\x0a á Windows). Þessi eina litla breyting á einu bæti mun gera skrána algjörlega ólesanlega og eyðileggja myndina! Notaðu ávallt "rb" og "wb" þegar þú vinnur með hrá gögn.
Skrifað og lesið: Sýnikóði
Í nútíma Python er mælt með því að nota svokallaðan with rithátt til að opna skrár. Kosturinn við það er að Python sér sjálfkrafa um að loka skránni og ganga frá öllu þegar við erum búin, jafnvel þótt villa komi upp í forritinu.
1. Að skrifa hrá bæti í skrá ("wb")
# Við opnum "fylki.bin" í wb (write binary) ham
# Breytan f stendur fyrir skráarhlutinn (file handle)
with open("fylki.bin", "wb") as f:
payload = b"A" * 50 + b"\xde\xad\xbe\xef"
f.write(payload)
print("Skráin hefur verið skrifuð!")
2. Að lesa hrá bæti úr skrá ("rb")
# Við opnum sömu skrá í rb (read binary) ham
with open("fylki.bin", "rb") as f:
# Lesum fyrstu 10 bætin
gogn_1 = f.read(10)
print("Fyrstu 10:", gogn_1)
# Ef við köllum aftur á read heldur Python áfram þar sem frá var horfið!
afgangur = f.read()
print("Afgangur:", afgangur)