Informaticasite van het Sondervick College te Veldhoven                 © L.J.M van Haperen (bron : R.J. van der Beek)
 

Hoofdstuk 18 Java

18.7 Werken met bestanden

  18.7.1. De klasse URL.

In deze paragraaf zie je hoe je in een applet een URL kunt opgeven, en hoe je de pagina van die URL dan kunt laten verschijnen in een nieuw browservenster.
Daar heb je niet zo veel aan, maar je kunt aan dit applet wel zien hoe je kunt manipuleren met URL's.
Je moet daarbij gebruik maken van de klasse URL uit de package java.net.

Als je in een applet een URL wilt opvragen moet je om drie dingen denken:
  • import java.net.* toevoegen
  • Een URL declareren, bijvoorbeeld URL adres;
  • De URL echt maken, bijvoorbeeld zo:
    adres = new URL(string);, waarbij string de URL bevat.
    Maar dat mag niet zomaar, want een URL moet aan bepaalde eisen voldoen. Het moet bijvoorbeeld beginnen met een protocol, meestal http://. En zo zijn er nog een aantal eisen.
    Er kan van alles misgaan (hoewel java niet een goede controle uitvoert), en daarom moet er gebruik worden gemaakt van een try-catch-blok.
    (er wordt trouwens nog niet gecontroleerd of het adres op internet gevonden kan worden)

    try  
    {  
       adres = new URL(string); 
    } 
    catch (Exception e)  
    { 
      .............. 
    }

  • Door middel van de opdracht
    getAppletContext().showDocument(adres,"_blank");
    wordt er een niew browservenster geopend (de naam van het venster is _blank, en dat heeft tot gevolg dat er een nieuw venster verschijnt), en daarin verschijnt het gevraagde (als het bestaat).
Als je dus de naam van een url hebt ingetypt moet de string eerst worden omgezet in een echte URL, zoals hierboven.
Als je een URL hebt, en je wilt er een string van maken dan kan dat met de methode toString()
Dus bijvoorbeeld s = adres.toString();

In het programma hier onder wordt een URL in een tekstvenster getypt.
String s = txtUrl.getText(); heeft tot gevolg dat de string s het ingetypte adres bevat.
Dan komt er een groepje opdrachten die enige verduidelijking nodig hebben.

if (s.length() > 6)  
 { 
      if (!s.substring(0,7).toUpperCase().equals("HTTP://")) 
      s = "http://" + s; 
 } 
 else s = "http://" + s; 

Als de string s uit meer dan 6 tekens bestaat, dan wordt er gekeken of de naam wel begint met http://
Als het uit minder dan 6 tekens bestaat dan begint het zeker niet met http://, want dat zijn er al 7. Dan wordt http:// aan de naam toegevoegd (achter else: s = "http://" + s;)
Als de string s uit meer dan 6 tekens bestaat dan worden de eerste 7 tekens bekeken, want s.substring(0,7) is de substring vanaf teken 0 (dat is het eerste teken), en dan 7 tekens.
Daar wordt de methode toUpperCase() op toegepast, en dat heeft tot gevolg dat de tekens in hoofdletters worden omgezet.
En daarna wordt het vergeleken met "HTTP://". Als het daaraan gelijk is dan krijgt de hele uitdrukking de waarde true (equals betekent: is gelijk aan). Maar doordat er een uitroepteken voor staat wordt true veranderd in false of omgekeerd.
Dus als de substring niet gelijk is aan HTTP:// dan is het geheel true, en dan wordt er HTTP:// aan s toegevoegd.

De volledige code van het voorbeeld is:

import java.awt.*; 
import java.applet.*; 
import java.net.*; 
import java.awt.event.*; 

public class Oefening7 extends Applet implements ActionListener
{
    TextField txtUrl; 
    Button cmdLaatzien; 
    URL adres; 

    public void init()
    {
       setLayout(new FlowLayout()); 
       txtUrl = new TextField("informaticavo.nl"); 
       cmdLaatzien = new Button("Laat de pagina zien!");
       cmdLaatzien.addActionListener(this); 
       add(txtUrl); 
       add(cmdLaatzien);
    }
      
    public void actionPerformed(ActionEvent act)  
    { 
       String s = txtUrl.getText(); 
       if (s.length() > 6)  
       { 
            if (!s.substring(0,7).toUpperCase().equals("HTTP://")) 
            s = "http://" + s; 
       } 
       else s = "http://" + s;  

       // zorg ervoor dat de string in een echte URL wordt gewijzigd 
       // en laat de pagina zien in een browservenster
       try  
       {  
            adres = new URL(s);
            getAppletContext().showDocument(adres,"_blank");  
       } 
       catch (Exception e)  
       { 
            txtUrl.setText("fout adres");  
       }  
     } 

}

In het applet hieronder kun je het uitproberen. Typ het adres van een internetsite (de complete URL) en klik op "Laat de pagina zien".



  18.7.2. Gegevensstromen.

Je kunt ook werken met bestanden op internet via Java, maar dat heeft wel beperkingen.
Je kunt alleen bestanden inlezen van de server, waarop het applet staat. Als je probeert een bestand van een andere site in te lezen of er naartoe te schrijven, dan wordt er een zogenaamde SecurityException opgeworpen.

Als je de inhoud van een bestand op internet wilt inlezen en tonen m.b.v. van een applet dan moet je gebruik maken van de methode openStream van de klasse URL.
Je moet dan klassen gebruiken uit de package java.io, dus je moet de volgende regel toevoegen:
import java.io.*

Als je de methode openStream toepast op een URL dan levert dat een zogenaamde InputStream op, zeg maar een bulk tekens.
Je gebruikt daarvoor de opdracht
InputStream is = adres.openStream();

Die bulk tekens moet worden ingelezen, en daarvoor kun je een InputStreamReader gebruiken.
Die moet je toepassen op de InputStream m.b.v. de opdracht
InputStreamReader ir = new InputStreamReader(is);
Maar een nadeel van een InputStreamReader is dat die de stroom gegevens alleen teken voor teken kan lezen.
Meestal is het handiger steeds een hele regel in te lezen, en zo regel na regel alles in te lezen.
Dat kan als je een BufferedReader gebruikt. En die kun je krijgen door de InputStreamReader als parameter te nemen.
Dat doe je m.b.v. de volgende opdracht:
BufferedReader dis = new BufferedReader(new InputStreamReader(is));

Een BufferedReader kent o.a. de volgende methoden:
  • int read();
    De methode read() zonder parameters leest het eerstvolgende karakter van de invoerstroom en geeft het resultaat als een geheel getal.
    Om dat geheel getal (int) vervolgens om te zetten naar een char moeten we gebruik maken van een typecast.
    (Typecasten betekent dat een variabele van een bepaald type wordt omgezet in een ander type, en dat doe je door de naam van de variabele of de uitdrukking te laten voorafgaan door de naam van het gewenste type, tussen haakjes)
    bijvoorbeeld: char c = (char) bestand.read();
    Als de read-instructie daarna weer wordt gebruikt dan wordt het volgende karakter van de invoerstroom gelezen.
    Als het laatste teken is ingelezen, en de read-instructie wordt daarna weer gebruikt, dan wordt het getal -1 als resultaat gegeven.

  • String readLine()
    Die leest een zin tot aan het einde-regel-teken (in java aangegeven met '\n')
    M.b.v. de opdracht String r = dis.readLine(); wordt de eerstvolgende regel ingelezen. Of als er geen regel meer is dan bevat de variabele r de waarde null.
De opdracht is.close(); dient om het invoerbestand (de InputStream) netjes af te sluiten.

Exceptions
Als je een bestand wilt inlezen moet je altijd rekening houden met fouten, die kunnen optreden.
Er kunnen verschillende soorten fouten optreden.
Als het bestand, dat je wilt inlezen, helemaal niet bestaat (je hebt bijvoorbeeld een typefout gemaakt bij het invoeren van de naam van het bestand) dan wordt er een zogenaamde MalformedURLException opgeworpen. En die moet worden opgevangen m.b.v. een try-catch blok.
Als het bestand wel bestaat, maar het is beschadigd of iets dergelijks, dan kan er een leesfout ontstaan. Dan wordt er een zogenaamde IOException opgeworpen. En ook zo'n fout moet worden opgevangen m.b.v. een try-catch blok.

  18.7.3. De volledige code.

import java.awt.*;
import java.io.*;
import java.net.*;
import java.applet.*;
import java.awt.event.*;
 
public class Fileinlezen extends Applet implements ActionListener
{
    String Filenaam="";
    Label lblBestand;
    TextField txtBestand;
    Button cmdLaatzien;
    List lstInhoudfile;

   public void init() {
      setLayout(null);
      setSize(435,390);
      
      lblBestand = new Label("Naam bestand",Label.CENTER);
      lblBestand.setBounds(20,20,140,25);
      lblBestand.setFont(new Font("TimesRoman", Font.PLAIN, 18));
      lblBestand.setForeground(new Color(255,255,255));
      lblBestand.setBackground(new Color(255,0,0));
      add(lblBestand);
      
      txtBestand = new TextField();
      txtBestand.setBounds(160,20,260,25);
      txtBestand.setFont(new Font("Dialog", Font.PLAIN, 12));
      add(txtBestand);
      
      cmdLaatzien = new Button("Laat de inhoud van het bestand zien");
      cmdLaatzien.setBounds(20,50,400,25);
      cmdLaatzien.setFont(new Font("Dialog", Font.BOLD, 14));
      cmdLaatzien.setBackground(new Color(150,150,150));
      add(cmdLaatzien);
      cmdLaatzien.addActionListener(this);

      lstInhoudfile = new List();
      lstInhoudfile.setBounds(20,80,400,300);
      lstInhoudfile.setFont(new Font("Dialog", Font.BOLD, 10));
      lstInhoudfile.setBackground(new Color(200,200,200));
      this.add(lstInhoudfile);
   }
 
    public void actionPerformed(ActionEvent evt)  
     { 
       String r;
       URL adres=null;
       Filenaam = txtBestand.getText();
        
        try
        {
           adres = new URL(Filenaam);
        } 
        catch(MalformedURLException e) 
        {
           txtBestand.setText("Verkeerde URL ");
           stop();
        }
 
        try
        {
           InputStream is = adres.openStream();
           BufferedReader dis = new BufferedReader(new InputStreamReader(is));
           while((r = dis.readLine()) != null) 
           {
              lstInhoudfile.add(r);
           }
           is.close();
         }
         catch(IOException e) {}
      }
 }

In het applet hieronder kun je het uitproberen. Typ de naam van een bestand van deze site in (de complete URL, beginnend met http://lcinformatica.nl/) en klik op "Laat de inhoud van het bestand zien".