Java II - 1 Strömmar • Vid läsning och skrivning används något som kallas strömmar. • En ström är ett flöde av data som strömmar in eller ut från ett program. • Man skiljer på inströmmar och utströmmar. – En ström har en koppling till en fil, en enhet, eller en kommunikationsförbindelse och används för att skriva eller läsa data till denna koppling Java II - 2 Klassen System • Klassen System, i paketet java.lang innehåller tre olika strömmar, definerade som klassvariabler. System.in System.out System.err • System.in är ett statiskt objekt av klassen InputStream. • System.out och System.err är statiska objekt av klassen PrintStream. • Både System.out och System.err brukar vara kopplade mot skärmen, medan System.in brukar vara kopplad mot tangentbordet. Java II - 3 Klassen System import java.io.*; public final class System { //.. . public static final PrintStream err; public static final InputStream in; public static final PrintStream out; //.. . } public abstract class InputStream { //.. . public abstract int read() throws IOException; //.. . } Metoden ”read()” är abstrakt eftersom den måste definieras i en subklass som är kopplad till en faktisk kommunikationskanal, i detta fall till tangentbordet. Java.io, klasser som läser byteströmmar Java II - 4 InputStream SequenceInputStream FileInputStream PipedInputStream ByteArrayInputStream FilterInputStream DataInputStream PushBackInputStream BufferedInputStream Några metoder i Inputstream Java II - 5 Metoder som läser ett byte eller ett fält av byten abstract int read() throws IOExeption OBS! Abstrakt metod. Läser nästa byte och returnerar det som en int. int read(byte[] b) throws IOExeption Läser ett antal byte till vektorn ”b”. Antalet lästa bytes returneras. int read(byte[] b, int off, int len) throws IOExeption Läser ett antal byte till fältet ”b”. Första byte läggs i ”b[off]”. Maximalt läses ”len” stycken bytes. Antalet lästa bytes returneras. Java.io, klasser som skriver byteströmmar Java II - 6 OutputStream FileOutputStream PipedOutputStream ByteArrayOutputStream FilterOutputStream DataOutputStream PrintStream BufferedOutputStream Några metoder i Outputstream Java II - 7 Metoder som skriver ett byte eller ett fält av byten i outputstream abstract void write(int b) throws IOExeption OBS! Abstrakt metod. Skriver byte ”b” till utströmmen void write(byte[] b) throws IOExeption Skriver ”b.length” byte från vektorn ”b” void write(byte[] b, int off, int len) throws IOExeption Skriver ett antal byte till fältet ”b”. Första byte som skrivs är ”b[off]”. Totalt skrivs ”len” stycken bytes. Ett exempel med read() och write() Java II - 8 import java.io.*; public class EnklaTecken { public static void main(String[] argument) throws IOException { while ((lästTecken = System.in.read()) >= 0) { System.out.write(lästTecken) ; } } } Utskrift Hur fungerar detta? Hur fungerar detta? Vad ska jag nu skriva.. . Vad ska jag nu skriva.. . Avsluta med <Ctrl-Z> Avsluta med <Ctrl-Z> Java.io, klassen PrintStream Java II - 9 OutputStream FileOutputStream PipedOutputStream ByteArrayOutputStream FilterOutputStream DataOutputStream PrintStream BufferedOutputStream Några metoder i klassen PrintStream Java II - 10 • Några metoder i Klassen PrintStream: Metoder som skriver ett objekt eller variabel av angiven typ till utströmmen print(Object), print(String), print(char[]), print(char), print(int), print(long), print(float), print(double), print(bolean) Metoder som skriver ett objekt eller variabel av angiven typ till utströmmen och avslutar med ett nyradstecken println(Object), println(String), println(char[]), println(char), println(int), println(long), println(float), println(double), println(bolean) • Exempel System.out.print(”Vad heter du: ”); System.out.flush(); • Strängen skrivs inte ut direkt utan mellanlagras i en utdatabuffert. Bufferten kan tömmas med hjälp av metoden flush. Funktionen println flushar bufferten automatiskt. Ett exempel på läsningJava II - 11 från System.in import java.io.*; public class Exempel { static int ettTal; static char ettTecken; public static void main(String[] argument) { System.out.print("Skriv ett tecken: "); System.out.flush(); ettTal = System.in.read(); System.out.println("Du skrev ett: " + ettTecken); } } Utskrift Skriv ett tecken: q Du skrev ett: q Java II - 12 Inläsning • Data som skrivs på tangentbordet hamnar i strömmen System.in som är ett objekt av InputStream i paketet java.io. • Det går inte att direkt läsa från System.in utan den strömmen måste kopplas till en annan ström. I jdk 1.2 går det dock. System.in (InputStream) (InputStreamReader) MinaInData (BufferedReader) BufferedReader MinaInData = new BufferedReader( new InputStreamReader(System.in)); • I klassen BufferedReader finns en metoden readLine. Java II - 13 Ett exempel på inläsning av en hel rad import java.io.*; public class Rad { public static void main(String[] argument) throws IOException { BufferedReader MinaInData = new BufferedReader(new InputStreamReader(System.in)); String namnet; System.out.print("Vad heter du: "); System.out.flush(); namnet = MinaInData.readLine(); System.out.println("Hej, " + namnet + "!"); } } Exempel på exekvering ==> java Rad Vad heter du: Hans-Edy Mårtensson Hej, Hans-Edy Mårtensson! ==> Java.io, klasser som Java II - 14 läser teckenströmmar Reader PipedReader InputStreamReader CharArrayReader FileReader BufferedReader FilterReader StringReader LineNumberReader PushbackReader Java.io, klasser som skriver teckenströmmar Java II - 15 Writer OutputStreamWriter BufferedWriter FileWriter PipedWriter FilterWriter PrintWriter StringWriter CharArrayWriter Java II - 16 Textfiler • För att läsa eller skriva en fil skall man i Java koppla en ström till filen. • Om man skall hantera binära data så väljer man lämpliga subklasser från superklassena InputStream eller OutputStream. • Om man skall hantera tecken så väljer man lämpliga subklasser från superklassena Reader eller Writer. • Om man vill koppla en fil till en teckenström kan man använda klasserna FileReader eller FileWriter. • I programmet bör man inte läsa direkt från en ström av klassen FileReader, utan i stället via BufferedReader. • På liknade sätt använder man klasserna BufferedWriter och FileWriter vid skrivning till en textfil. • För att få tillgång till metoderna print och println så kan man först låta sin teckenström passera PrintWriter. Ett exempel på accessJava II - 17 av textfiler, del 1 import java.io.*; public class Kopiera { public static void main(String[] argument) throws IOException, FileNotFoundException { //Vi skapar en indataström från tangentbordet BufferedReader inStrom = new BufferedReader( new InputStreamReader(System.in)); //Vi skapar en teckenström från den fil som ska //kopieras System.out.print("Infilens namn? : "); System.out.flush(); String filNamnet = inStrom.readLine(); BufferedReader inFil = new BufferedReader(new FileReader(filNamnet)); //Vi skapar en teckenström till den nya kopian System.out.print("Utfilens namn? : "); System.out.flush(); filNamnet = inStrom.readLine(); PrintWriter utFil = new PrintWriter( new BufferedWriter(new FileWriter(filNamnet))); //Programmet forsätter på nästa sida Ett exempel på accessJava II - 18 av textfiler, del 2 //Och nu kopierar vi den ena filen till den andra int n = 0; while (true) { String rad = inFil.readLine(); if (rad == null) break; utFil.println(rad); n++; } utFil.close(); inFil.close(); System.out.println(n + " rader kopierade"); } } Java II - 19 Inläsning av tal • Tyvärr så innehåller inte klassen BufferedReader metoder för att omvandla till strängar till numeriska data. • Det finns flera olika tekniker för att omvandla en sträng till ett tal. Ett sätt beskrivs här nedan. • Omvandlingen kan ske med hjälp av de primitiva datatypernas omslagsklasser (wrappers). String textRad = minaInData.readLine(); int mittHeltal = Integer.parseInt(textRad); • I det ovanstående exemplet används metoden parseInt i omslagsklassen Integer för att omvandla strängen textRad till motsvarande heltal. • För att omvandla ett sträng till motsvarande decimaltal måste man gå tillväga på ett något annorlunda sätt. String textRad = minaInData.readLine(); int mittDecimaltal = Double.valueOf(textRad).doubleValue(); Ett exempel på inläsning av tal Java II - 20 import java.io.*; public class Tal { public static void main(String[] argument) throws IOException { BufferedReader MinaInData = new BufferedReader( new InputStreamReader(System.in)); System.out.print("Skriv ett heltal: "); System.out.flush(); String textRad = MinaInData.readLine(); textRad = textRad.trim(); //Rensar bort blanktecken int helTalet = Integer.parseInt(textRad); System.out.println("Heltalet är: " + helTalet); System.out.print("Skriv ett decimaltal: "); System.out.flush(); textRad = MinaInData.readLine(); textRad = textRad.trim(); double decimalTalet = Double.valueOf(textRad).doubleValue(); System.out.println("Decimaltalet är: " + decimalTalet); } }