Plan for dagen Vprg 4 LC191D Videregående programmering Høgskolen i Sør-Trøndelag Avdeling for informatikk og e-læring Anette Wrålsen Del: Intro til tekstfiler Del II: Mer om tekstfiler, Scanner-klassen Del III: Binærfiler og serialisering Ca. en time på hver av delene, inkludert pauser Dagens tema - filbehandling! Hva er en datafil? En datafil inneholder data, til forskjell fra en programfil. Hva bruker vi datafiler til? Vi bruker dem til å lagre data og informasjon om programtilstand mellom kjøringer. Trenger vi datafiler? Ja! Alternativet er å bruke databaser. Strømmer Når vi skal skrive til eller lese fra en fil, gjøres det gjennom en forbindelse kalt en strøm. Vi kan ha lesestrømmer og skrivestrømmer, men vi kan ikke både lese og skrive med samme strøm. For hver fil vi skal lese fra eller skrive til må vi åpne en strøm, og strømmen må avsluttes når vi er ferdige. Tekstfiler En tekstfil er en fil som er lesbar for mennesker vedhjelp av en teksteditor. Tekstfiler kalles noen ganger sekvensielle filer fordi leses sekvensielt. De består også av en sekvens med linjer. Slike filer lagres ofte som filnavn.txt. Klassen FilLeser.java Vi skal nå se på et program som leser linje for linje fra en tekstfil. Hver linje skal skrives på skjermen.
Oppsummering Vi oppretter et FileReader-objekt (som igjen oppretter en lesestrøm og kan sende oss data fra den). Deretter oppretter vi en BufferedReader som vi kan lese gjennom for å få færre diskaksesser. Husk å lukke filen til slutt! Klassen FilSkriver.java Vi skal nå se på et program som går i løkke og skriver nye linjer til datafilen fra forrige oppgave. Oppsummering Vi oppretter FileWriter, BufferedWriter og PrintWriter-objekter for å få best mulig metoder tilgjengelig. Husk at når du skriver til fil er det ekstra viktig å huske å stenge av strømmen - ellers er faren stor for å miste data. Gruppeoppgave Lag en ren tekstfil kalt data.txt i en editor, og skriv inn navn og fødselsdato til alle i gruppa i filen (en linje per person). Lag et program som leser filen og teller antall linjer (og dermed antall personer på gruppa). Anta at dere ønsker å lagre denne informasjonen i en samling Person-objekter. Hvordan kan dere gå fram for å hente ut relevant informasjonen fra filen? Burde dere lagret dataene annerledes? Dette trenger dere ikke å programmere, men foreslå en strategi. Pause! Fram til 09:40 Scanner java.util.scanner brukes for å finne data av forskjellige typer i en strøm eller streng. Et Scanner-objekt ser på de neste tegnene i strømmen, og prøver å omforme dem til datatypen vi ber om (for eksempel int eller double). Går ikke dette, kaster den InputMismatchException. Den skanner kun framover i strømmen.
Eksempel - Klassen LesMangeTall Programmeringsoppgave Lag et program som krypterer ei tekstfil. Det skal lese et og et tegn fra tekstfila, som krypteres til heltall vha. klassen Kryptosystem som du finner i it s learning. Resultatene lagres som tall til fil med et mellomrom mellom hvert tall. Klarer du å utvide Kryptosystem med en dekrypteringsmetode og lage et dekrypteringsprogram? Prøv å bruke Scannerklassen til å scanne strenger etter tall. For spesielt interesserte: Hvordan knekker man en kryptering som denne? Pause! Fram til 10:45 Hvordan overføres tall til en tekstfil? Tekstlig vs. binær data Når dataene er lagret som tekst, er de mulige å lese for mennesker. Men vi må gå gjennom ekstra steg for å omforme tallet 25 til en bitsekvens, og senere for å oversette tilbake. Kan vi ikke lagre det direkte som 11001?
Binær overføring av data Vi kan godt lagre 25 direkte som 11001. Da lagrer vi ikke lenger som en tekstfil, men som en såkalt binær fil. Vi tenker da på filen som en lang sekvens med bits. Dette sparer en lagringsplass, men filen blir ikke leselig for mennesker. Direkte tilgang til innholdet i en fil I denne typen filer er det vanlig å hoppe fram og tilbake i filen som vi ønsker under lesing. Den er ikke organisert som linjer, så det er opp til programmereren å holde styr på hva som står hvor, helt ned til hver enkelt bit! Vi flytter oss i filen ved å hoppe et antall bytes fram eller tilbake. Det betyr at det kan være veldig krevende å holde styr på innholdet i en slik fil. Hvordan kan vi gå fram hvis vi ønsker å lagre grupper av heltall på en binær fil, der hver gruppe innholder et ukjent antall heltall? Å lagre objekter Vi har allerede jobbet med en fil som inneholdt informasjon som beskrev objekter. Men hvordan gjør man dette generelt? Java tilbyr metoder som ordner dette for oss, men ikke alle programmeringsspråk gjør det. La oss først anta at vi må gjøre det selv. Å lagre objekter forts. Vi må lagre alle attributtene til objektet i et system, for eksempel en på hver linje i en tekstfil. Har objektet andre objekter som attributter, må vi lagre informasjon om dem også, har det tabeller må de gjennomløpes osv. Dette kan bli omstendelig! Vi må altså lage en spesiell lagringsmetode for hver klasse, og en egen metode for å gjøre det motsatte.
Serialisering Java tilbyr en teknikk for å lagre objekter til fil, kalt serialisering. Det lar oss lagre hele objekter med en enkelt setning i en binær fil. Ved serialisering behandler filen sekvensielt, dvs. gjennomløpes i en retning. Hva skal til for at et objekt skal kunne serialiseres? Klassen må implementere interfacet java.io.serializable. De aller fleste klassene i Java- APIet gjør dette allerede. I prosessen lagres objektvariabler men ikke klassevariabler. Objekter som lagres får et serienummer, slik at de ikke blir lagret flere ganger enn nødvendig på samme fil. Hvis klassen endrer seg mellom skriving og lesing av filen kastes InvalidClassException. Eksempelkode Implementasjon av java.io.serializable: Lagring: Lesing: Oppgave Start på Øving 4 - der skal du først opprette en samling objekter fra en tekstfil, serialisere dem og til slutt skrive dem ut igjen for å se om det stemmer med den opprinnelige filen.