Algoritmer og datastrukturer Vedlegg A.2 BitOutputStream

Like dokumenter
Algoritmer og datastrukturer A.1 Filbehandling på bit-nivå

Algoritmer og datastrukturer A.1 BitInputStream

Algoritmer og datastrukturer Vedlegg A.4 Filbehandling på char-nivå

Algoritmer og datastrukturer Kapittel 3 - Delkapittel 3.1

Algoritmer og datastrukturer Kapittel 5 - Delkapittel 5.4

Algoritmer og datastrukturer E Løkker i Java

Algoritmer og datastrukturer Kapittel 9 - Delkapittel 9.1

Algoritmer og datastrukturer Eksamen 22. februar 2011

UNIVERSITETET I OSLO

Algoritmer og datastrukturer Eksamen

UNIVERSITETET I OSLO

Algoritmer og datastrukturer Kapittel 2 - Delkapittel 2.1

Hva er verdien til variabelen j etter at følgende kode er utført? int i, j; i = 5; j = 10; while ( i < j ) { i = i + 2; j = j - 1; }

Algoritmer og datastrukturer Kapittel 1 - Delkapittel 1.8

Algoritmer og datastrukturer Kapittel 9 - Delkapittel 9.2

Algoritmer og datastrukturer Løsningsforslag

Algoritmer og datastrukturer Vedlegg A.3 Filer på byte-nivå

Algoritmer og datastrukturer Kapittel 4 - Delkapittel 4.3

Fagnr: A. Ant. vedlegg: 1 (2 sider)

Algoritmer og datastrukturer Løsningsforslag

UNIVERSITETET I OSLO

IN Notat om I/O i Java

Algoritmer og datastrukturer Eksamen

Algoritmer og datastrukturer Kapittel 4 - Delkapittel 4.4

Fagnr: A. Ant. vedlegg: 1 (2 sider)

UNIVERSITETET I OSLO

Algoritmer og datastrukturer Kapittel 1 - Delkapittel 1.3

INF Notat om I/O i Java

G høgskolen i oslo. Emne: Algoritmer og datastrukturer. Emnekode: 80131A. Faglig veileder: UlfUttersrud. Gruppe(r) : Dato:

Obligatorisk oppgave 5: Labyrint

Algoritmer og datastrukturer Eksamen

UNIVERSITETET I OSLO

INF 1010, vår 2005 Løsningsforslag uke 11

Løsningsforslag til eksamen i INF1000 våren 2006

UNIVERSITETET I OSLO

Algoritmer og datastrukturer Eksamen

2 Om statiske variable/konstanter og statiske metoder.

Hittil har programmene kommunisert med omverden via tastatur og skjerm Ønskelig at data kan leve fra en kjøring til neste

INF1000 EKSTRATILBUD. Stoff fra uke 1-5 (6) 3. oktober 2012 Siri Moe Jensen

Algoritmer og datastrukturer Kapittel 11 Delkapittel 11.2

IN1010 V18, Obligatorisk oppgave 5

INF Uke 10. Ukesoppgaver oktober 2012

class Book { String title; } class Dictionary extends Book { int wordcount; } class CartoonAlbum extends Book { int stripcount; }

Gjennomgang prøveeksamen oppgave 1, 2, 4, 5, 7

Arv. Book book1 = new Book(); book1. title = "Sofies verden" class Book { String title; } class Dictiona ry extends Book {

Oblig4 - forklaringer. Arne og Ole Christian

Programmering i C++ Løsningsforslag Eksamen høsten 2005

Rekker (eng: series, summations)

TOD063 Datastrukturer og algoritmer

UNIVERSITETET I OSLO

Algoritmer og datastrukturer Løsningsforslag

Rekker (eng: series, summations)

Algoritmer og datastrukturer Kapittel 1 - Delkapittel 1.3

Algoritmer og datastrukturer Kapittel 2 - Delkapittel 2.2

EKSAMEN 6108/6108N PROGRAMMERING I JAVA Alt trykt og skriftlig materiale.

UNIVERSITETET I OSLO

EKSAMEN. Dato: 9. mai 2016 Eksamenstid: 09:00 13:00

INF1000: noen avsluttende ord

Teori og oppgaver om 2-komplement

Løsnings forslag i java In115, Våren 1996

Å lese tall fra en fil, klassen Scanner

EKSAMEN. Dato: 18. mai 2017 Eksamenstid: 09:00 13:00

IN1010 V19, Obligatorisk oppgave 2

UNIVERSITETET I OSLO

Innhold uke 4. INF 1000 høsten 2011 Uke 4: 13. september. Deklarasjon av peker og opprettelse av arrayobjektet. Representasjon av array i Java

INF Løsning på seminaropppgaver til uke 8

Eksamen i emnet INF100 Grunnkurs i programmering (Programmering I) og i emnet INF100-F Objektorientert programmering i Java I

Jentetreff INF1000 Debugging i Java

EKSAMENSFORSIDE Skriftlig eksamen med tilsyn

Oppgave 1. Oppgave 2. Høgskolen i Østfold Avdeling for informasjonsteknologi

UNIVERSITETET I OSLO

Kom forberedt til tirsdag. INF1000 Tips til obligatorisk oppgave 4. Noen generelle tips. Oblig4: Komme igang

2 Om statiske variable/konstanter og statiske metoder.

INF1000 Behandling av tekster

Algoritmer og datastrukturer Løsningsforslag

i=0 Repetisjon: arrayer Forelesning inf Java 4 Repetisjon: nesting av løkker Repetisjon: nesting av løkker 0*0 0*2 0*3 0*1 0*4

Forelesning inf Java 4

Seminaroppgaver IN1010, uke 2

INF1010 Sortering. Marit Nybakken 1. mars 2004

programeksempel Et større En større problemstilling Plan for forelesingen Problemstillingen (en tekstfil) inneholdt ordet "TGA"

EKSAMEN med løsningsforslag

Argumenter fra kommandolinjen

Informasjon Prøveeksamen i IN1000 høsten 2018

UNIVERSITETET I OSLO

3 emner i dag! INF1000 Uke 5. Objekter og pekere. null. Litt om objekter, pekere og null Filer og easyio Litt mer om tekster

Oblig 4Hybelhus litt mer tips enn i oppgaven

Algoritmer og datastrukturer Eksamen

Leksjon 7. Filer og unntak

Lese fra fil. INF1000 : Forelesning 5. Eksempel. De vanligste lesemetodene. Metoder:

Tre måter å lese fra terminal. Java 4. Eksempel. Formatert utskrift til skjerm

Oblig 4 (av 4) INF1000, høsten 2012 Værdata, leveres innen 9. nov. kl

INF1000 Metoder. Marit Nybakken 16. februar 2004

INF1000-SIKT - Notat om I/O i Java

Oppgavesettet består av 7 sider, inkludert denne forsiden. Kontroll& at oppgaven er komplett før du begynner å besvare spørsmålene.

INF 1000 Prøveeksamen. 23. november Ole Christian og Arne. Oppgave 1 (10 poeng) Er disse programsetningene lovlige i Java? Oppgave 2 (10 poeng)

INF1000 Prøveeksamen Oppgave 7 og 9

Endret litt som ukeoppgave i INF1010 våren 2004

Dagens tema: 12 gode råd for en kompilatorskriver

Løse reelle problemer

Fagnr: SO 131 A. Ant. vedlegg: 1 (2 sider)

Transkript:

Vedlegg A.2 BitOutputStream Side 1 av 6 Algoritmer og datastrukturer Vedlegg A.2 BitOutputStream A.2 BitOutputStream A.2.1 Instansiering og skriving BitOutputStream har fire konstruktører og to konstruksjonsmetoder (eng: factory methods): public BitOutputStream(OutputStream out ) // konstruktør public BitOutputStream(OutputStream out, int size) // konstruktør public BitOutputStream(String filename) // konstruktør public BitOutputStream(String filename, int size) // konstruktør public static BitOutputStream tofile(string filename) public static BitOutputStream tofile(string filename, boolean append) Programkode A.2.1 a) BitOutputStream bruker en int-variabel og en byte-tabell som interne buffere for å kunne gjøre bithåndteringen og fil-skrivingen mest mulig effektiv. Når byte-tabellen blir full skrives innholdet automatisk ut ved hjelp av én skriveoperasjon. Standardstørrelsen på byte-tabellen er 4kb, men det er mulig å velge en annen størrelse (parameteren size). En kan enten knytte en BitOutputStream til en OutputStream eller til et filnavn. Hvis vi skal opprette en instans av BitOutputStream knyttet til en filen "utfil.txt" (og med standard bufferstørrelse), kan vi gjøre det på en av flg. to måter. Hvis det er en fil med dette navnet fra før, blir den overskrevet (egentlig fjernet og erstattet med en med samme navn): String utfil = "utfil.txt"; BitOutputStream ut1 = new BitOutputStream(utfil); // konstruktør BitOutputStream ut2 = BitOutputStream.toFile(utfil); // konstruksjonsmetode Programkode A.2.1 b) Hvis "utfil.txt" finnes fra før og vi ønsker å skrive videre på den, settes append til true: BitOutputStream ut1 = BitOutputStream.toFile("utfil.txt", true); BitOutputStream ut2 = new BitOutputStream(new FileOutputStream(utfil,true)); En instans av BitOutputStream «lukkes» ved void close(). BitOutputStream har åtte skrivemetoder: public void write0bit() // 0-bit public void write1bit() // 1-bit public void writebit(int bit) // den siste i bit public void write(int value) // 8 biter public void writebits(int value, int numberofbits) // numberofbits biter public void writebits(int value) // signifikante biter public void writeleftbits(int value, int numberofbits) // numberofbits biter public void writeleftbits(int value) // omvendt signifikante Programkode A.2.1 c)

Vedlegg A.2 BitOutputStream Side 2 av 6 De tre første write-metodene er vel selvforklarende. Metoden write(int value) skriver ut de åtte siste og writebits(int value, int numberofbits) de numberofbits siste bitene i value. Metoden writebits(int value) skriver ut de signifikante bitene, dvs. alle bitene fra og med første (fra venstre) 1-bit. Det betyr spesielt at hvis value er negativ, vil alle bitene bli skrevet ut. Tallet 0 har egentlig ingen signifikante biter, men hvis value er 0, vil det likevel bli skrevet ut en 0-bit. Se flg. eksempel. Hva vil filen inneholde i tekstformat? BitOutputStream ut = BitOutputStream.toFile("utfil.txt"); ut.writebit(0); // skriver ut en 0-bit ut.writebits(32); // skriver ut de signifikante bitene, dvs. 100000 ut.write1bit(); // skriver ut en 1-bit ut.writebits('b', 16); // skriver ut 0000000001000010 ut.close(); // VIKTIG: Avslutt alltid med close() Programkode A.2.1 d) Vi får bitsekvensen 010000010000000001000010 = 01000001 00000000 01000010 = A B De to siste write-metodene er mer spesielle. Det normale er at biter blir hentet fra høyre ende av parameterverdien. Men i noen situasjoner kan det være aktuelt å hente bitene fra venstre ende. Metoden writeleftbits(int value, int numberofbits) skriver derfor ut de numberofbits første bitene i value. Metoden writeleftbits(int value) skriver ut de «omvendt signifikante» bitene i value, dvs. alle bitene (fra venstre) til og med siste 1-bit. Hvis f.eks. siste bit i value er en 1-bit, vil alle bli skrevet ut. Hvis value er 0, blir det ikke skrevet ut noe: BitOutputStream ut = BitOutputStream.toFile("utfil.txt"); int a = 'A' << 24; // a = 01000001000000000000000000000000 ut.writeleftbits(a); // skriver ut 01000001 ut.writeleftbits(a, 8); // skriver ut 01000001 ut.close(); // VIKTIG: Avslutt alltid med close() Programkode A.2.1 e) Oppgaver til A.2.1 1. BitOutputStream er en subklasse av klassen OutputStream. Metoden write(int value) (se Programkode A.2.1 c) arves derfra. Den skriver ut en byte (dvs. de siste åtte bitene i value). OutputStream har to utskriftsmetoder til (står ikke i Programkode A.2.1 c). De skriver ut av en byte-tabell. Lag en BitOutputStream slik som i Programkode A.2.1 d), lag en byte-tabell med bokstavene A, B, C og D og skriv den til "utfil.txt". Sjekk etterpå at filen fikk det innholdet. 2 Lag kode slik at "utfil.txt" får bokstavene A, B, C og D med kun to write-setninger. Det er kun de fra Programkode A.2.1 c som skal brukes. 3 Som i Oppgave 2, med med kun én write-setning fra Programkode A.2.1 c.

Vedlegg A.2 BitOutputStream Side 3 av 6 A.2.2 Missing bits, close og flush Avslutningsmetoder: public int missingbits() public void flush() public void close() // det som mangler på en hel byte // tømmer (og skriver ut) bufrene // flusher og lukker Programkode A.2.2 a) Hvis en skal skrive ut et variabelt antall biter, vil som oftest ikke det sammenlagte antallet biter bli delelig med 8, dvs. at det tilsammen ikke blir et helt antall byter. Se flg. eksempel: BitOutputStream ut = BitOutputStream.toFile("utfil.txt"); ut.writebits(-1,9); // skriver ut 9 biter, dvs: 111111111 ut.writebits(45,7); // skriver ut 7 biter, dvs: 0101101 ut.writebits(22,5); // skriver ut 5 biter, dvs: 10110 ut.close(); // VIKTIG: Avslutt alltid med close() Programkode A.2.2 b) I koden over blir det skrevet ut 9 + 7 + 5 = 21 biter. Det gir et problem. Normalt er én byte den minste enheten for utskrift. BitOutputStream løser dette ved at biter fortløpende settes sammen til byter som så skrives ut. Dette går bra inntil vi skal avslutte. Da kan det være at vi ikke har nok biter til å fylle den siste byten. Systemet løser det selv ved at et tilstrekkelig antall 0-biter legges på til slutt. I Programkode A.2.2 b) der det skrives ut 21 biter, vil det internt bli lagt til 3 ekstra 0-biter bakerst. Tilsammen 24 biter som utgjør 3 byter. Utskriftsfilen "utfil.txt" vil derfor komme til å inneholde flg. 24 biter: 111111111010110110110000 Når en fil som er laget på denne måten, senere skal leses, vil problemet dukke opp igjen. Hvis det ligger en eller flere 0-biter bakerst på filen, er det ikke mulig å vite om det er biter vi har skrevet ut eller om det er biter som systemet selv har lagt til. Hvis det er viktig å vite dette, må vi «notere» det antallet 0-biter som systemet har lagt inn. Eventuelt kan vi i steden «notere» det totale antallet biter som write-metodene har skrevet ut. Metoden public int missingbits() forteller til enhver tid hvor mange biter som mangler for å kunne fylle den siste byten, dvs. et heltall i intervallet [0,7]. Hvis f.eks. den kalles rett før vi lukker, så får vi vite hvor mange 0-biter systemet kommer til å legge til bakerst. Det er særdeles viktig at vi lukker ved hjelp av metoden close() når vi er ferdige med skrivingen. Hvis ikke kan vi risikere at ikke alle bitene blir skrevet ut. Det kommer av at BitOutputStream bruker et internt buffer-system. Den interne byte-tabellen blir automatisk «tømt» (dvs. innholdet skrives ut) når det er fullt. Men det vil normalt ligge noe igjen i begge de interne bufferne (en int og en byte-tabell) når vi skal avslutte. Dette blir garantert skrevet ut når close() kalles. Det vil kunne være situasjoner der vi må «tømme» bufferne selv om vi ennå ikke er ferdige med skrivingen. Metoden flush() er laget for dette formålet. En må da være klar over at det vil bli lagt til tilstrekkelige mange 0-biter bakerst slik at det blir et helt antall byter. Metoden missingbits() vil som nevnt over, fortelle hvor mange. OBS: Det er ikke nødvendig eksplisitt å kalle flush() før close(). Det skjer allerede implisitt i close().

Vedlegg A.2 BitOutputStream Side 4 av 6 Oppgaver til A.2.2 1. Kjør Programkode A.2.2 b) og les filen "utfil.txt" som en tekstfil. Er den lesbar? 2. Legg inn en fjerde utskrift med lengde 3 i Programkode A.2.2 b). Bytt ut tallene -1, 5 og 22 med tall slik at slik at "utfil.txt" vil inneholde ABC. A.2.3 Testing av metoder I kodeeksemplene i avsnittene over skrev vi til en navngitt fil. Ved så å lese filen som en tekstfil, kunne vi sjekke at den inneholdt det som vi forventet. Men hvis vi skriver med et variabelt antall biter, vil filen kunne bli uleselig som en tekstfil. En mulig løsning er da å kopiere filinnholdet over i en byte-tabell og så analysere tabellen. Men dette kan vi få til uten å gå veien om den første filen. Vi kan isteden skrive til en ByteArrayOutputStream og så hente resultatet fra dens interne byte-tabell. Vi gjør litt om på Programkode A.2.2 b): ByteArrayOutputStream utskrift = new ByteArrayOutputStream(); BitOutputStream ut = new BitOutputStream(utskrift); ut.writebits(-1,9); // skriver ut 9 biter, dvs: 111111111 ut.writebits(45,7); // skriver ut 7 biter, dvs: 0101101 ut.writebits(22,5); // skriver ut 5 biter, dvs: 10110 ut.close(); // legger til tre ekstra 0-biter, dvs. 000 for (byte b : utskrift.tobytearray()) System.out.print(b + " "); // Utskrift: -1-83 -80 Programkode A.2.3 a) Metoden tobytearray() gir oss den interne byte-tabellen. Vi skriver ut 21 biter. Systemet legger til 3 0-biter. Dermed: 111111111010110110110000. Deler vi dette i åtte og åtte biter får vi 11111111 10101101 10110000. Den første (med kun 1-ere) representerer tallet -1, den andre -83 og det tredje -80. Alle er negative siden de starter med en 1-bit. Det kunne også være interessant å se selve bitinnholdet i en byte-tabell. BitOutputStream har flere muligheter for dette: public static String tobitstring(byte... b) public static String tobitstringwithspace(byte... b) public static String tobitstring(byte[] b, int[] part) public static String tobitstring(byte[] b, int numberofbits) Programkode A.2.3 b) Metoden tobitstring(byte... b) returnerer en String med bitene (som '0' og '1'). Metoden tobitstringwithspace(byte... b) gjør det samme, men med et mellomrom (space) for hver åttende bit (en byte) (Obs: byte... betyr en generalisert tabell): String biter1 = BitOutputStream.toBitString(b); String biter2 = BitOutputStream.toBitStringWithSpace(b); System.out.println(biter1 + " " + biter2); // Utskrift: 111111111010110110110000 11111111 10101101 10110000 Programkode A.2.3 c)

Vedlegg A.2 BitOutputStream Side 5 av 6 Det er også mulig å dele opp byte-tabellen i noe annet enn 8 og 8 biter, f.eks. i enheter på 5 og 5. Men hvis det totale antallet biter ikke er delelig med 5, vil den siste enheten få færre enn 5. I en byte-tabell med tre elementer er det 24 biter og dermed fire enheter med 5 biter og til slutt én enhet med 4 biter: System.out.println(BitOutputStream.toBitString(b, 5)); // Utskrift: 11111 11110 10110 11011 0000 Programkode A.2.3 d) Det må ikke deles opp i like store enheter. I Programkode A.2.3 a) tabellen til ved utskrift av forskjellige lengder. Vi kan dele den opp på samme måte: int[] oppdeling = {9, 7, 5}; System.out.println(BitOutputStream.toBitString(b, oppdeling)); // Utskrift: 111111111 0101101 10110 Programkode A.2.3 e) Summen av tallene i oppdelingstabellen må ikke, slik som også eksemplet over viser, være er lik antall biter i byte-tabellen. Hvis oppdelingen f.eks. er på 1, 2, 3 og 4 (sum = 10), kommer kun de 10 første bitene ut. Hvis den f.eks. er på 1, 2, 3, 4, 5, 6 og 7 (sum = 28), vil det kun komme ut 3 biter siste gang (og ikke 7) siden det kun er 3 biter igjen. int[] oppdeling = {1, 2, 3, 4, 5, 6, 7}; System.out.println(BitOutputStream.toBitString(b, oppdeling)); // Utskrift: 1 11 111 1110 10110 110110 000 Oppgaver til A.2.3 Programkode A.2.3 f) 1. Skriv ut én og én bit (et mellomrom mellom hver) fra tabellen {-1, -83, -80}.

Vedlegg A.2 BitOutputStream Side 6 av 6 A.2.4 Metodeoversikt public BitOutputStream(OutputStream out) // konstruktør public BitOutputStream(OutputStream out, int size) // konstruktør public BitOutputStream(String filename) // konstruktør public BitOutputStream(String filename, int size) // konstruktør public static BitOutputStream tofile(string filename) // konstr.metoder public static BitOutputStream tofile(string filename, boolean append) public void writebit(int bit) // den siste biten i bit public void write0bit() // en 0-bit public void write1bit() // en 1-bit public void write(int b) // de siste 8 bitene i b public void writebits(int value, int numberofbits) // de bakerste public void writebits(int value) // de signifikante bitene i value public void writeleftbits(int value, int numberofbits) // de første public void writeleftbits(int value) // de omvendt signifikante bitene public void flush() public int missingbits() public void close(); // tømmer bufrene og skriver ut // det som magler på en full byte // lukker filen public static String tobitstringwithspace(byte... b) // åtte og åtte public static String tobitstring(byte... b) // sammenhengende public static String tobitstring(byte[] b, int numberofbits) // gruppevis public static String tobitstring(byte[] b, int[] part) // gruppevis Copyright Ulf Uttersrud, 2017. All rights reserved.