Avatar billede jeffee Nybegynder
02. juni 2006 - 13:59 Der er 14 kommentarer og
2 løsninger

læse binær fil bit for bit

Hej eksperter

Jeg er ved at lave et lille program der henter informationer fra binære filer. Filerne er opbygget således at de første 22 bit i hver "linie" bestemmer hvad der skal læses fra resten af linien - Altså som en slags "bitmap" hvor et flag i bit nr 5, 7 og 11 betyder at variabel 5, 7 og 11 findes i den efterfølgende linie og skal læses.. hvorefter der så kommer en ny "bitmap"

Jeg kan imidlertidig ikke finde ud af at læse "bitmap´en" direkte. I øjeblikket oversætter jeg talværdien for bitstrengen til binær igen og bruger den til at finde ud af hvilke variable der skal læses.. Det må da kunne lade sig gøre at læse bitstrengen/bitmappen direkte??

Jeffee
Avatar billede nielle Nybegynder
02. juni 2006 - 14:01 #1
Den mindste enhed du kan læse fra din fil er på byteniveau - derefter er du nødt til at tygge dig igennem den læste byte bit for bit.
Avatar billede jeffee Nybegynder
02. juni 2006 - 14:11 #2
Og det vil sige at jeg så må oversætte talværdien for de enkelte bytes til binær for at finde den biære streng eller hvordan??
Avatar billede jeffee Nybegynder
02. juni 2006 - 14:17 #3
filen stammer fra et ældre program der er skrevet i fortran, og der kan man uden videre læse sådanne bitstrenge???
Avatar billede nielle Nybegynder
02. juni 2006 - 14:27 #4
I så fald "snyder" fortran og læser en byte, hvorefter den trækker de enkelte bits ud - sådan at det bliver udynligt for programmet.

Men, når der læses fra en HD så sker det dog altid på byteniveau uanset programmet.
Avatar billede sjh Nybegynder
02. juni 2006 - 15:03 #5
Noget i den stil.. så skal du bare loppe alle dine byte eller Bit igennem..

Option Explicit

Private Sub Form_Load()
Dim strBit As String
  strBit = ByteToBit(65) ' 65 = Asc("A")
  MsgBox "Byte2Bit: " & strBit ' 1 byte = 8 Bit
  MsgBox "Bit2Byte: " & BitToByte(strBit)
End Sub

Public Function BitToByte(ByVal strBin As String) As Byte
Dim i As Integer
  For i = 8 To 1 Step -1
    Select Case Mid$(strBin, i, 1)
          Case "1", 1
            BitToByte = BitToByte + (2 ^ (8 - i))
    End Select
  Next
End Function

Public Static Function ByteToBit(ByVal byt1 As Byte) As String
Dim i As Integer
Dim strByte(0 To 255) As String * 8
  If i Then
    ByteToBit = strByte(byt1)
      Else
    For i = 0 To 255
      strByte(i) = ExByteToBit(i)
    Next
    ByteToBit = strByte(byt1)
  End If
End Function

Private Function ExByteToBit(ByVal byt1 As Byte) As String
  ExByteToBit = "00000000"
  If byt1 And &H1& Then MidB$(ExByteToBit, 15&) = "1"
  If byt1 And &H2& Then MidB$(ExByteToBit, 13&) = "1"
  If byt1 And &H4& Then MidB$(ExByteToBit, 11&) = "1"
  If byt1 And &H8& Then MidB$(ExByteToBit, 9&) = "1"
  If byt1 And &H10& Then MidB$(ExByteToBit, 7&) = "1"
  If byt1 And &H20& Then MidB$(ExByteToBit, 5&) = "1"
  If byt1 And &H40& Then MidB$(ExByteToBit, 3&) = "1"
  If byt1 And &H80& Then MidB$(ExByteToBit, 1&) = "1"
End Function
Avatar billede sjh Nybegynder
02. juni 2006 - 15:13 #6
Øhh.. self.. sådan ikke den med de 255 loop.. :P

Private Sub Form_Load()
Dim strBit As String
  strBit = ByteToBit(65) ' 65 = Asc("A")
  MsgBox "Byte2Bit: " & strBit ' 1 byte = 8 Bit
  MsgBox "Bit2Byte: " & BitToByte(strBit)
End Sub

Public Function BitToByte(ByVal strBin As String) As Byte
Dim i As Integer
  For i = 8 To 1 Step -1
    Select Case Mid$(strBin, i, 1)
          Case "1", 1
            BitToByte = BitToByte + (2 ^ (8 - i))
    End Select
  Next
End Function

Public Function ByteToBit(ByVal byt1 As Byte) As String
  ByteToBit = "00000000"
  If byt1 And &H1& Then MidB$(ByteToBit, 15&) = "1"
  If byt1 And &H2& Then MidB$(ByteToBit, 13&) = "1"
  If byt1 And &H4& Then MidB$(ByteToBit, 11&) = "1"
  If byt1 And &H8& Then MidB$(ByteToBit, 9&) = "1"
  If byt1 And &H10& Then MidB$(ByteToBit, 7&) = "1"
  If byt1 And &H20& Then MidB$(ByteToBit, 5&) = "1"
  If byt1 And &H40& Then MidB$(ByteToBit, 3&) = "1"
  If byt1 And &H80& Then MidB$(ByteToBit, 1&) = "1"
End Function
Avatar billede jeffee Nybegynder
02. juni 2006 - 15:22 #7
SJH - tak for svaret

Jef er lige på vej ud af døren.. Og jeg kommer nok ikke til computeren i weekenden - ingen netforbindelse i sommerhuset forstås... , men jeg kigger lige på det først i næste uge.

Jeffee
Avatar billede nielle Nybegynder
02. juni 2006 - 15:27 #8
Jeg forstod ellers dit spørgsmål som om at det var denne byte-til-bit konversion du ønskerde at undgå hvis det var muligt?
Avatar billede sjh Nybegynder
02. juni 2006 - 15:42 #9
nielle > smid et svar så kan vi da dele de 100 point.. eller også kan du da få alle 100 point..
Avatar billede nielle Nybegynder
02. juni 2006 - 15:55 #10
Jeg er skam ikke ude efter point på denne her. Men, ellers tak for tilbudet. :^)

Det undrede mig bare at jeffee spørger efter en måde at læse fra filen bit-for-bit, og så alligevel er tilfreds over at for en byte-til-bit konverterings rutine; Umiddelbart lød spørgsmålet som om at der allerede var tjek på dette?
Avatar billede sjh Nybegynder
06. juni 2006 - 13:25 #11
nielle > Jo men har du et bedre bud.. jeg kan ikke se anden udvej med mindre det er noget standard BITMAP-Billede..

jeffee > Hvad er det lige det skal bruges til?? er det et standard BITMAP-Billede du vil læse? og hvorfor på den måde?
Avatar billede jeffee Nybegynder
06. juni 2006 - 15:04 #12
Hej igen

Beklager jeg ikke lige har været ved computeren så jeg har kunne kigge på svarene.. Nielle har forstået rigtigt at det er konversionen fra byte til bit jeg gerne vil udenom.. Den fil jeg læser er en binær fil, hvor hver linie starter med en 22 bit streng der fortæller hvilke variable der er tilstedeværende i den pågældende linie.. Hver bit repræsenterer en variabel...
Grunden til at filen ser således ud er at man så bliver fri for at skrive alle variable hver gang. Det er nemlig kun de variable der er anderledes end den foregående linie der angives. På den måde reduceres filstørrelsen krafigt, da størstedelen af de variable kun sjældent ændres fra linie til linie.. 
I første linie i filen vil de 22 bit dermed altiod være "tændte" og dermed findes alle 22 variable efterfølgende i linien, men derefter er kun de bit i strengen sat for hvilke den tilknyttede variable er ændret i forhold til den forrige linie.

Er det for kryptisk??
Avatar billede nielle Nybegynder
06. juni 2006 - 17:54 #13
Nej, det er ikke spor kryptisk, men svaret er fortsat det samme: Der findes i VB (mig bekendt) ikke nogen mulighed for at læse en fil på et mere findelt niveau end en enkelt byte af gangen.
Avatar billede jeffee Nybegynder
07. juni 2006 - 10:13 #14
Ok.. Det var ærgerligt - men trods alt ikke nogen katastrofe. Det kører jo fint nok med oversættelsen.... Bare lidt spild af regnekraft..

Nielle du kan lige smide et svar så kan i dele dem for indsatsen.
Avatar billede nielle Nybegynder
07. juni 2006 - 17:50 #15
Ok. :^)

Jeg tror dog ikke at du skal bekymre dig alt for meget om tabt regnekraft. Selv på maskinsprogs-niveau læses der på byte-niveau som det fineste. Faktisk er det endda mere effektivt at læse på word-niveau (2 bytes) ... eller sådan har det i hvert fald været engang. Hvis Fortran kan læse på bit-niveau, så må dette trick nødvendigvis ske ved at læse bytes og så trække bitsene ud af disse; Fortran kamouflere m.a.o. det som du selv ville gøre i din VB kode, og den bruger derfor den samme regnekraft til formålet.
Avatar billede jeffee Nybegynder
08. juni 2006 - 08:04 #16
Tak for hjælpen..
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester