Ch

ng 3

ươ

Các lu ng vào ra

1. Khái ni m v lu ng trong Java ề ồ

Khi l p b t kỳ ch ấ ậ ươ ữ ấ ộ ng trình và ngu n d li u cũng nh đích d li u là v n đ mà ng ươ ề ườ ậ ữ ệ ư ồ ữ ệ ươ ế ể ề ch ề quan tâm. Làm th nào đ ta có th truy n d li u cho m t ch hi u qu đ th c hi n đi u này: ng trình nào trong m t ngôn ng nào thì v n đ vào ra d li u gi a ữ ữ ệ ả i l p trình c n ph i ấ ữ ệ ầ ng trình Java. Có hai cách ộ ể ề ả ể ự ệ ệ

nào đó nh file ho c qua m t máy tính khác. ư ặ ộ ầ ự

• Thông qua m t tài nguyên tu n t ộ • Thông qua giao di n ng i máy. ườ ệ

ng này là xem xét cách truy n d li u cho m t ch ng trình thông ươ ữ ệ ề ộ ươ ụ ủ qua m t máy tính khác hay t p tin. M c đích c a ch ộ ậ

1.1. Khái ni m lu ng (stream) ồ ệ

Theo nghĩa đen lu ng là m t đ c. ộ ườ ồ ng ng n ố ướ

ắ V m t thu t ng chuyên ngành ta có th hi u “Các lu ng là các dãy d li u có s p ể ể ề ặ ữ ệ ữ ậ ồ th t ”. ứ ự

ươ ủ ể ồ ữ ệ ồ ể ể ự ậ ạ ng trình và ngu n d li u (Data Soure) ta có th phân lo i lu ng thành hai lo i: Lu ng xu t (output stream) và lu ng nh p (input stream). Đ tr c quan h n chúng ta xem hình v d Xét trên quan đi m c a ch ấ ạ đây: ồ ẽ ướ ồ ơ

InputStream

Program

Data Source

OutputStream

Hình 3.1

ngu n vào ch ế ươ ồ ng trình thì c n ph i s d ng lu ng ữ ệ ừ i, n u ta c n ghi d li u t ch ầ ấ ầ ữ ệ ừ ồ ươ ầ ng trình ra ngu n d li u thì ta c n ph i s ữ ệ ả ử ụ ầ ả ử ồ

Nh v y n u chúng ta c n l y d li u t ư ậ nh p. Ng ế ậ d ng lu ng xu t. ồ c l ượ ạ ấ ụ

, ch ng h n nh t ể ấ ằ ữ ệ ẳ ừ

ạ ấ liên k t m ng. Nh v y m t ch ươ ồ ạ ề ế ư ậ ẩ ấ ộ m t t p tin, t ư ừ ộ ệ ng trình có th truy xu t t ể các thi ấ ớ ế ị t b ề i nhii u

59

Ta có th th y r ng có r t nhi u lu ng d li xu t và nh p chu n, t ừ ậ ngu n d li u. ữ ệ ồ

InputStream

Console

Thi t bế ị

ng trình Ch ươ ng d ng ụ ứ

OutputStream

T p tin ệ

M ngạ

Hình 3.2

2. Lu ng xu t nh p chu n ấ

ng đ c s d ng đ hi n th k t qu đ u ra trên

ậ • System.out: Lu ng xu t chu n th ồ

ẩ ấ ườ ượ ể ể ử ụ ả ầ ị ế màn hình.

ng đ n t bàn phím và đ c s d ng đ hi n các • System.in: Lu ng nh p chu n th ồ ẩ ậ ườ ế ừ ượ ể ệ ử ụ ký t .ự

• System.err: Lu ng l i chu n. ồ ỗ ẩ

Các lu ng trên còn đ ồ ượ ồ ồ ậ c g i là các lu ng h th ng. M c dù các lu ng này r t có ích ặ ệ ố i quy t các v n đ vào ra quan tr ng khác. ấ ế ấ ọ khi l p trình nh ng chúng không đ m nh khi gi Trong các m c ti p theo ta s tìm hi u sâu m t s lu ng trong gói ề java.io ả ộ ố ồ ư ụ ế ẽ ọ ủ ạ ể

3. Lu nng nh phân

3.1. L p InputStream ớ

ng ừ ượ ứ ầ ừ ộ m t java.io, và L p tr u t ớ ụ ể ớ InputStream khai báo các ph ươ ầ ớ ơ ở ủ ng th c đ đ c d li u đ u vào t ữ ệ ậ ế ể ọ ồ ngu n c th . L p InputStream là l p c s c a h u h t các lu ng nh p trong gói nó h tr các ph ng th c sau: ứ ồ ỗ ợ ươ

Các ph ng th c: ươ ứ

• public InpuStream()

InputStream ch h tr constructor không tham s . ố ỉ ỗ ợ

• public abstract int read() throws IOException

ng th c read(). Ph ươ ủ ớ InputStream là ph ươ ứ

ế ị ả ề ờ ậ ng th c c b n c a l p ơ ả ứ ữ ệ ừ ồ ậ 0 đ n 255. Giá tr tr v là -1 khi k t thúc lu ng. Ph i khi m t byte d li u đ ớ ế ồ ữ ệ ủ ươ ượ ự ứ ọ ệ ậ ấ ậ ấ ệ ế ọ ng b i vì các l p con c n thay đ i đ ặ ng th c tr u t ứ ộ ớ ứ ầ Ph ọ ng th c này đ c ươ ứ m t byte d li u t lu ng nh p và tr v m t s ki u nguyên int có giá tr n m trong ộ ả ề ộ ố ể ị ằ kho ng t ng th c read() ch và ừ ả ế phong t a các đo n mã sau nó cho t c đ c. Vi c nh p và ạ ỏ ệ ộ ng trình c a ta th c hi n m t công vi c xu t di n ra v i t c đ ch m, vì v y n u ch ệ ộ ộ ươ ớ ố ễ t nh t là đ t các l nh nh p xu t vào m t tuy n đo n riêng c a khác quan tr ng thì t ủ ậ ạ ấ ố nó. Ph ổ ể ở ừ ượ ươ thích ích v i môi tr ng th c read() là ph ươ ng c th . ụ ể ườ ớ

• public int read(byte[] b) throws IOException

Ph ữ ệ ứ ọ ộ ụ ừ ộ ậ m t ngu n c a lu ng nh p ủ ồ ồ ươ và l u vào m ng b. ng th c này đ c m t dãy các byte d li u liên t c t ả ư

60

• public int read(byte[] b, int offs, int len) throws IOException

ng th c này đ c m t dãy các byte d li u và l u vào m ng b, v trí b t đ u l u d ắ ầ ư ữ ệ ư ứ ả ọ ộ ị ữ ươ Ph li u là offs và l u ệ ư len byte d li u ữ ệ

• public int available() throws IOException

Ph ng th c này cho bi t còn bao nhiêu byte d li u trong lu ng. ươ ứ ế ữ ệ ồ

• public long skip(long count) throws IOException

ng th c skip(long count) b qua long byte d li u ươ ữ ệ ứ ỏ • Ph public synchronized void mark(int readLimit)

ươ ng th c này đ ứ ượ ử ụ ể c s d ng đ dánh d u v trí hi n th i trong lu ng ị ệ ấ ờ ồ • Ph public void reset() throws IOException

i v trí lu ng là v trí đánh d u l n g n đây nh t. ấ ầ ầ ấ ồ ị ươ ứ ị • ng th c này xác đ nh l Ph ạ ị public boolean markSupported()

ng th c này tr v giá tr true n u lu ng này h tr đánh d u và false n u nó ỗ ợ ế ế ấ ồ ị ươ Ph ả ề ứ không h tr đánh d u. ấ ỗ ợ

• public void close() throws IOException

ệ ầ ớ ồ ạ ệ ề i lu ng đó. Đi u này cho phép h đi u ề ồ ộ i phóng các tài nguyên g n v i lu ng. ắ ớ ồ ả 3.2. L p OutputStream Khi đã làm vi c xong v i m t lu ng, ta c n đóng l hành gi ớ

ừ ượ OutputStream khai báo các ph ươ ng th c đ ghi d li u ra lu ng. Chúng ữ ệ ứ ể ồ ng ng th c sau đây: L p tr u t ớ bao g m các ph ồ ươ ứ

• public OuputStream()

Ph ng th c ươ ứ OutputStream h tr constructor không tham s ỗ ợ ố

• public abstract void write(int b)throws IOException

0 đ n 255. N u ta ứ ế ộ Ph ấ truy n vào m t s có giá tr l n h n 255 ho c nh h n 0, nó s th c hi n phép ế tính ng th c này ghi m t byte không d u có giá tr trong kho ng t ừ ả ẽ ự ị ỏ ơ ươ ề ộ ố ị ớ ệ ặ ơ

b =b mod 256 tr c khi ghi giá tr vào lu ng. ướ ồ ị

• public void write(byte[] b)throws IOException

Ph ng th c này ghi d li u t lu ng vào toàn b m ng b. ươ ữ ệ ừ ồ ộ ả ứ

• public void write(byte[] b, int off, int len) throws IOException

ng th c này ch ghi m t đo n con c a m ng d li u b t đ u t ắ ầ ừ ị ữ ệ ế v trí offs và ti p ủ ạ ả ộ ứ ỉ i khi ghi h t Ph ươ t c cho t ụ ớ ế len byte.

• public void close()

ng th c này đóng m t lu ng. Ph ng th c này đ c g i đ gi i phóng các tài ộ ồ ươ ứ ượ ọ ể ả ươ Ph ứ nguyên g n v i lu ng. ắ ớ ồ

• public void flush()

61

ồ các lu ng tr u t ồ ế ừ ừ ừ ng ượ ể ữ ệ ể ồ ậ ỗ ẳ ấ ậ InputStream và Các lu ng xu t nh p khác đ c th a k t ượ ấ OutputStream. Đ i v i m i ki u d li u và ngu n d li u chúng ta có th có các ki u lu ng ồ ể ữ ệ ố ớ ạ DataInputStream, DataOutputStream, FileInputStream, xu t và nh p riêng, ch ng h n FileOutputStream,… Sau đây chúng ta s l n l t xem xét t ng ki u lu ng c th . ụ ể ể ẽ ầ ượ ừ ồ

3.3. Các lu ng xu t nh p m ng byte ấ ồ ậ ả

ByteArrayInputStream

ByteArrayOutputStream

ể ự ể ượ ự ễ ả ộ bi u di n d li u có th đ c đ ặ c ho c gi ặ ủ ể ọ ậ ườ ủ ồ ồ ồ ữ ệ i mã d li u, ữ ệ i ta xem các m ng byte nh là ngu n c a các lu ng nh p ho c đích c a các lu ng xu t. ấ ồ Đ xây d ng m t xâu ký t ư ả ả ng Các lu ng byte cung c p các kh năng này. ấ

Hình 3.3

3.3.1. Lu ng nh p m ng byte ồ ậ ả

L p ByteArrayInputStream s d ng m t m ng byte nh là m t ngu n d li u đ u vào. ả ử ụ ữ ệ ư ầ ớ ộ ộ ồ Nó có hai constructor:

• public ByteArrayInputStream(byte[] buf)

T o ra m t đ i t ng ByteArrayInputStream t ố ượ ạ ừ ộ ả ầ đ ả lu ng. ượ ử ụ c s d ng m t cách tr c ti p. Khi k t thúc buf nghĩa là k t thúc nh p t ế ự ế ế m t m ng xác đ nh. M ng đ u vào ị ậ ừ ồ ộ ộ

• public ByteArrayInputStream(byte[] buf, int offset, int length)

ng ByteArrayInputStream t ừ ộ ỉ ử ụ ị ph n c a m ng buf t buf[offset] đ n buff[offset+length-1] ho c k t thúc m ng. T o ra m t đ i t ộ ố ượ ạ ừ ủ ầ ả ế m t m ng xác đ nh, ch s d ng m t ộ ả ả ặ ế

ồ ộ m t vùng đ m trong b nh đ ớ ượ ạ c bi u ể ộ ồ ng th c m i nào, nó n p ch ng ệ ứ ươ ả ớ ộ ng th c read(), skip(), available(), và reset() c a l p cha InputStream. ByteArrayInputStream t o ra m t lu ng nh p t ậ ừ ộ ạ di n b ng m t m ng byte. L p này không h tr b t kỳ ph ằ ỗ ợ ấ ớ ễ các ph ủ ớ ươ ứ

Ví d :ụ

T o m t m ng g m 100 byte r i g n vào m ng này m t lu ng ByteArrayInputStream ồ ắ ả ả ồ ộ ồ ộ ạ đ l y d li u ra. ữ ệ ể ấ

import java.io.*;

public class LuongNhapMang

{

public static void main(String[] args)

{

byte[] b = new byte[100];

for(byte i=0;i

62

try{

InputStream is = new ByteArrayInputStream(b);

for(byte i=0;i

System.out.print(is.read()+" ");

}

catch(IOException e)

{

System.err.println(e);

}

}

}

K t qu th c hi n ch ng trình ả ự ệ ế ươ

C:\MyJava\Baitap>java LuongNhapMang

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99

ng th c read(), m t byte d li u không còn trong ươ ữ ệ ứ ộ ằ ồ lu ng, nh ng v n t n t Chú ý: M i l n đ c lu ng b ng ph ỗ ầ ọ i trong m ng. ẫ ồ ạ ư ả ồ

3.3.1. Lu ng nh p m ng byte ồ ậ ả

ấ ả ạ ộ ồ ộ các kh năng b sung. ByteArrayOutputStream t o ra m t lu ng xu t trên m t m ng byte. Nó cũng cung c p ấ ả ổ

Các constructor:

• public ByteArrayOutputStream()

T o ra m t đ i t ng ByteArrayOutputStream v i kích th c m c đ nh ộ ố ượ ạ ớ ướ ặ ị

• public ByteArrayOutputStream(int size)

T o ra m t đ i t ng ByteArrayOutputStream v i kích th c xác đ nh ban đ u. ộ ố ượ ạ ớ ướ ầ ị

Các ph ng th c m i c a l p ByteArrayOutputStream: ươ ớ ủ ớ ứ

• public synchronized byte[] toByteArray():

Ph ữ ệ ư ủ ộ ồ và có th s a đ i d li u trong m ng này mà không c n thay đ i các byte c a lu ng xu t. ng th c này tr v m t b n sao d li u c a lu ng và l u d li u vào m t m ng ả ầ ả ề ộ ả ả ứ ổ ữ ệ ươ ể ử ữ ệ ủ ấ ổ ồ

• public size()

Tr v kích th c hi n th i c a vùng đ m ả ề ướ ờ ủ ệ ệ

• public String toString(int hiByte)

T o m t đ i t ng String m i t n i dung c a lu ng xu t m ng byte ộ ố ượ ạ ớ ừ ộ ủ ấ ả ồ

• public String toString()

Ph ng th c chuy n đ i m t lu ng byte thành m t đ i t ng String ươ ộ ố ượ ứ ể ộ ổ ồ

Ví d :ụ

ế ạ ậ ấ ồ 0 đ n 99. Đ d li u t ng trình t o l p m t lu ng xu t m ng ( ộ t ầ ử ừ ả ả ổ ữ ệ ừ ồ ByteArrayOutputStream) 100 byte. Ghi lu ng xu t m ng vào m ng b. In ả ế ấ ả m ng b ra màn hình. Vi t ch ươ vào lu ng xu t m ng 100 ph n t ấ ồ d li u t ữ ệ ừ ả

63

import java.io.*;

class LuongXuatMang

{

public static void main(String[] args)

{

try{

//Tao mot luong xuat mang 100 byte

ByteArrayOutputStream os = new ByteArrayOutputStream(100);

//Ghi du lieu vao luong

for(byte i=0;i<100;i++) os.write(i);

//Doc du lieu tu luong vao mang

byte[] b = os.toByteArray();

for(byte i=0;i<100;i++) System.out.print(b[i]+" ");

os.close();

}

catch(IOException e)

{

System.err.println(e);

}

}

}

K t qu th c hi n ch ng trình: ả ự ệ ế ươ

C:\MyJava\Baitap>java LuongXuatMang

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99

3.4. Lu ng xu t nh p t p tin ấ ậ ậ ồ

Ph n l n vi c nh p và xu t d li u trong các ng d ng là đ c và ghi d li u t ầ ớ ấ ữ ệ ụ ứ ậ ữ ệ ừ ậ ệ ệ ữ ệ ọ ệ ự ệ ấ ệ các t p tin và ghi vào d li u vào t p tin. Hai lu ng trong java.io th c hi n vi c xu t nh p t p tin là ệ FileInputStream và FileOutputStream. M i ki u lu ng có ba constructor. ồ ỗ ể ồ

ng String làm tên c a t p tin. ộ ậ ộ ố ượ ủ ệ

ng File đ tham chi u đ n t p tin. ậ ộ ộ ố ượ ế ệ ể ế

• M t constructor nh n m t đ i t • M t constructor nh n m t đ i t • M t constructor nh n đ i t ng ố ượ ậ ộ FileDescriptor làm tham s .ố

FileDescriptor bi u di n m t giá tr ph thu c vào h th ng mô t m t t p đang m . ệ ố ụ ể ễ ộ ộ ị ả ộ ệ ở

64

ng trình Java là n i tiêu th ồ ấ ươ ữ ệ ố ớ ậ ơ Đ i v i lu ng xu t nh p t p tin ta hình dung nh sau: ch ữ ệ ể ụ t p tin vào b nh ta s d ng lu ng ồ ộ ớ ấ ậ b nh vào t p tin ta s d ng lu ng xu t t p ử ụ ơ ử ụ ồ ữ ệ ừ ộ ậ ậ ậ ư ậ ậ d li u, t p tin là n i cung c p d li u. Đ đ c d li u t ữ ệ ừ ậ ể ọ ấ FileInputStream. Đ ghi d li u t nh p t p tin ớ tin FileOutputStream.

FileInputStream

FILE

FileOutputStream

Hình 4.5

Ví dụ

import java.io.*;

public class FileIOExam

{

public static void main(String[] args)

{

//Tao mot file de ghi

try{

OutputStream os = new FileOutputStream(args[0]);

String s = "Thu nghiem voi luong xuat nhap tap tin";

for(int i=0;i

os.close();

//Mo de doc

InputStream is = new FileInputStream(args[0]);

int len = is.available();

System.out.println("Luong nhap co "+len+ " bytes");

byte b[] = new byte[len];

int sobyte = is.read(b,0,len);

System.out.println(sobyte+ " la so bytes da doc");

System.out.println(new String(b));

is.close();

}

catch(IOException e)

{

System.err.println(e);

}

65

}

}

K t qu th c hi n ch ng trình ả ự ệ ế ươ

C:\MyJava\Baitap>java FileIOExam abc.txt

Luong nhap co 38 bytes

38 la so bytes da doc

Thu nghiem voi luong xuat nhap tap tin

3.5. Truy nh p t p ng u nhiên ậ ệ ẫ

RandomAccessFile cho phép ta truy nh p tr c ti p vào các t p, nghĩa là có th đ c, ghi ự ế ể ọ ệ ậ các byte b t kỳ v trí nào đó trong t p. ở ấ ệ ị

Các ph ươ ứ ạ ậ ệ ẫ ồ

ng th c t o lu ng truy nh p t p ng u nhiên • RandomAccessFile(String name, String mode) throws IOException • RandomAccessFile(File file, String mode) throws IOException

c xác đ nh b i tên ho c đ i t ng File. T p đ ệ ượ ố ượ ặ ở ị

Tham s mode cho phép xác đ nh m file đ đ c hay ghi. ể ọ ố ở ị

-“r”: Dùng đ đ c. ể ọ

-“rw”: Dùng đ ghi. ể

Các ph ươ ng th c khác ứ

• long getFilePointer() throws IOException : Tr v v trí c a con tr t p. ả ề ị ỏ ệ ủ

• long length() throws IOException: cho bi ế ố t s byte hay đ dài c a t p. ộ ủ ệ

• ỏ ệ ể ị ể ừ ầ đ u void seek(long offset) throws IOException: Chuy n con tr t p đi offset v trí k t t p.ệ

• void close() throws IOException: Khi không c n truy nh p t p n a thì đóng l ậ ệ ữ ầ i. ạ

Ví d :ụ

import java.io.*;

public class RandomAccessDemo

{

static String filename="dayso.dat";

final static int INT_SIZE=4;

//Tao file de ghi

public void createFile() throws IOException

{

File datFile = new File(filename);

RandomAccessFile out_file = new RandomAccessFile(datFile,"rw");

for(int i=0;i<10;i++)out_file.writeInt(i*i);

out_file.close();

}

//Mo file de doc

66

public void readFile() throws IOException

{

File datFile = new File(filename);

RandomAccessFile inp_file= new RandomAccessFile(datFile,"r");

System.out.println("Cac so doc tu file:");

long len = inp_file.length();

for(int i=INT_SIZE;i

{

inp_file.seek(i);

System.out.println(inp_file.readInt());

}

inp_file.close();

}

//Mo file de ghi

public void extendFile() throws IOException

{

RandomAccessFile out_file = new RandomAccessFile(filename,"rw");

for(int i=10;i<20;i++) out_file.writeInt(i*i);

out_file.close();

}

public static void main(String[] args)

{

try{

RandomAccessDemo rnd = new RandomAccessDemo();

rnd.createFile();

rnd.readFile();

rnd.extendFile();

rnd.readFile();

}

catch(IOException e)

{

System.err.println(e);

}

}

67

}

3.5. Lu ng PrintStream ồ

Lu ng PrintStream đ c s d ng m i khi c n s d ng các ph ượ ử ụ ử ụ ươ ứ ỗ ồ ươ ậ ớ ớ ng th c print và println ể ử ụ ng trình. L p PrintStream là l p con c a l p InputStream, vì v y ta có th s d ng ữ ệ ng th c print và println cho các ki u d li u ể ể ọ ầ ủ ớ ươ ứ ấ trong ch lu ng này đ l c các byte. Nó cung c p các ph ồ sau:

char int float Object boolean

char[ ] long double String

Ngoài ra ph ng th c println không tham s đ c s d ng đ k t thúc m t dòng. ươ ố ượ ử ụ ể ế ứ ộ

ỗ ợ ứ ậ ồ ộ ố Constructor th hai có thêm tham s đi u khi n vi c đ y d li u ra kh i lu ng. PrintStream h tr hai constuctor. Constructor th nh t nh n tham s là m t lu ng. ệ ấ ữ ệ ố ề ứ ể ẩ ỏ ồ

ư ể ồ ộ ố ậ ụ ể ừ ữ ự ộ Ngoài ra còn m t s ki u lu ng xu t và nh p khác nh DataInputStream, ấ ọ DataOutputStream,…tùy thu c vào t ng tình hu ng c th mà chúng ta có nh ng l a ch n ố cho phù h p.ợ

4. Lu ng ký t ồ

ồ ự ứ ệ ấ ộ hóa. Trong m t s tr ử . Các lu ng này s cung c p m t cách th c đ qu n lý vi c vào ra v i các ký t ồ ự ớ ớ ng h p làm vi c v i ộ ố ườ ả ố ế ụ ệ ợ Lu ng ký t d ng t p ký t ậ các lu ng ký t ồ ể Unicode và vì th có th qu c t ể ế hi u qu h n lu ng byte. ồ ự ự ệ ả ơ

InputStream

InputStreamReader

ẩ ự ớ ướ c d n xu t t t c các lu ng đ ồ ệ Các lu ng ký t ồ ồ ọ chu n vay m n t ồ ề ấ ả ồ ượ ấ ừ ồ r t nhi u các l p lu ng h ẫ ồ ữ ớ ố ự ự ể ớ ổ ề ị ầ . Hai l p này k t h p các hàm chuy n đ i các ký t ộ cho d li u Unicode đ Unicode và t ồ ữ ệ ự ự ồ thành các byte và ng ế ợ c xác đ nh. Đi u này cho phép m t ngu n d li u ASCII đ ữ ệ ng t ượ ộ ượ ộ ộ ệ ặ ẩ ẩ ồ ng byte, bao g m ượ ừ ấ các l p cha lu ng l c, lu ng đ m, và các lu ng t p tin, và t ớ ệ Reader và Writer. Ngoài ra, có hai l p đóng vai trò c u n i gi a các lu ng byte và các lu ng ồ ộ c l i theo m t ký t ượ ạ ổ c chuy n đ i ki u mã hóa đã đ ể ể ượ d dàng thành m t lu ng ký t c ghi m t cách ươ ễ ộ d dàng vào m t t p tin theo chu n mã hóa c c b , cho dù nó là chu n 8-bit, UTF-8, ho c 16 ụ ễ bit.

16-bit “Hi!”

72 105 33 8-bit

OutputStreamWriter

OutputStream

255 254 0 105 0 33 0

Hình 4.6

“Hi!” 16-bit

4.1. S t ng ng gi a lu ng byte và lu ng ký t ự ươ ứ ữ ồ ự Hình 4.7 ồ

B ng d ng ng gi a lu ng byte và lu ng ký t ả ướ i đây ch ra s t ỉ ự ươ ứ ữ ồ ồ ự

Lu ng byte Lu ng ký t ồ ồ ự

OuputStream Writer

InputStream Reader

FileOutputStream FileWriter

68

FileInputStream FileReader

ByteArrayInputStream CharArrayReader

ByteArrayOutputStream CharArrayWriter

StringWriter -

StringBufferedInputStream StringReader

PipedOuputStream PipedWriter

PipedInputStream PipedReader

FilterOutputStream FilterWriter

FilterInputStream FilterReader

BufferedOuputStream BufferedWriter

BufferedInputStream BufferedReader

PushbackInputStream PushbackReader

LineNumberInputStream LineNumberReader

PrintStream PrintWriter

DataOutputStream -

DataInputStream -

ObjectInputStream -

ObjectOuputStream -

SequenceInputStream -

- OuputStreamWriter

- OutputStreamReader

B ng 3.1 ả

4.2. Mã hóa ký tự

và m t lu ng byte, c n thi ố ự ộ ộ ồ ạ ượ Khi t o c u n i gi a m t lu ng ký t ữ ở ầ ử ụ ồ ồ ầ đ ự ượ c đ c t đ c s d ng b i các lu ng byte; nghĩa là, các ký t ượ ế ể ặ ả ở t ph i xác đ nh cách ị ả c bi u di n b i t ng byte mã hóa đ ễ ở ừ b i m t xâu ký t ho c t ng nhóm các byte. Tên c a cách mã hóa các byte đ ự ượ c ặ ừ ộ . truy n cho constructor t o c u n i OuputStreamReader và InputStreamReader ầ ề ủ ố ạ

Char ! ! Bytes 33 90

69

Mã hóa US-ASCII IBM-EBCDIC ISO Latin ISO Latin 2 UTF-8

B ng 3.2 ả

c a các lu ng byte t ng đ ươ ng th c h ứ ươ ươ ướ ồ Các ph ư ng ký t ặ ng v i latin 1, còn đ ớ ứ ng là phân bi ươ t ch hoa và ch th ự ườ ể ầ ượ c ng ng v i 256 ữ ữ ớ ự ủ t đ n nh là ISO Latin 1 ho c ISO 8859-1; nghĩa là cách mã hóa 8-bit t bi ế ế ký t Unicode đ u tiên. Các tên ki u mã hóa ký t ệ ự ng. th ườ

4.3 L p Writer ớ

. Nó cung c p các ph ng th c t Writer là l p cha c a t ớ ự ấ ấ ươ ứ ươ ng ủ ấ ả nh lu ng OuputStream, nh ng ch y u là ghi các ký t . t c các lu ng xu t ký t ồ ủ ế ư ư ồ ự t ự

4.3.1. Các constructor ấ ượ ng c a l p Writer nh ng ta có th t o ra các đ i t c cung c p b i l p này. Các constructor này là protected. Ta ộ ớ ng thu c l p ể ạ ủ ớ ở ớ ư ố ượ Có hai constructor đ ố ượ không th t o các đ i t ể ạ con c a l p này. ủ ớ

• protected Writer()

• protected Writer(Object obj)

4.3.1. Các ph ươ ứ ng th c đ ghi các ký t , t ng th c L p Writer cung c p các ph ấ ớ ươ ứ ể ự ừ ộ ầ m t m ng, ho c m t ph n ặ ả ộ . c a xâu ký t ủ ự

• void write(int c) throws IOException

Ph ng th c này ghi ký t c vào kênh truy n tin đ ươ ứ ự ề ượ c bi u di n b i lu ng này. ở ễ ể ồ

• void write(char cbuff[]) throws IOException

Ph ng th c này ghi m ng ký t vào lu ng ươ ứ ả ự ồ

• abstract void write(char cbuff[], int off, int len) throws IOException

Ph ng th c này ghi len ký t ươ ắ ầ ừ ị ớ ồ ừ ượ m ng cbuff ra lu ng g n v i m ng, b t đ u t ắ ớ v trí ả c cài đ t b i m t l p con g n v i kênh ộ ớ ả ượ ắ ặ ở ng b i vì nó ph i đ off. Đây là ph truy n tin th c s , nh t p tin ho c m t lu ng khác. ồ ặ ươ ự ự ề ứ ng th c tr u t ứ ư ệ t ự ừ ả ở ộ

• void write(String str) throws IOException.

Ph ng th c này ghi m t xâu ký t str ra lu ng. ươ ứ ộ ự ồ

4.4. L p Reader ớ

. Nó cung c p các ph ự ấ ươ ứ ng th c . ng t Reader là l p cha c a t ớ ự t c các lu ng nh p ký t ồ nh lu ng InputStream, nh ng ch y u ph c v cho vi c đ c các ký t ủ ế ủ ấ ả ư ậ ụ ụ ư ồ ự ệ ọ t ươ

• protetected Reader()

• protected Reader(Object lock)

ng th c ng th c c a l p Reader gi ng nh các ph ng th c c a l p InputStream ủ ớ ứ ứ ư ố ủ ớ ứ ươ ươ ng th c available() đ c thay th b i ph ng th c ready(). 4.4.1. Các ph Các ph ươ ngo i tr ph ạ ừ ế ở ươ ượ ứ ươ ứ

• int read() throws IOException

kênh truy n tin đ c bi u di n b i lu ng này và tr ề ượ ể ễ ở ồ ả ứ ộ Ph ự ng th c này đ c m t ký t ươ ọ , ho c giá tr -1 n u k t thúc lu ng. ế ặ t ự ừ ồ ế ị v ký t ề

int read(char cbuff[]) throws IOException

Ph ng th c này đ c các ký t ươ ứ ọ ự vào m ng cbuff ả

4.5. L p OutputStreamWriter ớ

70

ng ký t ướ ấ ố c chuy n thành các byte t L p này cung c p m t c u n i Writer h ớ c ghi vào l p Writer đ ớ ộ ầ ượ v i m t lu ng OutputStream. Các ký ự ớ ượ ng ng v i m t ki u mã hóa đ c ộ ươ ồ ớ ộ ứ ể ể t đ ự ượ

c ghi vào lu ng OutputStream g n v i nó. L p này ị ượ ồ ắ ớ ớ xác đ nh trong constructor và sau đó đ cung c p kh năng đ m d li u cho các byte đ ghi vào lu ng. ữ ệ ệ ể ấ ả ồ

Các constructor • public OutputStreamWriter(OutputStream out)

• public OutputStreamWriter(OutputStream out, String encoding)

• String getEncoding()

ng th c này tr v tên cách mã hóa các byte đ c s d ng đ chuy n đ i các ký Ph ả ề ượ ử ụ ể ể ổ ứ ươ thành các byte. t ự

4.6. L p InputStreamReader ớ

ễ ộ ầ ự ủ ướ ể lu ng nh p và đ ố h ộ c chuy n thành các ký t L p này ớ c đ c t ượ bi u di n m t c u n i ậ c a m t lu ng nh p InputStream. Các ậ ng ng v i ki u mã hóa ứ ng ký t ể ồ t ự ươ ượ ể ớ ọ ừ ồ c xác đ nh trong constructor. byte đ đ ượ ị

• InputStreamReader(InputStream in)

• InputStreamReader(InputStream in, String enc)

• String getEncoding()

Ph ả ề ứ ượ c s d ng b i lu ng này đ ở ử ụ ồ ể các byte thành các ký t ươ chuy n đ i t ổ ừ ể ng th c này tr v tên c a cách mã hóa byte đ ủ . ự

Ví d : Chuy n đ i cách mã hóa ụ ể ổ

import java.io.*;

public class Convert

{

public static void main(String[] args) throws Exception

{

if(args.length!=4)throw new IllegalArgumentException("Convert ");

FileInputStream fis=new FileInputStream(args[1]);

FileOutputStream fos=new FileOutputStream(args[3]);

InputStreamReader isr=new InputStreamReader(fis,args[0]);

OutputStreamWriter osw=new OutputStreamWriter (fos,args[2]);

char b[]=new char[16];

int num;

while((num=isr.read(b))>-1)osw.write(b,0,num);

osw.close();

isr.close();

}

}

71

4.7. L p FileWriter ấ ồ ộ ự ể ằ đ ghi các t p tin văn b n b ng ệ ả cách s d ng mã hóa m c đ nh. ớ L p Writer này cung c p m t interface lu ng ký t ớ ử ụ ặ ị

Đ xác đ nh cách mã hóa đ ể ị ượ ồ c s d ng đ mã hóa m t t p tin, ta s d ng m t lu ng ử ụ ử ụ ộ ệ ể ộ OuputStreamWriter g n v i lu ng FileOutputStream. ớ ắ ồ

ng v i vi c t o ra m t đ i t Các constructor T o m t đ i t ố ượ ộ ạ ươ ộ ố ượ ng ng FileOuputStream ng FileWriter hoàn toàn t OuputStreamWriter s d ng cách mã hóa m c đ nh và g n nó v i đ i t ị ng đ ươ ắ ớ ệ ạ ớ ố ượ ử ụ ặ

• FileWriter(String filename)throws IOException.

ộ ố ượ ộ ệ ể ng FileWriter đ ghi thông tin vào m t t p tin c th m c đ nh. B t kỳ t p nào có cùng tên s b ụ ể ẽ ị ự ặ ệ ấ ị Constructor này t o ra m t đ i t ạ là fileName, s d ng cách mã hóa ký t ử ụ xóa.

• FileWriter(File file)throws IOException.

ng ụ ể FileWriter đ ghi thông tin vào m t t p tin c th , ể ạ ộ ệ m c đ nh. B t kỳ t p nào có cùng tên s b xóa. Constructor này t o ra m t đ i t ộ ố ượ s d ng cách mã hóa ký t ị ự ặ ử ụ ẽ ị ệ ấ

• FileWriter(String fileName, boolean append) throws IOException.

ộ ệ ể ạ ứ ế ị ụ ể ng FileWriter đ ghi thông tin vào m t t p tin c th , Constructor này t o ra m t đ i t ộ ố ượ m c đ nh. Bi n boolean append xác đ nh cách th c ghi vào s d ng cách mã hóa ký t ị ự ặ ử ụ t p tin: ghi m i hay b sung thêm n i d ng vào t p hi n có. ớ ệ ộ ụ ệ ệ ổ

ươ ứ Các ph ng th c L p FileWriter cung c p t t c các ph ươ ủ ớ vào m t lu ng FileWriter t o ra các ký t ộ ấ ấ ả ạ ng dùng c a l p Writer. Vi c ghi ệ ứ ng ng ươ ể ớ ự các ký t ồ v i cách mã hóa c th và các byte này đ ụ ể ớ ượ ng th c th ứ đ ự ượ ệ ườ c chuy n thành các byte t ồ c ghi vào t p tin g n v i lu ng này. ắ ớ

IOException s đ ạ ệ ẽ ượ ư ở ế c đ a ra b i các ph Ngo i l i trong quá trình ghi t p tin, ho c không t o ra đ ệ ặ ạ ươ ượ ặ ng th c c a l p FileWriter n u g p ủ ớ ứ ng FileWriter thì nó đ a ra c đ i t ố ượ ư m t l ộ ỗ ngo i l IOException. ạ ệ

4.8. L p FileReader ớ

ớ ả ằ ồ L p Reader này cung c p m t interface lu ng ký t ấ ự ặ ệ ệ ộ ị ả ớ Unicode mà không c n quan tâm đ n cách th c mã hóa ký t . đ đ c các t p văn b n b ng cách ự ể ọ m c đ nh. L p này cho phép ta đ c các t p tin văn b n nh đ c ư ọ ọ ứ s d ng cách mã hóa ký t ử ụ các lu ng ký t ồ ự ự ế ầ

c s d ng đ gi ể ử ụ ị ộ ố i mã m t t p tin, ta s d ng m t đ i ử ụ ộ ệ Đ xác đ nh cách mã hóa đ ng InputStreamReader g n v i đ it t ể ả ng InputStreamReader. ượ ớ ố ượ ắ t ượ

Vi c t o ra m t đ i t ng FileReader hoàn toàn t ng đ ộ ố ượ ệ ạ ươ ươ ộ ố ng v i vi c t o ra m t đ i ệ ạ ớ t ượ ắ ớ ồ

ng InputStreamReader và sau đó g n nó v i lu ng FileInputStream. • FileReader(String fileName)throws FileNotFoundException.

ộ ố ượ ạ ụ ể ng FileReader đ c n i dung c a m t t p tin c th , ọ ộ đ Constructor này t o ra m t đ i t ằ ở ượ ị ử ụ ố ủ ặ ộ ệ ị

c xác đ nh b i tham s fileName b ng cách s d ng cách mã hóa m c đ nh. • FileReader(File file)throws FileNotFoundException.

Constructor này t o m t đ i t ng FileReader đ đ c n i dung c a m t t p tin c th ộ ố ượ ạ ộ ệ ụ ể ủ đ c xác đ nh b i t p tin file s d ng cách th c mã hóa m c đ nh. ượ ử ụ ở ệ ứ ị ể ọ ặ ộ ị

ng th c ươ Các ph ứ L p FileReader cung c p các ph ng th c c a l p Reader. Đ c các ký t t ấ ớ ươ ủ ớ ứ ọ ự ừ ộ ố m t đ i ng FileReader. t ượ

Ví d minh h a ụ ọ

Ví d d i đây minh h a cách s d ng các lu ng FileWriter và FileReader. ụ ướ ử ụ ọ ồ

import java.io.*;

public class TepKyTu

72

{

public static void main(String[] args) throws IOException

{

FileReader fr=new FileReader(FileDescriptor.in);

FileWriter fw=new FileWriter(FileDescriptor.out);

char[] b=new char[256];

int num;

while((num=fr.read(b))>-1)

{

String upper=new String(b,0,num).toUpperCase();

fw.write(upper);

fw.flush();

}

}

}

K t qu th c hi n ch ng trình là ả ự ế ệ ươ

ụ ắ ắ ớ ồ ớ ắ ớ ồ ớ C:\>java TepKyTu Xin chao cac ban! Day la chuong trinh minh hoa FileReader va FileWriter XIN CHAO CAC BAN! DAY LA CHUONG TRINH MINH HOA FILEREADER VA FILEWRITER Trong ví d này, ta g n FileReader v i FileDescriptor.in, lu ng này g n v i bàn phím. ữ t hoa bàn phím vào vùng đ m b[], chuy n đ i các ký t này thành ch vi ặ ữ ế ắ ổ ượ ự ệ ể Ta cũng g n FileWriter v i FileDescriptor.out, lu ng này g n v i màn hình. Trong vòng l p, d li u đ ệ sau đó ghi d li u ra lu ng xu t. c đ c t ọ ừ ữ ệ ấ ồ

5. Lu ng đ m

ồ ồ ọ ố ị ư ế ự ề ẩ ệ ộ ẩ ườ ậ ượ ữ ạ ộ Unicode-đi u này hoàn toàn ph ổ ế ồ ữ ệ ấ ắ ể ặ i gi a các byte và các khuôn d ng d li u khác. Các lu ng InputStream và OuptutStream là các lu ng thô. Chúng đ c và ghi các byte theo t ng nhóm. Vi c xác đ nh các byte này có ý nghĩa nh th nào-chúng là s nguyên hay ừ các s d u ph y đ ng theo chu n IEEE 754 hay là các ký t ụ ố ấ i l p trình. Tuy nhiên, có nh ng khuôn d ng d li u r t ph bi n đã đ c cài thu c vào ng đ t trong các th vi n l p. Java cung c p m t s l p l c đ ta g n các lu ng d li u thô v i ớ ư ệ ớ ữ ệ ộ ố ớ ọ chúng nh m m c đích chuy n đ i qua l ụ ấ ạ ữ ữ ệ ể ạ ằ ổ

ồ ế ố ạ Các lu ng l c đ ượ ồ ồ ế ố ớ ọ ồ ớ ồ Các lu ng l c cũng có hai lo i là:lu ng đ c (reader) và lu ng ghi (writer). K t n i các ồ ọ ọ lu ng l c v i nhau. ủ c k t n i v i các lu ng thông qua các constructor c a ọ chúng.

Ví dụ

FileInputStream fis=new FileInputStream(“data.txt”);

BufferedInputStream bis=new BufferedInputStream(fis);

c tiên, ta th y m t đ i t ấ ượ ạ ớ BufferedInputStream bis v i tham s ng ộ ố ượ data.txt. Sau đó, ta t o ti p đ i t ạ FileInputStream đ ố ượ ế ng ừ ờ ộ ầ ể ở Tr ướ m t tên t p tin ệ đ u vào c a constructor ủ ng th c các ph fis và bis. ng c t o ra v i tham s đ u vào là ố ầ ố ớ BufferedInputStream là fis. T th i đi m này tr đi, ta có th s d ng ể ử ụ ứ read() đ đ c c đ i t ể ọ ả ố ượ ươ

Ta cũng có th xây d ng tr c ti p m t lu ng bên trong m t lu ng khác. ự ế ự ể ồ ộ ồ ộ

73

DataOuputStream dos =new DataOutputStream(new BufferedOutputStream(new FileOutputStream(“data.txt”)));

Các lu ng đ m ồ ệ

ữ ữ ệ ượ ư ớ i khi t c d li u ra lu ng xu t đúng L p ớ BufferedOutputStream l u tr d li u đ ệ ặ ầ ồ c ghi vào trong m t vùng đ m cho t ộ ấ ữ ấ ả ữ ệ ệ ồ vùng đ m đ y ho c là lu ng b ị flush(). Sau đó nó ghi d t m t l n. Đi u này làm tăng t c đ trao đ i d li u. ộ ổ ữ ệ ộ ầ ề ố

ử ụ ộ ả ượ ượ ướ ươ ứ ọ L p ớ BufferedInputStream cũng có m t m ng byte đ c g i, tr ọ ự ự ệ c s d ng đ làm vùng đ m. Khi ệ ể ng th c đ c lu ng read() đ c yêu c tiên nó nh n d li u đ ượ ậ ồ ữ ệ ngu n. Lúc vùng đ m. Ch khi vùng đ m h t d li u th c s nó m i đ c d li u t ế ữ ệ ệ ồ ữ ệ ừ ầ ngu n vào vùng đ m n u có th , cho dù d li u có c n ồ ữ ệ ừ ớ ọ ể ữ ệ ỉ ề ệ ế ọ m t trong các ph ộ c u t ầ ừ này, nó đ c càng nhi u d li u t ngay t c kh c hay không. ắ ứ

• public BufferedInputStream(InputStream in)

• public BufferedInputStream(InputStream in, int bufferSize)

• public BufferedOutputStream(OutputSream out)

• public BufferedOutputStream(OutputStream out, int bufferSize)

ươ ấ ng th c t BufferedInputStream không khai báo các b t kỳ ph ứ ừ ng th c m i nào c a riêng nó. Nó ứ ớ ở ạ InputStream. Nó th c s h tr vi c đánh d u và kh i t o ự ỗ ợ ệ ủ ấ ươ ự ch n p ch ng các ph ồ l ạ ỉ ạ i lu ng. ồ

• public int read() throws IOException

• public int read(byte[] input,

6. Lu ng vào ra m i – New Input Output

B t đ u t phiên b n Java 1.4 Sun đã b sung thêm m t cách m I đ qu n lý các thao ắ ầ ừ ớ ể ả ả ộ ổ tác vào ra.

6.1. Căn b n v NIO ả ề

H th ng vào ra m I đ ố ớ ệ ự ự ụ ể ệ ộ ộ ơ ả ễ ệ ố ể ử ụ ế ớ ộ ượ ư ư ệ i m t thi ộ i m t thi ộ ả ớ ề ớ ữ ữ ệ ể ư ệ ộ c xây d ng d a trên hai h ng m c c b n là: buffer và ạ channel. M t vùng đ m (buffer) l u tr d li u. M t kênh (channel) bi u di n m t liên k t m ở ữ ữ ệ ộ t b vào ra m i, nh t p tin ho c m t socket. Đ s d ng h th ng vào ra m i, ta t ặ ớ ế ị t b vào ra và m t vùng đ m đ l u tr d li u. Sau đó ph i nh n m t kênh truy n t ế ị ộ ta có th th c hi n thao tác trên vùng đ m đ vào và ra d li u. ệ ậ ể ự ữ ệ ể ệ

6.2. Buffer (Các vùng đ m)ệ

Các vùng đ m đ ệ ượ ớ ị ị i là ch m c trong vùng đ m mà t i h n, và dung l ng. V trí hi n t ệ ạ ượ ệ ạ ẽ ễ ớ ạ ủ ệ c đ nh nghĩa trong gói java.io. T t c các vùng đ m là các l p con ệ ấ ả ệ t c các vùng đ m: ấ ả i đó i h n là ch m c cu i cùng c a vùng đ m. Dung ở ạ Buffer cũng h tr kh năng đánh d u và kh i t o. ọ ng là s ph n t ố ỉ ụ ố ả ỉ ụ ỗ ợ ầ ử ấ ệ ng th c. Buffer, l p này đ nh nghĩa ch c năng chính dùng chung cho t c a l p con ứ ủ ớ ớ v trí hi n th i, gi ị ờ ệ ị ớ ạ thao tác đ c và ghi ti p theo s di n ra. Gi ế có trong vùng đ m. l ượ Buffer đ nh nghĩa m t s ph ộ ố ươ ứ ị

Ph ng th c ươ ứ Mô tả có trong vùng đ m ệ ầ ử ả ề ố

Final int capacity() Final Buffer clear() Final Buffer flip() i h n c a vùng đ m v v trí hi n hành và ệ ề ị

Final boolean hasRemaining() ế ệ ị Abstract boolean isReadOnly() ệ ủ ớ ạ i v trí hi n hành v 0 ề ệ ng th c này tr v giá tr true n u còn các ph n ầ ị ả ề ứ c l i ượ ạ ả ề ế ỉ ọ ệ ị

74

Final int limit() Final Buffer limit(int n) i h n c a vùng đ m là n i h n c a vùng đ m là n và tr v tham ả ề ệ ệ Tr v s ph n t Xóa vùng đ m ệ t l p gi Thi ế ậ t l p l thi ế ậ ạ ị Ph ươ trong vùng đ m. Tr v giá tr false n u ng t ả ề ử Tr v giá tr true n u vùng đ m là ch đ c. Tr v giá ả ề tr false n u ng ế ị t l p gi Thi ế ậ Thi t l p gi ế ậ chi u t ế ớ ế c l i ượ ạ ủ ớ ạ ớ ạ ủ i vùng đ m đ ệ c g i ọ ượ

Final Buffer mark() i vùng t l p v trí đánh d u và tr v tham chi u t ấ ả ề ế ậ ế ớ ị c g i ọ ệ ệ ủ Final int Position() Final Buffer position(int n) ủ ế t l p v trí c a Buffer là n. Tr v m t tham chi u ả ề ộ ị ệ Final Buffer reset() ị ệ t l p tr ế ậ ướ

Final Buffer rewind() t l p v trí hi n hành c a vùng đ m v 0 ủ ệ ề ị Thi đ m đ ượ ệ Tr v v trí hi n hành c a vùng đ m ả ề ị Thi ế ậ i vùng đ m t ớ i v trí hi n hành c a vùng đ m và v trí t l p l Thi ệ ủ ế ậ ạ ị c thi đánh d u đ c đó. Tr v m t tham ả ề ộ ượ ấ chi u t i vùng đ m ệ ế ớ Thi ệ ế ậ B ng 3.3 ả

L p Buffer có các l p con ch a các ki u d li u nh sau: ứ ữ ệ ư ể ớ ớ

• ByteBuffer •

IntBuffer • CharBuffer •

LongBuffer • DoubleBuffer • MappedByteBuffer • FloatBuffer • ShortBuffer

ng th c get() và put() cho phép ta nh n d li u t m t vùng đ m và ấ ả ươ ữ ệ ừ ộ ư ệ ậ T t c các ph đ t d li u vào m t buffer. ặ ữ ệ ộ

ứ ươ

Ph ng th c Abstract byte get() ByteBuffer get(byte[] vals) ữ ệ ạ ị ữ ệ

ầ ế c xác đ nh b i tham s ỉ ở ượ

ầ ử BufferUnderflowException ạ ệ Abstract byte get(int idx) c xác đ nh ữ ệ ạ ị ượ ị i v trí đ ệ ỉ ụ Abstract ByteBuffer put(byte b) ệ i v trí hi n ữ ệ ạ ị

final ByteBuffer put(byte b[]) ầ ử ủ ả c a m ng b v trí hi n hành. ệ i vùng đ m ả ề ByteBuffer put(byte b[], int start, int num) t c các ph n t ắ ầ ừ ị ệ t ầ ử ừ ả

ế t c các ph n t c t ầ

BufferByte put(ByteBuffer bb) ầ ử ủ

ệ c a vùng đ m v trí hi n hành . ệ t c các c t ượ ấ ả ệ ạ ư c a vùng đ m thì ngo i l ệ ử

75

Mô tả i v trí hi n hành Tr v byte d li u t ệ ả ề ộ vùng đ m vào m t Sao chép d li u t ệ ừ ả c tham chi u b i m ng vals. Tr m ng đ ế ả ở ượ ả v m t tham chi u t i buffer ế ớ ề ộ buffer vào ByteBuffer get(byte vals[], int start, int num) Sao chép num s ph n t t ử ừ ố ầ c tham chi u b i vals, b t đ u m ng đ ắ ở ượ ả ố i ch m c đ t ị ụ ạ i vùng đ m. N u start. Tr v tham chi u t ế ệ ế ớ ả ề không còn ph n t ệ nào trong vùng đ m, ngo i l Tr v byte d li u t ả ề b i ch m c idx trong vùng đ m ở Sao chép byte d li u b vào t hành Sao chép t ấ ả vào vùng đ m, b t đ u t ệ Tr v tham chi u t ế ớ ắ ầ m ng b b t đ u Sao chép num ph n t v tham i v trí start vào vùng đ m. Tr t ả ề ệ ạ ị i vùng đ m. N u vùng đ m không chi u t ệ ệ ế ớ c a vùng ch a đ ử ủ ả ượ ư ấ đ m thì ngo i l BufferOverflowException ạ ệ ệ c đ a ra s đ ư ẽ ượ t c các ph n t Sao chép t ấ ả BufferByte g i, b t đ u t ắ ầ ừ ị ọ N u vùng đ m không ch a đ ệ ế ph n t ủ ầ BufferOverflowException s đ Sao chép byte d li u b t Abstract ByteBuffer put(int idx, byte b) c đ a ra ư i v trí idx vào ẽ ượ ạ ị ữ ệ

i vùng đ m ế ớ ệ vùng đ m. Tr v tham chi u t ả ề ệ B ng 3.4 ả

c đ nh nghĩa trong ByteBuffer. T t c các l p buffer còn h tr ượ ứ ớ ỗ ợ ị các ph Ph ươ ấ ả ươ ng th c th c hi n các thao tác khác nhau trên vùng đ m. ệ ng th c put()đ ệ ự ứ

6.3. Các kênh (Channel)

ị ễ ượ ộ ộ ộ ọ ậ ộ ng h tr c đ nh nghĩa trong gói java.io.channel. M t kênh bi u di n m t liên k t ế ể ươ ng c m t kênh b ng cách g i ph ằ ượ ặ kênh. Java 2 phiên b n 1.4 đ a thêm vào ả ư ộ ể ỗ ợ ng th c getChannel() cho các l p sau: ứ ố ượ ớ

Các kênh đ m t i m t ngu n ho c đích vào ra. Ta có th nh n đ ồ ở ớ th c getChannel() trên m t đ i t ứ ph ươ • FileInputStream • FileOutputStream • RandomAccessFile • Socket • ServerSocket • DatagramSocket

c tiên ta ph i nh n m t đ i t ướ ộ ộ ố ượ ậ ng c a các l p này và sau ớ ủ c m t kênh, tr ậ ng th c getChannel() trên đ i t ả ng đó. ể đó g i ph ọ Đ nh n đ ươ ượ ứ ố ượ

ng ch u tác đ ng c a ph ể ụ ể ượ ố ượ ộ ư Ki u kênh c th đ ụ c tr v ph thu c vào ki u đ i t ộ ứ ị ụ ể ng th c getChannel() trên đ i t ố ượ ươ v là FileChannel. Khi g i ph ươ ng ủ ng FileInputStream, ươ ng ọ ặ ng Socket thì ki u kênh tr v là SocketChannel(). ả ề th c getChannel(). Ví d khi g i ph ọ FileOutputStream ho c RandomFileAccess thì kênh tr th c getChannel() trên đ i t ố ượ ả ề ả ề ứ ể

Ph

ng th c ứ

Mô tả

ươ abstract int read(ByteBuffer bb)

kênh vào m t vùng đ m bb ộ ữ ặ ự

abstract int read(ByteBuffer bb, long start)

ế

abstract int write(ByteBuffer bb)

ế ủ

ệ v s byte đã đ

i v trí hi n hành. Tr ệ

ả ề ố

abtsract int write(ByteBuffer bb, int start)

ả ề ố

ượ

i v trí hi n start. Tr v s byte đã đ ệ B ng 3.5

Đ c các byte t ọ i khi đ y vùng đ m ho c không còn d cho t ệ li u trên kênh. Ki u tr v là s byte th c s ệ ả ề đ c đ c ượ ọ ắ kênh vào m t vùng đ m, b t Đ c các byte t ừ ọ i khi đ y vùng đ m v trí start cho t đ u t ệ ừ ị ầ ho c không còn d li u đ u vào. V trí hi n ệ ầ ữ ệ ặ th i không thay đ i. Tr ọ v s byte đã đ c ờ ả ề ố ổ c ho c –1 n u k t thúc lu ng đ ượ Ghi n i dung c a vùng đ m ra kênh, b t đ u ắ ầ t ượ c ạ ị ghi. ắ ầ Ghi n i dung c a vùng đ m ra kênh. B t đ u c ghi t ạ ị ả

Các kênh FileChannel và SocketChannel h tr các ph ỗ ợ ươ ướ ng th c read() và write() cho ng th c read() ươ ứ ộ ố ứ c đ nh nghĩa trong FileChannel. phép ta th c hi n các thao tác vào ra thông qua kênh. D i đây là m t s ph ự và write()đ ượ ệ ị

T t c các kênh đ u h tr các ph ấ ả ỗ ợ ề ỗ ợ ụ ệ ng th c b tr ổ ợ ứ ng th c đ nh n và thi ể ứ ươ i gi a các kênh, nh n kích th ậ ể ề ữ ạ ươ khi n kênh. Ví d , FileChannel h tr các ph truy n thông tin qua l kênh,..FileChannel cũng cung c p ph ng th c map()đ ánh x m t t p vào m t buffer. ề cho phép ta truy xu t và đi u ấ t l p v trí hi n hành, ị ậ ế ậ c hi n th i c a kênh, khóa ủ ờ ệ ướ ạ ộ ệ ươ ứ ể ấ ộ

6.4. Charset và Selector

76

Hai th c th khác đ c s d ng b i NIO là các CharSet và Selector. ự ể ượ ử ụ ở

CharSet xác đ nh cách ánh x các byte thành các ký t ạ ị ể ự ộ ể ả ộ b ng cách s d ng m t b mã hóa và cũng có th gi ử ụ b ng cách s d ng b gi i mã. Charset, encoder và decoder đ . Ta có th mã hóa m t xâu ký i mã m t dãy các byte thành các ký b i gói c h tr ộ ộ ộ ử ụ ả ỗ ợ ở ượ t ự ằ t ự ằ java.nio.charset.

Selector h tr vào ra ghép kênh, không phong t a, d a trên phím. ỗ ợ ỗ ợ ở Ngoài ra, selector b i các l p trong gói ớ ượ ệ ỏ còn cho phép ta làm vi c v i nhi u kênh. Selector đ java.io.channels. Các selector ng d ng nhi u nh t v i các kênh d a trên lu ng. ự c h tr ự ấ ớ ề ụ ớ ứ ề ồ

6.5. S d ng h th ng vào ra m i ớ ệ ố

ử ụ

ứ ẽ ấ ầ ể i các t p tin trên đĩa b ng cách s d ng h th ng vào ra m i. Do h u h t các thao ổ ế ằ ệ ử ụ ệ ố ế ầ ớ c s d ng s là ByteBuffer. Đ n v d li u vào ra ph bi n nh t là t p tin, trong ph n này ta s xem cách th c đ ơ truy xu t t ấ ớ tác trên t p là m c byte nên ki u vùng đ m đ ệ ị ữ ệ ệ ứ ượ ử ụ ể ệ ẽ

6.5.1. Đ c t p ọ ệ

Có m t s cách đ đ c d li u t ệ ố ể ọ ộ ố ẽ ằ ộ ệ ứ ự ộ ộ ệ ự ệ ọ ộ m t t p tin b ng cách s d ng h th ng vào ra m i. ớ ử ụ ữ ệ ừ ộ ệ ộ Chúng ta s xem xét hai cách. Cách th nh t đ c m t t p tin b ng cách ánh x nó vào m t ằ ạ ấ ọ ứ buffer và sau đó th c hi n m t thao tác đ c. Cách th hai đ đ c m t t p tin là t đ ng hóa ể ọ quá trình đ c.ọ

• Cách 1:

B c 1: M m t t p tin đ đ c b ng cách s d ng lu ng FileInputStream. ướ ở ộ ệ ử ụ ể ọ ằ ồ

B c 2: ng FileInputStream nh ph ng th c ướ Nh n m t kênh t ộ ậ đ i t ừ ố ượ ờ ươ ư

FileChannel getChannel()

B c 3: Xác đ nh kích th ướ ị ướ ủ ệ c c a t p tin b ng cách g i ph ằ ọ ươ ng th c size() ứ

Long size() throws IOException

B c 4: ướ

ươ ng th c allocate()đ phân b m t vùng đ m đ l n đ l u gi ổ ộ ể ư ủ ớ ứ ệ ể ữ ộ ủ n i dung c a G i ph ọ t p. ệ

static ByteBuffer allocate(int cap)

Ví dụ

import java.io.*;

import java.nio.*;

import java.nio.channels.*;

public class ChannelRead

{

public static void main(String[] args)

{

FileInputStream fis;

FileChannel fc;

long fSize;

ByteBuffer bb;

try{

//Mo mot ep

77

fis=new FileInputStream(args[0]);

//Mo mot kenh toi tep

fc=fis.getChannel();

//Nhan kich thuoc tep tin

fSize=fc.size();

//Phan bo mot vung dem co kich thuoc can thiet

bb=ByteBuffer.allocate((int)fSize);

//Doc tep tin vao vung dem

fc.read(bb);

//Mo tep de doc

bb.rewind();

for(int i=0;i

fc.close();

fis.close();

}

catch(IOException e)

{

System.out.println(e);

}

}

}

K t qu th c hi n ch ng trình ả ự ế ệ ươ

C:\MyJava>javac ChannelRead.java

C:\MyJava>java ChannelRead Bai3.java

class Bai3 {

public static void main( String args[] ) {

double x = 42 ;

System.out.println( x = 42 % 3 + 3 * 3 - 3 / 3 );

}

}

• Cách 2

ộ ệ Ư ể ễ ơ ạ ộ ộ ệ đ ng l u n i dung c a t p tin. Không c n thao tác đ c c ể ọ ệ ủ ệ ự ộ ư ầ ậ ộ ọ ủ M t cách d h n đ đ c m t t p tin là ánh x vào m t vùng đ m. u đi m cho c a cách ti p c n này là vùng đ m t ụ ế th nào. ể

Các b c th c hi n ướ ự ệ

B c 1: M m t t p tin b ng cách s d ng lu ng FileInputStream ở ộ ệ ử ụ ướ ằ ồ

78

i t p tin đó b ng cách g i ph B c 2: Nh n m t kênh t ậ ướ ộ ớ ệ ằ ọ ươ ố ng th c getChannel() trên đ i ứ ng FileInputStream. t ượ

B c 3: Ánh x kênh v i m t vùng đ m b ng cách g i ph ộ ướ ệ ọ ươ ố ng th c map() trên đ i ứ ng th c map có d ng nh sau: ạ ng FileChannel. Ph ươ t ượ ớ ứ ạ ằ ư

MappedByteBuffer map(FileChannel.MapMode how, long pos, long size) throws IOException

Ph ữ ệ ượ ươ ệ ệ ạ ơ ộ nh . Tham s how xác đ nh ki u thao tác đ ng th c ố ứ map() làm cho d li u trong t p tin đ ự c ánh x và o vùng đ m trong b c phép th c hi n trên t p tin: ệ ượ ệ ể ớ ị

MapMode.READ

MapMode.READ_WRITE

MapMode.PRIVATE

Đ đ c m t t p tin ta dùng ch đ ể ọ ế ọ MapMode.READ. Đ đ c và ghi t p ta dùng ch đ ể ọ ệ ả ộ ỉ ng t ớ ệ ưở ệ ả ổ ị ị c xác đ nh b i ị ố pos và s byte ánh x đ ạ ượ ở ố ế ộ ủ ế ộ MapMode.PRIVATE ch làm cho m t b n sao riêng c a i t p tin. V trí trong t p tin b t ắ ở size. ủ ByteBuffer. M iỗ ế MappedByteBuffer, là m t l p con c a ữ ị ộ vùng đ m. ộ ệ MapMode.READ_WRITE. Ch đ m t t p b thay đ i và nh ng thay đ i này không nh h ộ ệ ổ đ u ánh x đ c xác đ nh b i tham s ạ ượ ầ Ph ứ ươ khi t p tin đ ượ ệ ả ề c ánh x vào vùng đ m ta có th đ c t p t ệ ng th c tr v là m t tham chi u ạ ể ọ ệ ừ ộ ớ ệ

import java.io.*;

import java.nio.*;

import java.nio.channels.*;

public class MappedChannelRead

{

public static void main(String[] args)

{

FileInputStream fis;

FileChannel fc;

MappedByteBuffer mbb;

long fSize;

try{

//Mo tep de doc

fis=new FileInputStream(args[0]);

//Mo kenh

fc=fis.getChannel();

//Nhan kich thuoc tep

fSize=fc.size();

// Anh xa file vao vung dem

mbb=fc.map(FileChannel.MapMode.READ_ONLY,0,fSize);

//Doc cac byte tu vung dem

for(int i=0; i

fc.close();

fis.close();

79

}

catch(IOException e)

{

System.out.println(e.getMessage());

System.exit(1);

}

}

}

K t qu th c hi n ả ự ệ ế

C:\MyJava>java MappedChannelRead Bai3.java

class Bai3 {

public static void main( String args[] ) {

double x = 42 ;

System.out.println( x = 42 % 3 + 3 * 3 - 3 / 3 );

}

}

6.5.2. Ghi t p tin ệ

ể ộ ố Có m t s cách đ ghi t p thông qua m t kênh. ệ Ở ể ộ ệ ử ụ ằ ứ ấ ế ệ ộ ệ ượ ứ ệ c m đ th c hi n các thao tác đ c/ghi, ta có th ánh x c t ệ ữ c mô t đây, chúng ta cũng tìm hi u hai cách ghi t p. Cách th nh t là ghi t p thông qua m t kênh b ng cách s d ng các thao tác write. Cách th hai, n u t p tin đ ạ ể ở ể ự t p vào m t vùng đ m và sau đó ghi vào vùng đ m. Nh ng thay đ i v i vùng đ m s đ ẽ ượ ự ệ ệ ộ đ ng nh h ượ ề ả ộ ọ ổ ớ trong m c này. ụ ng đ n t p tin. C hai cách đ u đ ả ệ ế ệ ưở ả

Đ ghi m t t p thông qua kênh b ng cách s d ng các l i ph ng th c write(), ử ụ ằ i g i t ờ ọ ớ ươ ứ c sau đây. ể ta th c hi n các b ệ ộ ệ ướ ự

B c 1: M m t t p đ ghi. ướ ở ộ ệ ể

ọ Xác đ nh m t vùng đ m byte đ ghi d li u vào vùng đ m đó, sau đó g i ữ ệ ể ệ ệ ộ ị ng th c write(). ph B c 2: ướ ứ ươ

import java.io.*;

import java.nio.*;

import java.nio.channels.*;

public class ChannelWrite

{

public static void main(String[] args)

{

FileOutputStream fos;

FileChannel fc;

ByteBuffer bb;

try

{ String s="This is a test of NIO system";

80

fos=new FileOutputStream(args[0]);

fc=fos.getChannel();

bb=ByteBuffer.allocateDirect(s.length());

//Ghi mot so byte vao vung dem

byte[] b=s.getBytes();

for(int i=0;i

bb.rewind();

fc.write(bb);

fc.close();

fos.close();

}

catch(Exception e)

{

System.err.println(e);

}

}

}

Sao chép m t t p b ng cách s d ng ti n ích vào ra m i ớ ử ụ ộ ệ ệ ằ

ộ ố ể ụ ệ ươ ng ệ ố ả i đây sao chép m t t p tin. trình d H th ng vào ra m i đ n gi n hóa m t s ki u thao tác trên t p tin. Ví d , ch ướ ớ ơ ộ ệ

import java.io.*;

import java.nio.*;

import java.nio.channels.*;

public class NIOCopy

{

public static void main(String[] args)

{

FileOutputStream fos;

FileInputStream fis;

FileChannel fco,fci;

long fSize;

MappedByteBuffer mbb;

try{

fis=new FileInputStream(args[0]);

81

fos=new FileOutputStream(args[1]);

fci=fis.getChannel();

fco=fos.getChannel();

fSize=fci.size();

mbb=fci.map(FileChannel.MapMode.READ_ONLY,0,fSize);

fco.write(mbb);

fci.close();

fco.close();

fos.close();

fis.close();

}

catch(Exception e)

}

}

}

7. K t lu n ế

82

Ch ể ệ ả ng này các lu ng h ươ ồ ng ký t c gi ự ụ ướ ượ ệ ớ ệ i thi u trong ch c gi Ở ệ ệ ớ ử ụ các ch ữ ệ ạ ạ ử ề ằ ồ ng byte và các lu ng ướ i thi u. Khái ni m vào ra m i b ng cách s d ng các ớ ằ ươ ng ng này. ượ ươ ằ ng trình l p trình m ng đ u vào ra d li u b ng ề ậ ế i th đ b n đ c ti p t sâu v lu ng vào ra s là m t l ộ ợ ề ồ ế ể ạ ế ể ẽ ế ọ ầ ệ ng ti p theo. ng này chúng ta đã tìm hi u các khái ni m căn b n v vào ra b ng cách s ươ d ng các lu ng trong Java. Cũng trong ch ồ h trong Java đã đ kênh (channel) và vùng đ m (buffer) cũng đ ti p theo các b n s th y h u h t các ch ươ ẽ ấ ế cách s d ng các lu ng. Vi c hi u bi ử ụ ồ c n v i các ch ớ ậ ươ ế