Föreläsning 14 Filhantering
Filhantering Att hantera filer, dvs att läsa eller skriva data till en fil är en viktig del i de flesta program. Ur Javas synvinkel är filer objekt med egenskaper och metoder precis som vilka andra objekt. Bland en fils egenskaper finns dess namn och dess plats i sekundärminnet. Platsen ges av sökvägen: - /home/sanders/book/ch8-examples/fish.java (Linux) - C:\Windows\Desktop\book\ch8-examples\Fish.java (Windows) Båda dessa sökvägar anger platsen för en fil kallad Fish.java. I Java finns klassen File vars objekt sammanlänkar program med fysiska filer. Till File-klassen finns många metoder (se Java API). 2
Klassen File Detta exempel visar hur ett Fileobjekt skapas med ett filnamn. Med metoderna getname och getpath kan vi komma åt filens namn och plats. OBS! Fileobjektet är bara en länk mellan programmet och den fysiska filen. Resultat efter testkörning. 3
Läsa från fil När man läser från tangentbordet skapar man ett Scanner-objekt enligt: Scanner scanner = new Scanner(System.in); System.in är ett objekt som motsvarar tangentbordet. På samma sätt motsvarar File-objekt filer. När man läser från en fil med filnamn fn skapar man ett Scanner-objekt enligt nedan: Scanner scanner = new Scanner(new File(fn)); Att använda Scanner-objekt till att läsa från filer fungerar ungefär på samma sätt som att använda Scanner-objekt till att läsa från tangentbordet. 4
Läsa från fil Skillnaden mellan att läsa från en fil och från tangentbordet är att: - filen kanske inte existerar - filen existerar men finns i fel katalog - filen finns i rätt katalog men användaren har skrivit in namnet inkorrekt - filen finns i rätt katalog och är rätt inskriven av användaren, men användaren har inte rättighet att läsa den Dessutom kan man inte kompilera satsen: Scanner scanner = new Scanner(new File(fn)); Man får följande felmeddelande: Unhandled exception type FileNotFoundException FileNotFoundException tillhör de undantag som måste tas om hand. 5
En del av Javas Exception-hierarki Throwable Error Exception ClassNotFoundException IOException RuntimeException FileNotFoundException IndexOutOfBoundsException NullPointerException ArrayIndexOutOfBoundsException NoSuchElementException InputMismatchException 6
import java.io.*; import java.util.*; Läsa från fil public class TestIO { public TestIO() throws FileNotFoundException { System.out.println("Enter a file name: "); Scanner kbd = new Scanner(System.in); String fn = kbd.next(); Scanner file = new Scanner(new File(fn)); System.out.println(file.nextLine()); file.close(); Alternativ 1: Lägg till throws. Scanner-object kopplat till tangentbordet Scanner-object kopplat till fil public static void main(string [] args) throws FileNotFoundException { new TestIO(); 7
import java.io.*; import java.util.*; Läsa från fil public class TestRead { public TestRead() { System.out.println("Enter a file name: "); Scanner kbd = new Scanner(System.in); String fn = kbd.next(); try { Scanner file = new Scanner(new File(fn)); System.out.println(file.nextLine()); file.close(); catch(filenotfoundexception fnfe) { System.out.println("Can't open file"); public static void main(string [] args) { new TestRead(); Alternativ 2: Omslut med try/catch. 8
import java.io.*; import java.util.*; Skriva till fil public class TestWrite { public TestWrite() { System.out.println("Enter a file name: "); Scanner kbd = new Scanner(System.in); String fn = kbd.next(); try { PrintWriter file = new PrintWriter(new File(fn)); file.println("hoppsan"); file.close(); catch(filenotfoundexception fnfe) { System.out.println("Can't open file"); public static void main(string [] args) { new TestWrite(); PrintWriter har samma metoder som System.out 9
Tillämpning Använd metoden //Pre: true //Post: resultat = sant om program har balanserade //parentespar (), {, [], annars falskt public boolean isbalanced(string program) för att kontrollera om ett java-program har balanserade parentespar. Låt användaren skriva in namnet på filen. Läs hela filen och lägg innehållet i en sträng med metoden //Pre: true //Post: resultat = en sträng med innehållet i filen som //Scanner-objektet sc är kopplat till public String file2string(scanner sc) 10
Tillämpning //Pre: true //Post: resultat = en sträng med innehållet i filen //som Scanner-objektet är kopplat till public String file2string(scanner sc) { boolean cont = true; String str = ""; while (cont) { try { str += sc.nextline(); catch (NoSuchElementException e) { System.out.println("End of file"); cont = false; return str; 11
Tillämpning public Test() { StackApp stackapp = new StackApp(); System.out.println("Enter a file name: "); Scanner kbd = new Scanner(System.in); String fn = kbd.next(); try { Scanner file = new Scanner(new File(fn)); String str = file2string(file); if (stackapp.isbalanced(str)) System.out.println("Parenteserna är balanserade"); else System.out.println("Parenteserna är inte balanserade"); file.close(); catch(filenotfoundexception fnfe) { System.out.println("Can't open file"); 12
Binära sökträd till fil Hur kan man spara undan ett binärt sökträd på en fil för att man senare ska kunna återskapa trädet till dess ursprungsskick? Studera igen exemplet med vad som händer vid insättning i binära sökträd (se nästa bild). Vi kan konstatera att ordningen på talen spelar roll för det utseende trädet kommer att få. Dock kan vi se att trädet kan återskapas om vi sätter in talen i den följd som fås då ursprungsträdet skrivs ut i preorder. Detta kan vi utnyttja då vi vill skriva ut trädet på fil: skriv ut det i preorder, då kan vi med lätthet återskapa det igen genom att läsa in talen i ordning och sätta in dem i ett nytt träd. 13
Insättning i ett binärt sökträd Antag att vi vill sätta in talen 7, 10, 1, 0, -3, 45, 15, 8 i den ordning de anges i ett binärt sökträd. Hur går vi då till väga? Börja med ett tomt träd och lägg 7 i rotnoden. Tag sedan 10 och då 10 > 7 sätts 10 in som högerbarnnod till 7. Fortsätt på samma sätt med resten av talen. Vad händer om talen i talföljden byter ordning? 7 START 1 10 0 8 45-3 15 Preorder: 7, 1, 0, -3, 10, 8, 45, 15 Inorder: -3, 0, 1, 7, 8, 10, 15, 45 Postorder: -3, 0, 1, 8, 15, 45, 10, 7 14