ITK:P2
F8
Strömmar
och filhantering
DSV Peter Mozelius
I/O
{
{
{
I/O = Input /Output
Input = inmatning till en process
från en fil, ett tangentbord eller från
en annan process
Output = utmatning från en
process till en fil, en skärm, en
skrivare, eller till en annan process
Strömmar
{
{
Oavsett typ av I/O så sker den i Java med
hjälp av strömmar
En ström i Java är:
z
z
z
Ett flöde av data (binär eller som text)
Ett objekt som hämtar data från en källa
– inström
Ett objekt som levererar data till en destination
– utström
Poängen är att data behandlas lika oavsett
vad som är källa eller destination
z1
Strömmar
För att få tillgång till olika typer av
strömmar i Java:
import java.io.*;
{
{
En djungel av strömtyper
z
z
byte-strömmar
char-strömmar
Byte-strömmar
o
o
o
o
Dataflödet sker i form av bytes
Har funnits i Java sedan JDK 1.0
Den inbyggda datatypen byte
1 byte = 8 bitar
Alla klasser i Java som hanterar byteströmmar har ett klassnamn där ordet
Stream ingår
Char-strömmar
o
o
o
o
Dataflödet sker i form av char
Har funnits i Java sedan JDK 1.1
Den inbyggda datatypen char
1 char = 16 bitar
Alla klasser i Java som hanterar charströmmar har ett klassnamn där ordet
Reader eller Writer ingår
z2
Två olika filtyper
{
Alla filer lagras som 1:or och 0:or
{
Binärfiler
z
z
{
Läses just som en rad 1:or och 0:or
Effektiv läsning för olika program
Textfiler
z
z
Läses som en rad av tecken
Trevlig läsning för oss människor
Utström till fil 1
{
Öppna en 8-bitars byte-ström
FileOutputStream fout =
new FileOutputStream(”minfil.txt”);
{
Buffrad utmatning genom
BufferedOutputStream bout =
new BufferedOutputStream(fout);
The Decorator Design Pattern
{
{
Ett av många designmönster
Ett enkelt designmönster där koden
från förra bilden kan skrivas om
enligt:
BufferedOutputStream bout =
new BufferedOutputStream(new
FileOutputStream(”minfil.txt”));
z3
The Decorator Design Pattern
En FileOutputStream kan dekoreras för
kryptering enligt:
{
ObjectOutputStream ous =
new ObjectOutputStream(
new CipherOutputStream(
new FileOutputStream(fil), cipher));
Poängen är att klasser inom samma familj kan kedjas
ihop dynamiskt och ytterligare klasser inte behövs
Utström till fil 2
{
Öppna en 16-bitars char-ström
till en textfil och skriv med metoden
println() lika enkelt som på P1 med
System.out.println();
PrintWriter pw = new PrintWriter(
new FileOutputStream(”minfil.txt”));
OCH SEDAN
pw.print(); ELLER pw.println();
PrintWriter
{
Klassen PrintWriter
z
Innehåller metoderna
{
{
z
{
print()
println()
Skriver ut med 16 bitar
Vi ska titta på ett kodexempel
MEN först
15 min PAUS!
z4
Att skriva till fil, exempel1
import java.io.*;
public class F8_exempel1 {
public static void main(String[] args) {
PrintWriter pout = null;
try {
pout = new PrintWriter(new
FileOutputStream("min.fil"));
}catch (FileNotFoundException fnfe) {
System.err.println("Angiven fil kunde inte
öppnas.");
System.exit(0);
}
Att skriva till fil, exempel1
{
{
{
Om filen min.fil redan finns och har
ett innehåll så kommer innehållet
att skrivas över
Ibland är detta precis vad man vill
Men ibland är det önskvärt att det
tidigare innehållet ska finnas kvar
Att skriva till fil, exempel2
try{
pout = new PrintWriter(new
FileOutputStream("min.fil", true));
}
catch (FileNotFoundException fnfe) {
System.err.println("Angiven fil
kunde inte öppnas");
System.exit(0);
}
Det som skrivs läggs till sist i filen
z5
Att skriva ut objekt
{
{
{
{
Att dela upp komplexa objekt i sina
beståndsdelar och skriva ut del för
del till en fil kan kräva mycket kod
I Java finns inbyggd serialisering
Om en klass bara implementerar
interfacet Serializable
Så kan hela objektet istället skrivas
ut på en gång med writeObject()
Att skriva ut objekt
{
Även en datasamling med ett antal
objekt kan skrivas ut i sin helhet:
ArrayList al = new ArrayList();
Lägg in en massa objekt;
out.writeObject(al);
Där out är en instans av klassen
java.io.ObjectOutputStream
Att läsa in objekt
{
Att sedan läsa in de utskrivna
objekten igen görs genom:
ObjectInputStream oin =
new ObjectInputStream(
new FileInputStream(fil));
OCH sedan
oin.readObject()
z6
Klassen ObjectOutputStream
{
Klassen ObjectOutputstream har
även en del andra instansmetoder
för enklare utskrifter som t ex:
public
public
public
public
void
void
void
void
writeBoolean(boolean b);
writeChars(String str);
writeFloat(float f);
writeDouble(double d);
RandomAccessFile
{
{
Den filåtkomst vi hittills tittat på har
varit sekventiell
För vissa tillämpningar är det bättre
med direktåtkomst (random access)
RandomAccessFile
RandomAccessFile raf = new
RandomAccessFile(”lager.fil”, ”rw”);
Skapar en direktaccessfil som det går
att både läsa och skriva till
Flytta sedan inom filen med raf.seek();
15 min PAUS!
z7
En meny för filinläsning
{
I program med grafiskt gränssnitt
vill man ofta ha menyer i stil med
En meny för filinläsning
{
Menyval kan som i kursbokens kap
14 skapas enligt:
public JMenuBar skapaArkivMeny() {
filBar = new JMenuBar();
arkivMeny = new JMenu("Arkiv");
arkivMeny.setMnemonic('a');
filBar.add(arkivMeny);
En meny för filinläsning
Menyerna behöver också lyssnas av
MenuListener ml = new MenuListener(this,
meddelandeRuta, infoRuta);
mItem = arkivMeny.add(
new JMenuItem("Öppna", 'ö'));
mItem.addActionListener(ml);
mItem = arkivMeny.add(
new JMenuItem("Avsluta", 'a'));
mItem.addActionListener(ml);
z8
En meny för filinläsning
Menylyssnaren är en egendefinierad klass
som implementerar interfacet ActionListener
class MenuListener implements
ActionListener {
med vår gamle vän
public void actionPerformed(
ActionEvent e) {
En dialog för att välja fil
JFileChooser fc = new JfileChooser();
int val = fc.showOpenDialog(fönster);
Användarens filval
{
Att användaren verkligen har valt
en fil och inte avbrutit dialogen kan
kontrolleras genom:
if(val == JFileChooser.APPROVE_OPTION)
{
Sedan inleds filinläsningen med:
BufferedReader inFil = null;
try {
z9
Att läsa in vald fil
inFil = new BufferedReader(new
FileReader(jfc.getSelectedFile()));
String rad;
while((rad = inFil.readLine())!= null)
meddelande += "\n" + rad;
}catch(FileNotFoundException fnfe){…
}catch (IOException e){…}
Ett egendefinierat filfilter
{
Det kan vara praktiskt att filtrera bort de
filtyper som man INTE vill läsa in:
private class InFilter extends
javax.swing.filechooser.FileFilter {
public boolean accept(File f) {
if(f.getName().toLowerCase().endsWith(".fil"))
return true;
else
return false;
}
...
Er inlämningsuppgift
{
Jobba nu på med:
Tack för idag!
z10