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.ợ ồ ự ứ ệ ấ ộ 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
ọ ừ
ữ ệ ấ ồ ồ ồ ọ ố ị ư ế
ự ề ẩ ệ
ộ
ẩ
ườ ậ ượ ữ ạ ộ 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, 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
ự ấ ớ ề
ụ ớ
ứ ề ồ ứ ẽ ấ ầ ể
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) } } } 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
ớ
ậ ươ ế4. Lu ng ký t
ồ
ự
5. Lu ng đ m
ồ
ệ
6. Lu ng vào ra m i – New Input Output
ồ
ớ
6.5. S d ng h th ng vào ra m i
ớ
ệ ố
ử ụ
7. K t lu n
ế
ậ