Kí hiệu e khi ghi file trong java là gì năm 2024
Chào các bạn! Có lẽ đã có quá nhiều những bài viết hướng dẫn các bạn làm việc với file trong Java. Thế nhưng đừng vội bỏ qua chuỗi bài viết này! Show
Nếu các bạn là những người mới bắt đầu làm quen với Java, hay mới chỉ tìm hiểu Java IO qua những ví dụ rời rạc, thì bài viết này của mình được tạo ra chính bởi mong muốn cho các bạn 1 cái nhìn tổng quan và rồi sau đó đi vào chi tiết nhất có thể, để các bạn có thể dễ hình dung hơn, dễ nắm bắt hơn, cũng như hiểu sâu hơn về Java IO. Từ đó, JavaIO sẽ trở nên thật dễ dàng Trong bài viết này, chúng ta sẽ cover các API của vào - ra trong Java ( hay Java IO). Chúng ta sẽ học cách để truy cập vào file hay thư mục và làm sao để đọc, ghi file. Chúng ta cũng đi tìm hiểu sâu hơn về từng lớp trong cây phân cấp trong Java IO để hiểu xem chúng làm gì và vì sao nó được sinh ra, nó mang lại ưu và có nhược điểm gì. Bài viết này cũng sẽ cho các bạn thấy cơ chế serialization đối tượng (), thứ mà sẽ giúp bạn lưu trữ đối tượng một cách thật dễ dàng, dễ như cách mà bạn làm với dữ liệu chữ hay số vậy. Mình cũng cung cấp cho bạn source code demo tương ứng để cho các bạn tiện theo dõi và thực hành. Trong quá trình đọc series về JavaIO này của mình, nếu có bất cứ thắc mắc gì liên quan, vui lòng liên hệ mình theo các địa chỉ
Đồng thời, nếu có điểm gì sai sót, mong các bạn bớt chút thời gian feedback lại, để bài viết có thể được đầy đủ hơn, hoàn thiện hơn, giúp các mới về sau có được những hướng dẫn đầy đủ, chính xác nhưng lại dễ hiểu nhất có thể nhé. Bởi vì khi viết series này, mình cũng chỉ mới tìm hiểu lại về JavaIO thôi I. Sơ lược về Java IO.Java IO (gói 1. Stream (luồng) là gì?Trong Java API, một đối tượng từ đó chúng ta đọc được một dãy bytes được gọi là Byte-oriented streams (Hay luồng hướng byte / luồng hướng tới việc xử lý dạng byte) là không thuận lợi cho việc xử lý thông tin được lưu dưới dạng Unicode (nhắc lại rằng Unicode sử dụng nhiều bytes cho mỗi một ký tự). Do đó, một cây phân cấp tách biệt cung cấp các lớp cho việc xử lý ký tự Unicode được sinh ra, các lớp này được kế thừa từ các lớp trừu tượng 2. Cây phân cấp trong JavaIOXem chi tiết thêm tại https://docs.oracle.com/javase/7/docs/api/java/io/package-tree.html Hình 1: Cây phân cấp trong Java IO top-level Hình 2: Cây phân cấp trong Java IO của byte-oriented stream Hình 3: Cây phân cấp trong Java IO của character-oriented stream (Cái cuối là PrintWriter nhé. Mình sẽ đổi hình sau) Trong bài học trước tôi đã giới thiệu về luồng vào ra nhị phân (input-output binary stream), trong bài này chúng ta tiếp tục tìm hiểu về luồng vào ra ký tự (input-output character stream) trong Java. Như bạn đã biết uồng nhị phân (binary stream), mỗi một lần đọc/ghi một byte (Tương đương với 8 bit), trong khi đó luồng ký tự (character stream) mỗi lần đọc/ghi một ký tự, tùy thuộc vào kiểu mã hóa (encoding) ( UTF-8, UTF-16,..) mà ký tự đó tương đương với 1, 2 hoặc 3 byte. Trong Java, có nhiều lớp hỗ trợ các thao tác với luồng ký tự và các lớp này được dẫn đầu bởi 2 class Reader và Writer:
Nội dung Đọc chuỗi từ consoleVí dụ nhập một chuỗi từ bàn phím và hiển thị chuỗi ra màn hình package com.gpcoder.characterstream; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; public class ReadConsole { public static void main(String[] args) throws IOException { }
}Kết quả thực thi chương trình trên: Enter your name: gpcoder.com Hello gpcoder.com Enter your name: exit Finished! Sử dụng lớp FileReader và FileWriterVí dụ ghi file sử dụng lớp FileWriterimport java.io.FileWriter; public interface FileWriterExample { public static void main(String args[]) { }
}Thực thi chương trình trên, một file test.txt được tạo ra trong thư mục data với nội dung gpcoder.com Ví dụ đọc file sử dụng lớp FileReaderpackage com.gpcoder.characterstream; import java.io.FileReader; public class FileReaderExample { public static void main(String args[]) throws Exception { }
}Kết quả thực thi chương trình trên: gpcoder.com Chuyển một luồng nhị phân thành luồng ký tựVí dụ chuyển từ OutputStream sang Writerpackage com.gpcoder.characterstream; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.Writer; public class OutputStreamWriterExample { public static void main(String[] args) throws IOException { }
}Ví dụ chuyển từ InputStream sang Readerpackage com.gpcoder.characterstream; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; public class InputStreamReaderExample { public static void main(String[] args) throws IOException { }
}Sử dụng FilterInputStream và FilterOutputStreamLớp FilterOutputStream trong java extends lớp OutputStream. Nó cung cấp các lớp con khác nhau như BufferedOutputStream và DataOutputStream để cung cấp các chức năng bổ sung. Vì vậy, nó ít được sử dụng riêng lẻ. Lớp FilterInputStream trong java extends lớp InputStream. Nó cung cấp các lớp con khác nhau như BufferedInputStream và DataInputStream để cung cấp chức năng bổ sung. Vì vậy, nó ít được sử dụng riêng lẻ. Ví dụ ghi file sử dụng lớp FilterOutputStreampackage com.gpcoder.characterstream; import java.io.File; import java.io.FileOutputStream; import java.io.FilterOutputStream; import java.io.IOException; public class FilterOutputStreamExample { public static void main(String[] args) throws IOException { }
}Ví dụ đọc file sử dụng lớp FilterInputStreampackage com.gpcoder.characterstream; import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FilterInputStream; import java.io.IOException; public class FilterInputStreamExample { public static void main(String[] args) throws IOException { }
}Sử dụng lớp BufferedReader và BufferedWriterLớp BufferedWriter trong java được sử dụng để cung cấp bộ đệm cho các các thể hiện của lớp Writer. Nó giúp hiệu suất nhanh. Nó thừa kế lớp Writer. Các ký tự đệm được sử dụng để cung cấp việc ghi dữ liệu hiệu quả với các mảng đơn, các ký tự và chuỗi. Lớp BufferedReader trong java được sử dụng để đọc văn bản từ một input stream dựa trên các ký tự (character stream). Nó có thể được sử dụng để đọc dữ liệu theo dòng (line by line) bằng phương thức readLine(). Nó giúp hiệu suất nhanh. Nó kế thừa lớp Reader. Ví dụ ghi file sử dụng BufferedWriter package com.gpcoder.characterstream; import java.io.BufferedWriter; import java.io.FileWriter; public class BufferedWriterExample { public static void main(String[] args) throws Exception { }
}Ví dụ đọc file sử dụng BufferedReader Enter your name: gpcoder.com Hello gpcoder.com Enter your name: exit Finished! 0 Sử dụng lớp CharArrayReader và CharArrayWriterCharArrayReader gồm có hai từ: CharArray và Reader. Lớp CharArrayReader trong java được sử dụng để đọc mảng ký tự như là một trình đọc (Reader). Nó kế thừa lớp Reader. Lớp CharArrayWriter trong java có thể được sử dụng để ghi dữ liệu chung cho nhiều file. Lớp này thừa kế lớp Writer. Bộ đệm của nó tự động phát triển khi dữ liệu được ghi vào stream này. Gọi phương thức close() đối với đối tượng này không có hiệu lực. Ví dụ đọc một ký tự sử dụng lớp Java CharArrayReaderEnter your name: gpcoder.com Hello gpcoder.com Enter your name: exit Finished! 1 Kết quả thực thi chương trình trên: Enter your name: gpcoder.com Hello gpcoder.com Enter your name: exit Finished! 2 Ví dụ ghi một dữ liệu chung ra nhiều fileEnter your name: gpcoder.com Hello gpcoder.com Enter your name: exit Finished! 3 Thực thi chương trình trên, 4 file f1.txt, f2.txt, f3.txt, f4.txt được tạo ra trong thư mục data và có cùng nội dung gpcoder.com Sử dụng lớp StringReader và StringWriterLớp StringWriter trong java là một charater stream thu thập dữ liệu từ bộ đệm chuỗi, có thể được sử dụng để xây dựng một chuỗi. Lớp StringWriter kế thừa lớp Writer. Trong lớp StringWriter, các tài nguyên hệ thống như các network socket và file không được sử dụng, do đó việc đóng StringWriter là không cần thiết. Lớp StringReader trong java là một character stream với chuỗi như một nguồn dữ liêu. Nó lấy một chuỗi đầu vào và thay đổi nó vào character stream. Nó kế thừa lớp Reader. Trong lớp StringReader, các tài nguyên hệ thống như các network socket và các file không được sử dụng, do đó việc đóng StringReader là không cần thiết. Ví dụ StringWriter sử dụng BufferedReader để đọc file từ luồng (stream)Enter your name: gpcoder.com Hello gpcoder.com Enter your name: exit Finished! 4 Ví dụ StringReader đọc chuỗi như luồng ký tự (stream)Enter your name: gpcoder.com Hello gpcoder.com Enter your name: exit Finished! 5 Ghi file với lớp PrintStreamLớp PrintStream trong java cung cấp các phương thức để ghi dữ liệu vào một stream khác. Lớp PrintStream tự động làm sạch dữ liệu vì vậy không cần gọi phương thức flush(). Hơn nữa, các phương thức của nó không ném ngoại lệ IOException. Enter your name: gpcoder.com Hello gpcoder.com Enter your name: exit Finished! 6 Ghi file với lớp PrintWriterLớp PrintWriter trong java là bản cài đặt của lớp Writer. Nó được sử dụng để ghi các định dạng đại diện của các đối tượng vào stream hướng văn bản. Enter your name: gpcoder.com Hello gpcoder.com Enter your name: exit Finished! 7 Thực thi chương trình trên, một dòng chữ Data to write on Console using PrintWriter trong Console và một file test.txt được tạo ra trong thư mục data của project với nội dung Data to write in File using PrintWriter. Sử dụng lớp PushbackInputStreamLớp PushbackInputStream trong java ghi đè các phương thức của lớp InputStream và cung cấp thêm chức năng mở rộng cho một input stream khác. Nó có thể unread một byte đã được đọc và đẩy trở lại một byte. Enter your name: gpcoder.com Hello gpcoder.com Enter your name: exit Finished! 8 Kết quả thực thi chương trình trên: Enter your name: gpcoder.com Hello gpcoder.com Enter your name: exit Finished! 9 Sử dụng lớp PushbackReaderLớp PushbackReader trong java ghi đè các phương thức của lớp FilterReader và cung cấp thêm các chức năng mở rộng. Nó được sử dụng để đọc một luồng ký tự và có thể đẩy trở lại một ký tự vào stream. import java.io.FileWriter; public interface FileWriterExample { public static void main(String args[]) { }
}0 Kết quả thực thi chương trình trên: import java.io.FileWriter; public interface FileWriterExample { public static void main(String args[]) { }
}1 Sử dụng lớp PipedReader và PipedWriterĐặt ra một tình huống bạn có 2 luồng một luồng đầu vào và một luồng đầu ra. Chẳng hạn luồng dữ liệu đầu vào X đọc một file, lấy thông tin từ luồng này ghi vào luồng dữ liệu Y đầu ra là một file khác. Hai luồng X và Y trong tình huống này là tách riêng nhau. Vì vậy trong ứng dụng bạn phải có 3 thao tác:
Hai thao tác đầu phải có, nhưng bạn muốn bỏ đi thao tác thứ 3, nghĩa là có một cái gì đó liên hệ ngầm với nhau giữa 2 luồng ,để sao cho những ký tự xuất hiện trên luồng đầu đọc X lập tức luồng đầu ra Y biết được và đọc luôn các ký tự đó vào luồng của mình. Đó được gọi là liên hệ đường ngầm giữa 2 luồng vào và ra. Điều này còn thực sự có ý nghĩa hơn khi biết rằng (với hiệu ứng đường ngầm này) khi luồng đầu ra khi đã đọc hết các ký tự trên luồng đầu vào nó tự động chờ đợi các ký tự nào đó xuất hiện trên luồng đầu vào và lại đọc hết vào luồng đầu ra. Thật vậy hiệu ứng đường ngầm này chỉ sử dụng hiệu quả trong một vài tình huống không phải tất cả , và khi sử dụng nó thường được sử dụng đi đôi với xử lý đa luồng (Mulit-thread). |