Wykład 10:
Wejście/Wyjście
Program realizuje wejście/wyjście przez użycie potoku.
Ten sam sposób obsługi różnych urządzeń:
●
konsola
●
klawiatura
●plik na dysku
●
gniazdko sieciowe, itp.
Program nie musi znać różnicy między obsługą np.
czytania z klawiatury, czy obsługą czytania z sieci.
Pakiet
java.io
.
Potoki
Dwa rodzaje:
●
bajtowy – pisanie/czytanie danych binarnych
●znakowy – pisanie/czytanie danych znakowych:
●
używa Unicode (internacjonalizacja)
●bardziej efektywny
Potoki Bajtowe
Klasy abstrakcyjne
InputStream
i
OutputStream
Abstrakcyjne metody
read()
i
write().
Pod-klasy:
● Buffered... buforowany I/O
● ByteArray... I/O z tablicy bajtów
● Data... I/O ze standardowych typów danych
● File... I/O z plików
● Filter... implementuje ...Stream
● Piped... łączenie potoków
● PrintStream OutputStream z print() i println()
● PushbackInputStream InputStream z "unget"
● RandomAccessFile losowy dostęp do pliku
Potoki Znakowe
Klasy abstrakcyjne
Reader
i
Writer.
Abstrakcyjne metody
read()
i
write().
Pod-klasy:
● Buffered... buforowany I/O
● CharArray... I/O z tablicy znaków
● File... I/O z plików
● Filter... I/O z filtrowaniem
● String... I/O z ciągu znaków
● Piped... łączenie potoków
● InputStreamReader translacja bajtów na znaki
● OutputStreamWriter translacja znaków na bajty
● PrintWriter OutputStream z print() i println()
Potoki Pre-Definiowane
Częścią pakietu
java.lang
jest klasa
System
.
Dostarcza trzy zmienne potokowe (
public
,
static
):
●
System.in: InputStream
standardowe urządzenie wejściowe (klawiatura)
●System.out: PrintStream
standardowe urządzenie wyjściowe (konsola)
●System.err: PrintStream
Czytanie z Konsoli
Tradycyjnie – przez potok bajtowy.
Preferowana metoda – potok znakowy jest łatwiejszy w
konserwacji i internacjonalizacji.
●
zamiana potoku bajtowego na znakowy
InputStreamReader isr =
new InputStreamReader(System.in)
●
otoczenie potoku znakowego potokiem buforowanym
BufferedReader br =
new BufferedReader(isr)
Czytanie Znaków
Czytanie znaków z
BufferedReader
:
int read() throws IOException
Czyta znak z potoku wejściowego:
●zwraca liczbę całkowitą
●
zwraca
-1
jeśli koniec potoku
Wejście jest buforowane – przekazanie danych do
programu po naciśnięciu
ENTER
.
Czytanie Znaków: Przykład
import java.io.*; class BRRead {
public static void main(String args[]) throws IOException { char c; BufferedReader br = new BufferedReader( new InputStreamReader(System.in)); System.out.println("Enter characters, 'q' to quit."); do { c = (char) br.read(); System.out.println(c); } while(c != 'q'); } }
Czytanie Łańcuchów
Czytanie ciągu znaków z klawiatury:
Czytanie Łańcuchów: Przykład
import java.io.*; class BRReadLines {
public static void main(String args[]) throws IOException { BufferedReader br = new BufferedReader( new InputStreamReader(System.in)); String str;
System.out.println("Enter lines of text."); System.out.println("Enter 'stop' to quit."); do { str = br.readLine(); System.out.println(str); } while(!str.equals("stop")); } }
Czytanie Łańcuchów: Inny Przykład
import java.io.*; class TinyEdit {
public static void main(String args[]) throws IOException
{
BufferedReader br =
new BufferedReader(
new InputStreamReader(System.in)); String str[] = new String[100];
System.out.println("Enter lines of text."); System.out.println("Enter 'stop' to quit.");
Czytanie Łańcuchów: Inny Przykład
for(int i=0; i<100; i++) { str[i] = br.readLine();
if(str[i].equals("stop")) break; }
System.out.println("\nHere is your file:"); for(int i=0; i<100; i++) {
if(str[i].equals("stop")) break; System.out.println(str[i]);
} } }
Pisanie na Konsolę
Najłatwiej przez
print()
i
println()
.
Jest też nisko-poziomowy
void write(int byteval)
class WriteDemo {
public static void main(String args[]) { int b = 'A';
System.out.write(b);
System.out.write('\n'); }
}
Mimo iż argument jest typu
int
, wypisywane jest tylko
Preferowana Metoda Pisania
Przez znakową klasę
PrintWriter
:
PrintWriter(
OutputStream outputStream,
boolean flushOnNewline)
●
outputStream
to potok wyjściowy (
System.out
)
●flushOnNewline
– czy potok jest czyszczony za
każdym wywołaniem
println()
PrintWriter
dostarcza
print()
i
println()
. Jeśli
Pisanie na Konsolę: Przykład
import java.io.*;
public class PrintWriterDemo {
public static void main(String args[]) { PrintWriter pw =
new PrintWriter(System.out, true); pw.println("This is a string"); int i = -7; pw.println(i); double d = 4.5e-7; pw.println(d); } }
Czytanie/Pisanie do Plików
Bajtowe potoki do obsługi plików. Można jest otaczać
potokami znakowymi.
Otwarcie pliku do czytania/pisania:
● FileInputStream(String fileName)
throws FileNotFoundException
● FileOutputStream(String fileName)
throws FileNotFoundException
Zamknięcie pliku po obsłudze:
Czytanie/Pisanie do Plików
Czytanie z pliku:
int read() throws IOException
Zwraca -1 gdy koniec pliku.
Pisanie do pliku:
void write(int byteval) throws IOException
Mimo iż argument jest typu
int
, wypisywane jest tylko
Czytanie Pliku: Przykład
import java.io.*; class ShowFile {
public static void main(String args[]) throws IOException
{
int i;
FileInputStream fin; try {
fin = new FileInputStream(args[0]); } catch(FileNotFoundException e) {
System.out.println("File Not Found"); return;
} catch(ArrayIndexOutOfBoundsException e) { System.out.println("Usage: ShowFile File"); return;
Czytanie Pliku: Przykład
do {
i = fin.read();
if(i != -1) System.out.print((char) i); } while(i != -1);
fin.close(); }
Pisanie do Pliku: Przykład
import java.io.*; class CopyFile {
public static void main(String args[]) throws IOException { int i; FileInputStream fin; FileOutputStream fout; try { try {
fin = new FileInputStream(args[0]); } catch(FileNotFoundException e) {
System.out.println("File Not Found"); return;
Pisanie do Pliku: Przykład
try {
fout = new FileOutputStream(args[1]); } catch(FileNotFoundException e) {
System.out.println(
"Error Opening Output File"); return;
}
} catch(ArrayIndexOutOfBoundsException e) { System.out.println(
"Usage: CopyFile From To"); return;
Pisanie do Pliku: Przykład
try { do { i = fin.read(); if(i != -1) fout.write(i); } while(i != -1); } catch(IOException e) { System.out.println("File Error"); } fin.close(); fout.close(); } }Wejściowy Potok Bajtowy
Metody definiowane przez klasę
InputStream
:
●
int available()
- liczba bajtów do czytania
●void close()
- zamyka potok
●
void mark(int numBytes)
– oznacza bieżące
miejsce w potoku do przeczytania
numBytes
znaków
●
boolean markSupported()
- czy potok wspiera
mark/reset
●
int read()
- zwraca następny dostępny bajt, lub
-1
●int read(byte buffer[])
próbuje czytać znaki
do bufora, zwraca ilość przeczytanych lub
-1
●
int read(byte buffer[],int off,int num)
–
jak wyżej, ale zapisuje z przesunięciem
off
Wejściowy Potok Bajtowy, Ciąg Dalszy
●
void reset()
– przesuwa wskaźnik pliku do
poprzednio zaznaczonej pozycji
●
long skip(long numBytes)
– przeskakuje
numBytes
bajtów z potoku wejściowego, zwraca
Wyjściowy Potok Bajtowy
Metody definiowane przez klasę
OutputStream
:
●
void close()
- zamyka potok
●
void flush()
– czyści bufor na wyjście
●
void write(int b) –
pisze pojedynczy bajt to
potoku wyjściowego
●
void write(byte buffer[])
- zapisuje całą
tablicę bajtów do potoku wyjściowego
●
void write(byte buffer[],int off,int num)
– zapisuje do potoku wyjściowego
num
bajtów z
Pliki
Klasa
File
nie operuje na zawartości plików (potoku), a
na samych plikach:
●dostęp
●ścieżka
●data i czas
●katalogi i podkatalogi
Konstruktory:
File(String directoryPath)File(String directoryPath, String filename) File(File dirObj, String filename)
Pliki: Przykład
import java.io.File; class FileDemo {
static void p(String s) { System.out.println(s); }
public static void main(String args[]) { File f1 = new File("C:/temp/COPYRIGHT"); p("File Name: " + f1.getName());
p("Path: " + f1.getPath());
p("Abs Path: " + f1.getAbsolutePath()); p("Parent: " + f1.getParent());
Pliki: Przykład
p(f1.canWrite() ? "is writeable" : "is not writeable");
p(f1.canRead() ? "is readable" : "is not readable");
p("is " + (f1.isDirectory() ? "" : "not" + " a directory"));
p(f1.isFile() ? "is normal file" : "might be a named pipe");
p(f1.isAbsolute() ? "is absolute" : "is not absolute");
p("File last modified: " + f1.lastModified()); p("File size: " + f1.length() + " Bytes");
} }
Katalog
Katalog jest plikiem z listą innych plików/katalogów.
Czy plik jest katalogiem?
boolean isDirectory()
Lista plików w katalogu:
Katalog: Przykład
import java.io.File; class DirList {
public static void main(String args[]) { String dirname = "C:/temp";
File f1 = new File(dirname); if (f1.isDirectory()) {
System.out.println(
"Directory of " + dirname); String s[] = f1.list();
Katalog: Przykład
for (int i=0; i < s.length; i++) {
File f = new File(dirname + "/" + s[i]); if (f.isDirectory()) { System.out.println(s[i] + " is a directory"); } else { System.out.println(s[i] + " is a file"); } } } else { System.out.println(dirname + " is not a directory"); } } }