So sánh size của 2 file txt trong java năm 2024

Lớp của Java `BufferedWriter`ghi văn bản vào luồng ký tự đầu ra, đệm các ký tự để ghi các ký tự, mảng và chuỗi một cách hiệu quả. Bạn có thể chuyển kích thước bộ đệm cho hàm tạo làm đối số thứ hai. Nhà xây dựng:

  
BufferedWriter(Writer out) // Create a buffered output character stream that uses the default buffer size.  
BufferedWriter(Writer out, int sz) // Creates a buffered character output stream that uses a buffer with the specified size.  

Show

phương pháp:

  
close() // Close the stream  
flush() // Send the data from the buffer to the Writer  
newLine() // Move to a new line  
write(char[] cbuf, int off, int len) // Write to the buffer  
write(int c) // Write to the buffer  
write(String s, int off, int len) // Write to the buffer  

BufferedReaderĐây là một ví dụ về việc sử dụng các lớp và Java BufferedWriter:

Viết vào một tập tin:

  
import java.io.*;
public class WriteFile {  
    public static void main(String[] args) {  
        String[] list = {"one", "two", "three", "fo"};  
        try {  
            File file = new File("file.txt");  
            FileWriter fileReader = new FileWriter(file); // A stream that connects to the text file  
            BufferedWriter bufferedWriter = new BufferedWriter(fileReader); // Connect the FileWriter to the BufferedWriter
            for (String s : list) {  
                bufferedWriter.write(s + "\n");  
            }
            bufferedWriter.close (); // Close the stream  
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
    }  
}  
  
close() // Close the stream  
mark(int readAheadLimit) // Mark the position in the stream  
markSupported() // Indicates whether stream marking is supported  
int  read() // Read the buffer  
int  read(char[] cbuf, int off, int len) // Read the buffer  
String  readLine() // Next line  
boolean  ready() // Is the stream ready to read?  
reset() // Reset the stream  
skip(long n) // Skip characters  

3ngay lập tức ghi dữ liệu vào đĩa. Mỗi khi chúng tôi truy cập nó, bộ đệm bao quanh nó sẽ tăng tốc ứng dụng của chúng tôi. Bộ đệm sẽ ghi dữ liệu bên trong, sau đó ghi các khối tệp lớn vào đĩa. Chúng tôi đọc dữ liệu từ bàn điều khiển và ghi nó vào một tệp:

  
import java.io.*;
class ConsoleRead {  
    public static void main(String[] args) {  
        try {  
            File file = new File("file.txt");  
            InputStreamReader inputStreamReader = new InputStreamReader(System.in); // A stream for reading from the console  
            BufferedReader bufferedReader = new BufferedReader(inputStreamReader); // Connect InputStreamReader to a BufferedReader
            FileWriter fileReader = new FileWriter(file); // A stream that connects to the text file  
            BufferedWriter bufferedWriter = new BufferedWriter(fileReader); // Connect the FileWriter to the BufferedWriter
            String line;  
            while(!(line = bufferedReader.readLine()).equals("exit")) {  
                bufferedWriter.write(line);  
            }
            bufferedReader.close(); // Close the stream  
            bufferedWriter.close();  
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
    }  
}  

John Selawsky

Tại

A senior Java developer and Java tutor at Learning Tree International programming courses. Sometimes I write some stupid programmi ... [Đọc toàn bộ tiểu sử]

Hầu hết các chương trình ứng dụng hoạt động với dữ liệu được lưu trữ trong các tệp cục bộ hoặc đến từ máy tính qua mạng. Java làm việc với luồng dữ liệu. Một luồng là một chuỗi dữ liệu. Nó cũng có thể được định nghĩa là một thực thể logic tạo ra hoặc tiêu thụ thông tin. Một luồng dữ liệu là một kênh thông qua đó dữ liệu di chuyển từ nguồn đến đích. Nguồn hoặc đích này có thể là thiết bị đầu vào hoặc đầu ra, phương tiện lưu trữ hoặc máy tính trên mạng. Một bộ nhớ lưu trữ dữ liệu vật lý được ánh xạ thành một luồng logic và sau đó, một chương trình Java đọc dữ liệu từ luồng này theo chuỗi – một byte sau một byte, hoặc ký tự sau ký tự. Nói cách khác, một tệp vật lý có thể được đọc bằng cách sử dụng các loại luồng khác nhau, ví dụ: FileTnputStream, hoặc Fi leReader. Java sử dụng các luồng như vậy để thực hiện các hoạt động đầu vào và đầu ra khác nhau.

Sự cần thiết của Các Lớp và Giao diện Stream

Trong Java, luồng là bắt buộc để thực hiện tất cả các hoạt động đầu vào/đầu ra (I/O). Một luồng đầu vào nhận dữ liệu từ một nguồn vào chương trình và một luồng đầu ra gửi dữ liệu đến một đích từ chương trình.

Do đó, các lớp và giao diện luồng giúp hữu ích trong các tác vụ:

  • Đọc dữ liệu từ một luồng
  • Ghi đầu ra vào một luồng.
  • Quản lý tệp đĩa
  • Chia sẻ dữ liệu với mạng máy tính

Mục lục

Các Lớp và Giao diện Luồng

Luồng đầu/ra tiêu chuẩn trong Java được biểu diễn bởi ba trường của lớp System:

  • in

Luồng đầu vào tiêu chuẩn được sử dụng để đọc ký tự dữ liệu. Luồng này phản hồi đến đầu vào bàn phím hoặc bất kỳ nguồn đầu vào nào được chỉ định bởi môi trường hoặc người dùng. Nó đã được định nghĩa như sau:

public static final InputStream in;

  • out

Luồng đầu ra tiêu chuẩn được sử dụng để hiển thị đầu ra trên màn hình hoặc bất kỳ phương tiện đầu ra nào khác. Nó đã được định nghĩa như sau:

public static final PrintStream out;

  • err

Đây là luồng lỗi tiêu chuẩn. Theo mặc định, đây là console của người dùng. Nó đã được định nghĩa như sau:

public static final PrintStream err;

Để đọc hoặc ghi dữ liệu bằng cách sử dụng các luồng Đầu vào/Đầu ra, cần thực hiện các bước sau:

  • Mở một luồng trỏ vào một nguồn dữ liệu cụ thể: một tệp, một socket, URL, và nhiều hơn nữa.
  • Đọc hoặc ghi dữ liệu từ/đến luồng này.
  • Đóng luồng.

InputStream và OutputStream là các lớp trừu tượng và được sử dụng để đọc và ghi các chuỗi byte không có cấu trúc. Các luồng đầu vào và đầu ra khác là các lớp con của các lớp trừu tượng này và được sử dụng để đọc và ghi vào tệp. Các loại luồng byte khác nhau có thể được sử dụng có thể sử dụng chung vì chúng kế thừa cấu trúc của lớp Input/OutputStream. Để đọc hoặc ghi byte, phải sử dụng một lớp con của lớp InputStream hoặc OutputStream tương ứng.

Luồng Phản ứng (Reactive Stream)

Lập trình phản ứng là một mô hình lập trình, tương tự như cách lập trình hướng đối tượng hoặc lập trình hàm là các mô hình lập trình.

Theo Chương trình phản ứng (một hướng dẫn xây dựng kiến trúc hiện đại, linh hoạt và có quy mô lớn), bất kỳ ứng dụng phản ứng nào phải tuân theo bốn đặc điểm chính:

  • Responsive: Hệ thống tập trung vào việc cung cấp thời gian phản hồi nhanh chóng và nhất quán và đáp ứng một cách kịp thời.
  • Resilient: Hệ thống là có khả năng phục hồi và vẫn giữ được tính phản ứng ngay cả khi gặp sự cố.
  • Elastic: Hệ thống là linh hoạt và có thể điều chỉnh tùy theo công việc biến đổi.
  • Message-driven: Hệ thống phụ thuộc vào các hoạt động điều khiển bất đồng bộ dựa trên tin nhắn.

Trong Java, Reactive Streams cung cấp một API chung để triển khai lập trình phản ứng.

RxJava và Akka Streams là hai phiên bản phổ biến của Reactive Streams.

RxJava

RxJava giúp thực hiện multithreading trong ứng dụng. RxJava là một trong những API được sử dụng cho Java. RxJava là một hiện thực Java của Reactive Extensions, là một thư viện cho các chương trình không đồng bộ và dựa trên sự kiện. Điều này được thực hiện bằng cách sử dụng mẫu Iterator, quan sát và lập trình hàm.

Trong thế giới Rx (lập trình phản ứng), có hai loại chính:

  • Observables: Được gọi là các đối tượng phát ra một chuỗi sự kiện hoặc dữ liệu,
  • Observers/Subscribers: Được gọi là các đối tượng thực hiện trên dữ liệu được phát ra.

Akka Concepts

Akka là một thư viện mã nguồn mở giúp phát triển dễ dàng các ứng dụng đồng thời và phân tán với Java, Akka là cả một nguyên tắc thiết kế và một nền tảng đồng thời.

Akka sử dụng mô hình Actor, mô hình/thiết kế trong đó “một actor” đại diện cho một thực thể tính toán độc lập. Actor tương tác chỉ thông qua các tin nhắn không đồng bộ và không tương tác thông qua các cuộc gọi phương thức trực tiếp. Không có phương thức nào có thể được gọi trên các đối tượng bên ngoài, nhưng việc truyền các actor dưới dạng đối tượng là có thể. Trong hầu hết các trường hợp, một trường hợp lớp được sử dụng cho điều này.

Hỗ trợ Reactive Streams được giới thiệu trong Java 9 thông qua java.util.concurrent.Flow API.

Luồng Phản ứng Java 9

Reactive Streams liên quan đến việc xử lý luồng theo cách không đồng bộ. Nó yêu cầu một nhà xuất bản để xuất bản luồng dữ liệu và một người đăng ký để tiêu thụ dữ liệu. Đôi khi dữ liệu được chuyển đổi giữa nhà xuất bản(publisher) và người đăng ký (subcriber). Cuối cùng, bộ xử lý chuyển đổi dữ liệu nhận được từ nhà xuất bản để người đăng ký hiểu được. Do đó, có thể có một loạt các bộ xử lý.

Triển khai Luồng Phản ứng bằng Flow API

Java Flow API từ phiên bản 9 trở đi triển khai đặc tả Reactive Streams. Sự kết hợp giữa mẫu Iterator và Observer tạo nên Flow API. Nếu một ứng dụng rút các mục từ nguồn, đó được gọi là mô hình rút theo Iterator. Nếu nguồn đẩy một mục đến ứng dụng, đó được gọi là mô hình đẩy theo Observer. Trong quá trình đăng ký, người đăng ký Java Flow API có thể yêu cầu N mục. Sau đó, các mục được đẩy đến người đăng ký cho đến khi tất cả các mục được thực hiện hoặc một lỗi xuất hiện.

Các lớp và giao diện của Flow API

Dưới đây là các lớp và giao diện của Flow API:

java.util.concurrent.Flow

Lớp này của Flow API là lớp chính và bao gồm các giao diện quan trọng của Flow API được lồng trong lớp này. Nó là một lớp cuối cùng và không thể được mở rộng.

java.util.concurrent.Flow.Publisher

Đây là một giao diện chức năng và mọi nhà xuất bản phải triển khai phương thức subscribe () để thêm người đăng ký để nhận thông điệp.

java.util.concurrent.Flow.Subscriber

Mỗi người đăng ký phải thực hiện giao diện này. Các phương thức của người đăng ký được thực hiện theo thứ tự tuần tự nghiêm ngặt. Bốn phương thức trong giao diện này được mô tả trong Bảng dưới.

Phương thứcMô tảsubscribeNhư người đăng ký, đăng ký để nhận thông điệp, phương thức này được khởi tạo bởi nhà xuất bản. Để bắt đầu nhận các mục từ bộ xử lý, subscription.request() được gọi trong cài đặt của phương thức này, nơi subscription là một trường hợp của giao diện Flow.Subscription.onContextSau khi nhận được một mục từ một nhà xuất bản, logic nghiệp vụ được triển khai để xử lý luồng. Phương thức onContext được triển khai để yêu cầu thêm dữ liệu từ nhà xuất bản.onErrorKhi xảy ra lỗi không thể phục hồi, phương thức onError được khởi chạy. Phương thức này cho phép các công việc dọn dẹp, chẳng hạn như kết thúc/đóng kết nối cơ sở dữ liệu trước khi kết thúc nhiệm vụ.onCompleteSau khi sản xuất tất cả các mục, nhà xuất bản sẽ được đóng. Sau đó, cuối cùng, phương thức onComplete được khởi chạy. Nó cũng được sử dụng để gửi thông báo khi luồng được xử lý một cách hiệu quả.Các phương thức của giao diện Subscriber

java.util.concurrent.Flow.Subscription

Người đăng ký sử dụng giao diện này để đăng ký vào một nhà xuất bản. Giao diện này xây dựng các liên kết không đồng bộ không chặn giữa một nhà xuất bản và người đăng ký. Nó cung cấp một phương thức request để người đăng ký yêu cầu các mục từ nhà xuất bản. Nó cũng cung cấp một phương thức hủy bỏ để kết thúc việc đăng ký.

java.util.concurrent.Flow.Processor

Giao diện này giúp biến đổi tin nhắn giữa nhà xuất bản và người đăng ký và mở rộng đến cả hai.

java.util.concurrent.SubmissionPublisher

Nó sử dụng khung Executor để phát hành các mục được gửi đến người đăng ký hiện tại một cách không đồng bộ cho đến khi nó được đóng. Ví dụ, người ta nên sử dụng lớp này trong các ví dụ luồng phản ứng để thêm một người đăng ký và sau đó, gửi các mục.

Ghi chú: Phát triển bằng cách sử dụng luồng Phản ứng được khuyến nghị chỉ trong các ứng dụng Java tiên tiến và phức tạp.

takeWhile(), dropWhile(), ofNullable(), và iterate với Condition

Trong Java, có thể thực hiện các hoạt động toàn diện với mẫu đối tượng khi sử dụng luồng (streams). Các phương thức sau đây làm tinh chỉnh luồng:

takeWhile(Predicate Interface)

Cú pháp:

default Stream takeWhile(Predicate predicate)

Phương thức takeWhile nhận giá trị cho đến khi điều kiện trả về false. Phương thức takeWhile chọn tiền tố dài nhất của các phần tử từ một luồng phù hợp với điều kiện đã cho trong một luồng được sắp xếp.

Ví dụ:

public static final PrintStream out;

0

dropWhile(Predicate Interface)

Phương thức dropWhile loại bỏ toàn bộ dải giá trị ban đầu cho đến khi điều kiện trả về true. Trong một luồng được sắp xếp, phương thức này trả về các phần tử còn lại sau khi loại bỏ tiền tố dài nhất của các phần tử phù hợp với điều kiện đã cho.

Cú pháp:

public static final PrintStream out;

1

Ví dụ:

public static final PrintStream out;

2

iterate()

Phương thức lặp dừng vòng lặp khi vị từ hasNext hiển thị giá trị là false.

Cú pháp:

public static final PrintStream out;

3

Ví dụ:

public static final PrintStream out;

4

Output:

public static final PrintStream out;

5

ofNullable()

Phương thức ofNullable ngăn chặn NullPointerException và phù hợp với các luồng kiểm tra giá trị null. Nếu đối tượng không phải là null, phương thức này trả về một Stream có thứ tự bao gồm một phần tử duy nhất; ngược lại trả về một Stream trống.

Cú pháp:

public static final PrintStream out;

6

Ví dụ:

public static final PrintStream out;

7

Output:

public static final PrintStream out;

8

Lớp File và Các Phương thức của lớp File

Khác với các lớp khác làm việc với luồng (stream), lớp File tương tác trực tiếp với các tệp và hệ thống tệp. Các tệp được đặt tên bằng cách sử dụng quy ước đặt tên tệp của hệ điều hành máy chủ. Những quy ước này được đóng gói bằng cách sử dụng các hằng số của lớp File.

Một đường dẫn có thể là tuyệt đối hoặc tương đối. Trong một đường dẫn tuyệt đối, không cần thông tin bổ sung nào để xác định tệp cần thiết vì đường dẫn là hoàn chỉnh. Trong một đường dẫn tương đối, thông tin được thu thập từ một đường dẫn khác. Các lớp trong gói java.io giải quyết đường dẫn tương đối đối với thư mục người dùng hiện tại, được đặt bởi thuộc tính hệ thống user.dir.

Lưu ý: Điều này thường là thư mục mà JVM được gọi.

getParent() là phương thức được sử dụng để có được thư mục cha của một đường dẫn trừu tượng. Điều này bao gồm tiền tố của đường dẫn và mỗi tên trong chuỗi tên của đường dẫn. Lưu ý rằng tên cuối cùng không được bao gồm. Đường dẫn tuyệt đối của mỗi thư mục là một tổ tiên của bất kỳ đối tượng File nào có đường dẫn trừu tượng tuyệt đối. Ví dụ, “/use” là một tổ tiên của thư mục được chỉ định bằng đường dẫn /usr/local/bin.

Lưu ý: Trong đường dẫn, /usr/local/bin là một tổ tiên của thư mục đường dẫn /usr/local/bin.

Khái niệm tiền tố được sử dụng để xử lý thư mục gốc trên các nền tảng như UNIX. Bảng 5.2 mô tả tiền tố mà mỗi nền tảng sử dụng.

Nền tảngTiền tốMô tảUNIX“/”là tiền tố cho một đường dẫn tuyệt đối. Không có tiền tố cho đường dẫn tương đối. Đường dẫn trừu tượng chỉ định thư mục gốc có tiền tố “/” và một chuỗi tên trống.Microsoft Windows:Tiền tố của đường dẫn chứa chỉ định ổ đĩa bao gồm một chữ cái ổ đĩa theo sau là “:”. Điều này được theo sau bởi “\” nếu đường dẫn là tuyệt đối. Trong đường dẫn tương đối, không có tiền tố khi không có ổ đĩa được chỉ định.

Khi các đối tượng của lớp File được tạo, đường dẫn trừu tượng được biểu diễn bởi một đối tượng File không bao giờ thay đổi. Nói cách khác, đối tượng của lớp File là không thay đổi.

Lớp File đóng gói quyền truy cập thông tin về một tệp hoặc thư mục. Nó lưu trữ đường dẫn và tên của một thư mục hoặc tệp. Tất cả các hoạt động thông thường với tệp và thư mục được thực hiện bằng cách sử dụng các phương thức truy cập do

lớp File cung cấp. Các phương thức của lớp này cho phép tạo, xóa và đổi tên tệp, cung cấp quyền truy cập đến đường dẫn của tệp, xác định xem đối tượng nào là tệp hay thư mục và kiểm tra quyền truy cập đọc và ghi.

Các phương thức thư mục trong lớp File cho phép tạo, xóa, đổi tên và liệt kê các thư mục.

Các giao diện và lớp được định nghĩa bởi gói java.nio.file giúp máy ảo Java truy cập tệp tin hệ thống và thuộc tính của tệp. Phương thức toPath() giúp có được một Path sử dụng đường dẫn trừu tượng. Một đối tượng File sử dụng đường dẫn này để định vị một tệp.

Để chẩn đoán lỗi khi một hoạt động trên tệp thất bại, Path có thể được sử dụng với lớp Files.

Lưu ý: Khi Path được sử dụng với lớp Files, có sự truy cập hào phóng đến các ngoại lệ, hoạt động tệp bổ sung và thuộc tính tệp.

Các hàm khởi tạo của lớp File như sau:

File(String dirPath) Hàm tạo File(String dirPath) tạo một đối tượng File với đường dẫn của tệp được chỉ định bởi biến chuỗi dirPath thành một đường dẫn trừu tượng. Nếu chuỗi trống, kết quả là một đường dẫn trừu tượng trống. Chữ ký của nó như sau:

public static final PrintStream out;

9

File(String parent, String child) Hàm khởi tạo File(String parent, String child) tạo một đối tượng File với đường dẫn của tệp được chỉ định bởi các biến chuỗi parent và child. Nếu chuỗi cha là null, thì một thể hiện mới của File được tạo ra bằng cách sử dụng chuỗi đường dẫn con cung cấp. Hàm tạo này sẽ hoạt động giống như hàm tạo File một đối số với chuỗi đường dẫn con được cung cấp. Ngược lại, chuỗi đường dẫn cha được xem xét là trỏ đến một thư mục, và chuỗi đường dẫn con được xem xét là trỏ đến một thư mục hoặc tệp. Nếu chuỗi đường dẫn con là tuyệt đối, nó được chuyển đổi thành đường dẫn tương đối theo cách phụ thuộc vào hệ thống. Chữ ký của nó như sau:

public static final PrintStream err;

0

File(File fileObj, String fileName)

Hàm khởi tạo File(File fileObj, String fileName) tạo một đối tượng File mới từ một đối tượng File khác được chỉ định bởi biến fileObj, và tên tệp được chỉ định bởi biến chuỗi fileName. Nếu cha là null, thì một thể hiện mới của File được tạo ra bằng cách sử dụng chuỗi đường dẫn con cung cấp. Hàm tạo của File một đối số với chuỗi đường dẫn con được gọi và một thể hiện mới của File được tạo ra. Nếu điều này không xảy ra, đường dẫn trừu tượng cha được coi là trỏ đến một thư mục và chuỗi đường dẫn con được xem xét là trỏ đến một thư mục hoặc tệp. Chuỗi đường dẫn con được chuyển đổi thành đường dẫn tương đối theo cách phụ thuộc vào hệ thống nếu nó là tuyệt đối. Nếu cha là đường dẫn trừu tượng trống, một thể hiện mới của File được tạo ra. Điều này xảy ra bằng cách chuyển đổi con thành một đường dẫn trừu tượng và giải quyết kết quả so với một thư mục mặc định phụ thuộc vào hệ thống. Nếu không có điều này xảy ra, mỗi chuỗi đường dẫn được chuyển đổi thành một đường dẫn trừu tượng và đường dẫn trừu tượng con được giải quyết đối với cha.

Chữ ký của nó như sau:

public static final PrintStream err;

1

File(URL urlObj)

Hàm khởi tạo File(URL urlObj) chuyển đổi URL được chỉ định thành một đường dẫn trừu tượng và tạo một thể hiện mới của File. Đối với môi trường của URL là phụ thuộc hệ thống. Sự chuyển đổi bởi hàm tạo này cũng phụ thuộc vào hệ thống. Chữ ký của nó như sau:

public static final PrintStream err;

2

Ví dụ:

public static final PrintStream err;

3

Các phương thức trong lớp File

Các phương thức trong lớp File giúplàm việc với tệp trên hệ thống tệp. Một số phương thức bao gồm:

  1. renameTo(File newName) Phương thức renameTo(File newName) sẽ đặt tên cho đối tượng File hiện tại bằng tên mới được chỉ định bởi biến newName.

public static final PrintStream err;

4

  1. delete() Phương thức delete() xóa tệp được biểu diễn bởi đường dẫn trừu tượng.

public static final PrintStream err;

5

  1. exists() Phương thức exists() kiểm tra sự tồn tại của tệp hoặc thư mục được chỉ định bởi đường dẫn trừu tượng này.

public static final PrintStream err;

6

  1. getPath() Phương thức getPath() chuyển đổi đường dẫn trừu tượng thành một chuỗi đường dẫn.

public static final PrintStream err;

7

  1. isFile() Phương thức isFile() kiểm tra xem tệp được chỉ định bởi đường dẫn trừu tượng này có phải là một tệp thông thường không.

public static final PrintStream err;

8

  1. createNewFile() Phương thức createNewFile() tạo một tệp trống mới có tên là đường dẫn cho tệp này. Chỉ tạo khi tệp có tên tương tự không tồn tại.

public static final PrintStream err;

9

  1. mkdir() Phương thức mkdir() tạo thư mục có tên được chỉ định bởi đường dẫn trừu tượng này.

java.util.concurrent.Flow

0

  1. toPath() Phương thức toPath() trả về một đối tượng java.nio.file.Path được xây dựng từ đường dẫn trừu tượng.

java.util.concurrent.Flow

1

  1. toURI() Phương thức toURI() xây dựng một URI tệp. Tệp này đại diện cho đường dẫn trừu tượng này.

java.util.concurrent.Flow

2

Ví dụ:

java.util.concurrent.Flow

3

Ví dụ sử dụng lớp triển khai từ interface FilenameFilter để lọc file với các đuôi mở rộng xác định:

Tạo lớp FileFilter

java.util.concurrent.Flow

4

Tạo lớp DirList

java.util.concurrent.Flow

5

Lớp FileDescriptor

Lớp FileDescriptor cung cấp truy cập đến các bản mô tả tệp mà hệ điều hành duy trì khi tệp và thư mục được truy cập. Trong việc sử dụng thực tế, một bản mô tả tệp được sử dụng để tạo FileInputStream hoặc FileOutputStream để chứa nó. Bản mô tả tệp không nên được tạo ra độc lập bởi ứng dụng vì chúng liên quan đến hệ điều hành.

Lớp FileDescriptor có các trường công khai sau:

java.util.concurrent.Flow

6

Trường tĩnh FileDescriptor err hoạt động như một cánh cửa đến luồng lỗi tiêu chuẩn.

java.util.concurrent.Flow

7

Trường tĩnh FileDescriptor in hoạt động như một cánh cửa đến luồng nhập tiêu chuẩn.

java.util.concurrent.Flow

8

Trường tĩnh FileDescriptor out hoạt động như một cánh cửa đến luồng xuất tiêu chuẩn.

Constructor và Phương thức của FileDescriptor

Các constructor và phương thức của lớp FileDescriptor như sau:

FileDescriptor()

Constructor tạo ra một đối tượng FileDescriptor không hợp lệ.

java.util.concurrent.Flow

9

sync()

Phương thức sync() xóa bộ đệm hệ thống và ghi nội dung mà chúng chứa xuống phần cứng thực tế.

java.util.concurrent.Flow.Publisher

0

valid()

Phương thức valid() kiểm tra xem bản mô tả tệp có hợp lệ không. Do bản mô tả tệp liên quan đến các tệp mở, chúng trở thành không hợp lệ khi tệp được đóng.

java.util.concurrent.Flow.Publisher

1

Ví dụ:

java.util.concurrent.Flow.Publisher

2

Giao diện DataInput và DataOutput

Luồng dữ liệu hỗ trợ đầu ra/nhập của các kiểu dữ liệu nguyên thủy và giá trị chuỗi. Các luồng dữ liệu triển khai giao diện DataInput hoặc DataOutput.

Giao diện DataInput có các phương thức để:

Đọc các byte từ một luồng nhị phân và chuyển đổi dữ liệu thành bất kỳ kiểu nguyên thủy Java nào. Chuyển đổi dữ liệu từ định dạng Java Unicode sửa đổi (UTF)-8 thành chuỗi.

UTF-8 là một định dạng đặc biệt để mã hóa giá trị Unicode 16 bit.

Lưu ý: UTF-8 giả định rằng trong hầu hết các trường hợp, tám bit cao của một Unicode sẽ là không và tối ưu hóa tương ứng.

Giao diện DataOutput có các phương thức để:

Chuyển đổi dữ liệu hiện có trong kiểu nguyên thủy của Java thành một loạt byte và ghi chúng vào một luồng nhị phân, Chuyển đổi dữ liệu chuỗi thành định dạng UTF-8 được sửa đổi bởi Java và ghi vào một luồng.

Phương thức của Giao diện DataInput

Giao diện DataInput có một số phương thức để đọc đầu vào, chẳng hạn như dữ liệu nhị phân từ luồng đầu vào và xây dựng lại dữ liệu từ byte thành bất kỳ kiểu nguyên thủy Java nào. Một IOException sẽ được kích hoạt nếu các phương thức không thể đọc bất kỳ byte nào từ luồng hoặc nếu luồng đầu vào đã đóng.

Các phương thức trong giao diện DataInput như sau:

readBoolean()

Phương thức readBoolean() đọc một byte đầu vào từ một luồng và trả về true nếu byte không phải là không và false nếu ngược lại.

java.util.concurrent.Flow.Publisher

3

readByte()

Phương thức readByte() đọc một byte từ một luồng, là giá trị có dấu trong khoảng từ -128 đến 127.

java.util.concurrent.Flow.Publisher

4

readInt()

Phương thức readInt() đọc bốn byte từ một luồng và trả về giá trị int của các byte đã đọc.

java.util.concurrent.Flow.Publisher

5

readDouble()

Phương thức readDouble() đọc 8 byte từ một luồng và trả về giá trị double của các byte đã đọc.

java.util.concurrent.Flow.Publisher

6

readChar()

Phương thức readChar() đọc hai byte từ một luồng và trả về giá trị char.

java.util.concurrent.Flow.Publisher

7

readLine()

Phương thức readLine() đọc một dòng văn bản từ luồng đầu vào. Nó đọc một byte mỗi lần và sau đó chuyển đổi byte thành một ký tự và tiếp tục đọc cho đến khi nó gặp kết thúc dòng hoặc kết thúc tệp. Các ký tự sau đó được trả về dưới dạng một chuỗi.

java.util.concurrent.Flow.Publisher

8

readUTF()

Phương thức readUTF() đọc một dòng văn bản trong định dạng UTF-8 được sửa đổi từ một luồng.

java.util.concurrent.Flow.Publisher

9

Ví dụ sử dụng lớp DataInputStream được triển khai từ giao diện DataInput:

java.util.concurrent.Flow.Subscriber

0

Phương thức của giao diện DataOutput

Giao diện DataOutput có nhiều phương thức để ghi đầu ra, chẳng hạn như dữ liệu nhị phân vào luồng đầu ra. Một IOException có thể được kích hoạt nếu byte không thể được ghi vào luồng.

Các phương thức quan trọng trong giao diện này như sau:

writeBoolean(boolean b)

Phương thức writeBoolean(boolean b) ghi giá trị boolean được đưa vào làm tham số vào một luồng đầu ra. Nếu đối số có giá trị là true, thì sẽ được ghi 1, ngược lại, giá trị được ghi.

java.util.concurrent.Flow.Subscriber

1

writeByte(int value)

Phương thức writeByte(int value) ghi giá trị byte của số nguyên được đưa vào làm tham số vào một luồng đầu ra.

java.util.concurrent.Flow.Subscriber

2

writeInt(int value)

Phương thức writeInt(int value) ghi bốn byte biểu diễn giá trị số nguyên được đưa vào làm tham số vào một luồng đầu ra.

java.util.concurrent.Flow.Subscriber

3

writeDouble(double value)

Phương thức writeDouble(double value) ghi tám byte biểu diễn giá trị số thực double được đưa vào làm tham số vào một luồng đầu ra.

java.util.concurrent.Flow.Subscriber

4

writeChar(int value)

Phương thức writeChar(int value) ghi giá trị char của số nguyên được đưa vào làm tham số vào một luồng.

java.util.concurrent.Flow.Subscriber

5

writeChars(String value)

Phương thức writeChars(String value) ghi chuỗi được đưa vào làm tham số vào một luồng.

java.util.concurrent.Flow.Subscriber

6

writeUTF(String value)

Phương thức writeUTF(String value) ghi một chuỗi dưới dạng UTF-8 được sửa đổi được đưa vào làm tham số vào một luồng.

java.util.concurrent.Flow.Subscriber

7

Đoạn mã dưới hiển thị việc sử dụng giao diện DataOutput thông qua lớp DataOutputStream, lớp này thực hiện giao diện này. Mã giả định rằng đã có một thể hiện outStream đã được tạo và khởi tạo.

java.util.concurrent.Flow.Subscriber

8

Gói (Package) java.io

Một luồng (stream) đại diện cho nhiều nguồn và đích, như tệp trên đĩa và mảng trong bộ nhớ. Đó là một chuỗi dữ liệu. Một luồng I/O đại diện cho một nguồn đầu vào hoặc một đích đầu ra.

Các luồng hỗ trợ nhiều hình thức dữ liệu, như các byte đơn giản, kiểu dữ liệu nguyên thủy, ký tự cục bộ và các loại dữ liệu khác. Một số luồng cho phép dữ liệu trôi qua và một số luồng biến đổi dữ liệu một cách hữu ích.

Tuy nhiên, tất cả các luồng đều cung cấp một mô hình đơn giản để chương trình sử dụng chúng.

Một chương trình sử dụng một luồng đầu vào để đọc dữ liệu từ một nguồn. Nó đọc một mục mỗi lần.

So sánh size của 2 file txt trong java năm 2024

Một chương trình sử dụng một luồng đầu ra để khi dữ liệu tới nguồn. Nó viết mộ mục mỗi lần

So sánh size của 2 file txt trong java năm 2024

Chú ý: Các chương trình sử dụng byte streams để thực hiện đầu vào và đầu ra của byte 8-bit. Tất cả các lớp byte stream đều xuất phát từ InputStream và OutputStream.

Có nhiều lớp byte stream. Chúng hoạt động theo cùng một cách nhưng khác nhau về cách xây dựng.

Đoạn mã dưới mô tả cách byte streams hoạt động bằng cách sử dụng lớp FileInputStream và lớp FileOutputStream.

java.util.concurrent.Flow.Subscriber

9

Trong Đoạn mã trên, phương thức read() đọc một ký tự và trả về một giá trị int. Điều này cho phép phương thức read() chỉ ra rằng đã đến cuối luồng bằng cách trả về một giá trị là -1. Bằng cách sử dụng phương pháp này, toàn bộ nội dung của Hello.txt được đọc và sau đó, sao chép vào outagain.txt. Lưu ý rằng đường dẫn cho outagain.txt không được chỉ định. Điều này có nghĩa là nó sẽ được tạo trong thư mục hiện tại, tức là thư mục chứa tệp java này.

Khi một luồng không còn cần thiết nữa, quan trọng là phải đóng luồng, như được hiển thị ở đây trong khối finally. Điều này giúp tránh rò rỉ tài nguyên.

Nền tảng Java sử dụng quy ước Unicode để lưu trữ giá trị ký tự. I/O dòng ký tự chuyển đổi định dạng này vào và ra khỏi bộ ký tự địa phương.

Lưu ý rằng trong các vùng địa phương phương Tây, bộ ký tự địa phương thường là một siêu tập hợp 8-bit của ASCII.

Đối với hầu hết các ứng dụng, đầu vào và đầu ra được thực hiện bằng các lớp dòng tự động dịch từ và sang bộ ký tự địa phương. Một chương trình sử dụng các lớp dòng ký tự sẽ thích ứng với bộ ký tự địa phương và sẵn sàng cho quốc tế hóa. Tất cả các lớp dòng ký tự được xuất phát từ các lớp Reader và Writer. Có các lớp dòng ký tự chuyên biệt trong các hoạt động I/O tệp như FileReader và FileWwriter.

Đoạn mã dưới thể hiện việc đọc và ghi các luồng ký tự bằng cách sử dụng lớp FileReader và FileWriter:

java.util.concurrent.Flow.Subscription

0

Các luồng ký tự hoạt động như các lớp bọc cho luồng byte. Luồng ký tự quản lý việc chuyển đổi giữa ký tự và byte và sử dụng luồng byte để thực hiện các hoạt động I/O vật lý. Ví dụ, FileWriter sử dụng lớp FileOutputStream để ghi dữ liệu.

Khi không có lớp luồng ký tự đã đóng gói sẵn nào được yêu cầu, các luồng chuyển đổi từ byte sang ký tự, InputStreamReader và OutputStreamWriter, được sử dụng để tạo ra các luồng ký tự.

I/O ký tự thường xảy ra ở đơn vị lớn hơn so với từng ký tự một, chẳng hạn như một dòng bao gồm một chuỗi ký tự với một ký tự kết thúc dòng ở cuối.

Ký tự kết thúc dòng có thể là bất kỳ trong số các dạng sau:

  • Chuỗi kết thúc dòng và xuống dòng “\r\n”
  • Một ký tự trả về dòng duy nhất (“\r”)
  • Một ký tự xuống dòng duy nhất (“\n”)

Các phương thức BufferedReader.readLine() và PrintWriter.println() giúp đầu vào và đầu ra của một dòng mỗi lần. Phương thức readLine() trả về một dòng văn bản với dấu kết thúc dòng. Phương thức println() đưa ra mỗi dòng trên một dòng mới khi nó thêm ký tự kết thúc dòng cho hệ điều hành hiện tại. Lưu ý rằng các ký tự kết thúc dòng trong tệp đầu vào và đầu ra có thể khác nhau.

Lớp InputStream và Các Lớp Con

Lớp

public static final PrintStream out;

52 là một lớp trừu tượng xác định cách các luồng nhận dữ liệu và là lớp cha của tất cả các lớp luồng. Lớp này bao gồm các phương thức để đọc byte hoặc mảng byte, đánh dấu vị trí trong luồng, xác định số byte đã đọc hoặc có sẵn để đọc, và nhiều hơn nữa. Nó được sử dụng để đọc dữ liệu từ một luồng nhập.

Hình dưới mô tả cấu trúc lớp InputStream

So sánh size của 2 file txt trong java năm 2024

Các phương thức lớp InputStream

Lớp InputStream cung cấp một số phương thức để quản lý việc đọc dữ liệu từ một luồng. Một số phương thức này bao gồm:

  • read(): Phương thức này đọc byte tiếp theo từ luồng nhập và trả về một giá trị int trong khoảng từ 0 đến 255. Phương thức trả về -1 khi đến cuối tệp.

java.util.concurrent.Flow.Subscription

1

  • available(): Phương thức available() trả về số byte có thể đọc mà không bị chặn, kết quả là chỉ số số byte có sẵn.

java.util.concurrent.Flow.Subscription

2

  • close(): Phương thức close() đóng luồng nhập, giải phóng tài nguyên hệ thống liên quan đến luồng.

java.util.concurrent.Flow.Subscription

3

  • mark(int readlimit): Phương thức mark(int readlimit) đánh dấu vị trí hiện tại trong luồng và sẽ duy trì đến khi số byte được chỉ định bởi biến readlimit được đọc. Cuộc gọi đến phương thức reset() đặt lại con trỏ đến vị trí đã đánh dấu cuối cùng.

java.util.concurrent.Flow.Subscription

4

  • skip(long n): Phương thức skip(long n) bỏ qua n byte dữ liệu khi đọc từ luồng nhập.

java.util.concurrent.Flow.Subscription

5

  • reset(): Phương thức reset() đặt lại con trỏ đọc về vị trí đã đánh dấu trước đó trong luồng.

java.util.concurrent.Flow.Subscription

6

Lớp FileInputStream

Đối tượng luồng tệp có thể được tạo bằng cách truyền tên của tệp, hoặc một đối tượng File, hoặc một đối tượng FileDescriptor tương ứng. Lớp FileInputStream được sử dụng để đọc các byte từ một tệp. Khi một đối tượng của lớp FileInputStream được tạo, nó cũng được mở để đọc. Lớp FileInputStream ghi đè tất cả các phương thức của lớp InputStream ngoại trừ các phương thức mark() và reset(). Phương thức reset() sẽ sinh ra một ngoại lệ IOException.

Các hàm khởi tạo phổ biến của lớp này bao gồm:

  • FileInputStream(String sObj): Tạo một đối tượng InputStream có thể được sử dụng để đọc các byte từ một tệp. Tham số sObj lưu trữ đường dẫn đầy đủ của một tệp.

java.util.concurrent.Flow.Subscription

7

  • FileInputStream(File fileObj): Tạo một đối tượng InputStream có thể được sử dụng để đọc các byte từ một tệp, với fileObj là một đối tượng File.

java.util.concurrent.Flow.Subscription

8

  • FileInputStream(FileDescriptor fdObj): Tạo một đối tượng FileInputStream sử dụng đối tượng FileDescriptor có thể được sử dụng để biểu diễn một kết nối hiện tại đến tệp có sẵn trong hệ thống tệp. Đối tượng FileDescriptor là fdObj.

java.util.concurrent.Flow.Subscription

9

Đoạn mã dưới mô tả cách tạo đối tượng FileInputStream.

java.util.concurrent.Flow.Processor

0

Đoạn mã dưới minh họa cách tạo một đối tượng FileInputStream

java.util.concurrent.Flow.Processor

1

Lớp ByteArrayInputStream

Lớp ByteArrayInputStream (ByteArrayInputStream) chứa một bộ đệm lưu trữ các byte được đọc từ luồng. Lớp ByteArrayInputStream sử dụng một mảng byte làm nguồn. Lớp ByteArrayInputStream có một bộ đếm nội bộ, giữ theo dõi byte tiếp theo sẽ được đọc. Lớp này không hỗ trợ bất kỳ phương thức mới nào, chỉ ghi đè các phương thức của lớp InputStream như read(), skip(), available(), và reset().

Các thuộc tính quan trọng của lớp ByteArrayInputStream:

  • protected byte[] buf: Đây là một mảng byte được cung cấp bởi người tạo luồng.
  • protected int count: Đây là chỉ mục lớn hơn ký tự hợp lệ cuối cùng trong bộ đệm luồng đầu vào.
  • protected int mark: Đây là vị trí hiện tại được đánh dấu trong luồng.
  • protected int pos: Đây là chỉ mục của ký tự tiếp theo sẽ được đọc từ bộ đệm luồng đầu vào.

Các hàm khởi tạo của lớp này bao gồm:

  • ByteArrayInputStream(byte[] b): Tạo một ByteArrayInputStream với một mảng byte b làm nguồn đầu vào.
  • ByteArrayInputStream(byte[] b, int start, int num): Tạo một ByteArrayInputStream với một mảng byte b làm nguồn đầu vào, bắt đầu từ ký tự tại chỉ mục được chỉ định bởi start và có độ dài là num.

Đoạn mã dưới mô tả cách sử dụng lớp ByteArrayInputStream.

java.util.concurrent.Flow.Processor

2

Trong ví dụ này, chương trình tạo một mảng byte từ chuỗi “Hello, World!” và sau đó sử dụng ByteArrayInputStream để đọc từng byte từ mảng và in ra màn hình.

Lớp OutputStream và Các Lớp Con

Lớp OutputStream là một lớp trừu tượng định nghĩa cách mà byte hoặc mảng byte được ghi vào luồng. ByteArrayOutputStream và FileOutputStream là các lớp con của lớp OutputStream.

Các Phương thức trong Lớp OutputStream

Có một số phương thức trong lớp OutputStream được sử dụng để ghi byte dữ liệu vào một luồng. Tất cả các phương thức của lớp này đều ném ra một ngoại lệ IOException.

Một số phương thức của lớp này bao gồm:

  • write(int b): Phương thức này ghi byte đã chỉ định từ số nguyên được đưa vào làm tham số vào một luồng đầu ra. public abstract void write(int b) throws IOException.
  • write(byte[] b): Phương thức này ghi một mảng byte được đưa vào làm tham số vào một luồng đầu ra. Số byte sẽ bằng độ dài của mảng byte. public void write(byte[] b) throws IOException.
  • write(byte[] b, int off, int len): Phương thức này ghi các byte từ một mảng byte được đưa vào làm tham số, bắt đầu từ offset off đến len byte, vào một luồng đầu ra. Số byte được ghi vào luồng sẽ bằng giá trị được chỉ định trong len. public void write(byte[] b, int off, int len) throws IOException.
  • flush(): Phương thức flush() làm trống luồng. Dữ liệu đệm được ghi vào luồng đầu ra. Việc đẩy giúp đẩy dữ liệu đệm để được ghi vào đích đầu ra dự kiến. Nó đảm bảo chỉ có những byte được đệm được chuyển đến hệ điều hành để ghi. Không có đảm bảo rằng các byte sẽ được thực sự ghi vào thiết bị vật lý. public void flush() throws IOException.
  • close(): Phương thức close() đóng luồng đầu ra. Phương thức sẽ giải phóng tất cả các nguồn tài nguyên liên quan đến luồng đầu ra. public void close() throws IOException.

Lớp FileOutputStream

Lớp FileOutputStream tạo ra một OutputStream được sử dụng để ghi byte vào một tệp tin. FileOutputStream có thể hoặc không tạo ra tệp tin trước khi mở nó để ghi, điều này phụ thuộc vào nền tảng cụ thể.

Một số nền tảng chỉ cho phép một đối tượng ghi tệp tin mở một tệp tin để ghi. Do đó, nếu tệp tin đã được mở, các constructor trong lớp này sẽ thất bại (một FileNotFoundException sẽ được ném ra) chỉ khi một tệp tin chỉ được mở để đọc. Các constructor phổ biến của lớp này bao gồm:

  • FileOutputStream(String filename): Phương thức này tạo ra một đối tượng luồng ghi tệp tin đầu ra được sử dụng để ghi byte vào một tệp tin. Ở đây, filename là tên đầy đủ của một tệp tin. public FileOutputStream(String filename) throws FileNotFoundException.
  • FileOutputStream(File name): Phương thức này tạo ra một đối tượng FileOutputStream được sử dụng để ghi byte vào một tệp tin. Ở đây, name là một đối tượng File mô tả tệp tin. public FileOutputStream(File name) throws FileNotFoundException.
  • FileOutputStream(String filename, boolean flag): Phương thức này tạo ra một đối tượng FileOutputStream được sử dụng để ghi byte vào một tệp tin. filename là một đối tượng File. Nếu flag là true, tệp tin sẽ được mở ở chế độ nối (append mode). public FileOutputStream(String filename, boolean flag) throws FileNotFoundException.
  • FileOutputStream(File name, boolean flag): Phương thức này tạo ra một đối tượng FileOutputStream được sử dụng để ghi byte vào một tệp tin. name là một đối tượng File. Nếu flag là true, tệp tin sẽ được mở ở chế độ nối (append mode). public FileOutputStream(File name, boolean flag) throws FileNotFoundException.

Ví dụ FileOutputStream:

java.util.concurrent.Flow.Processor

3

Lớp ByteArrayOutputStream

Lớp ByteArrayOutputStream tạo ra một luồng đầu ra trong đó dữ liệu được ghi bằng cách sử dụng một mảng byte. Nó cho phép mảng đầu ra mở rộng kích thước để chứa dữ liệu mới được ghi.

Lớp ByteArrayOutputStream định nghĩa hai constructor:

  • ByteArrayOutputStream(): Constructor này khởi tạo một đối tượng mới của ByteArrayOutputStream và đặt kích thước của bộ đệm thành kích thước mặc định là 32 byte. public ByteArrayOutputStream().
  • ByteArrayOutputStream(int size): Constructor này khởi tạo một đối tượng mới của ByteArrayOutputStream và đặt kích thước của bộ đệm thành kích thước được chỉ định. public ByteArrayOutputStream(int size).

Các Phương thức trong Lớp ByteArrayOutputStream

Lớp ByteArrayOutputStream kế thừa tất cả các phương thức của lớp OutputStream. Các phương thức của lớp này cho phép truy xuất hoặc chuyển đổi dữ liệu. Các phương thức của lớp này có thể được gọi ngay cả sau khi luồng đầu ra đã được đóng và sẽ không tạo ra IOException.

Một số phương thức trong lớp ByteArrayOutputStream bao gồm:

  • reset(): Phương thức này xóa tất cả các byte đã được ghi cho đến nay bằng cách đặt giá trị về 0. public void reset().
  • size(): Phương thức này trả về số byte đã được ghi vào bộ đệm. public int size().
  • toByteArray(): Phương thức này tạo ra một mảng byte mới được cấp phát chứa các byte đã được ghi vào luồng đến thời điểm hiện tại. public byte[] toByteArray().
  • writeTo(OutputStream out): Phương thức writeTo(OutputStream out) ghi tất cả các byte đã được ghi vào luồng từ bộ đệm nội bộ vào luồng đầu ra được chỉ định. public void writeTo(OutputStream out) throws IOException.
  • toString(): Phương thức toString() chuyển đổi nội dung của mảng byte thành một chuỗi. Phương thức này chuyển đổi các byte thành các ký tự theo bảng mã ký tự mặc định của nền tảng. public String toString().

Ví dụ dưới mô tả việc sử dụng lớp ByteArrayOutputStream.

java.util.concurrent.Flow.Processor

4

Lọc luồng (Filter Stream)

Lớp FilterInputStream cung cấp chức năng bổ sung bằng cách sử dụng một luồng đầu vào làm nguồn dữ liệu cơ bản của nó. Lớp FilterOutputStream tạo luồng trên các luồng đầu ra hiện tại. Chúng có thể biến đổi dữ liệu trên đường đi hoặc cung cấp chức năng bổ sung.

Lớp FilterInputStream

Nó cũng có thể biến đổi dữ liệu trên đường đi. Lớp này ghi đè tất cả các phương thức của lớp InputStream để chuyển tất cả các yêu cầu đến luồng đầu vào chứa. Các lớp con cũng có thể ghi đè một số phương thức và có thể cung cấp các phương thức và trường bổ sung.

Dưới đây là các trường và constructor cho lớp java.io.FilterInputStream:

  • protected InputStream in: Luồng đầu vào này phải được lọc.
  • protected FilterInputStream(InputStream in): Tạo một FilterInputStream. Đối số được gán cho trường in và có thể được gọi lại bất kỳ lúc nào.

Dưới đây là các phương thức của lớp này:

  • mark(int readlimit): Phương thức này xác định vị trí hiện tại trong luồng đầu vào. void mark(int readlimit).
  • markSupported(): Phương thức này kiểm tra xem luồng đầu vào có hỗ trợ các phương thức mark và reset hay không. boolean markSupported().
  • read(): Phương thức này đọc byte tiếp theo từ luồng đầu vào. int read().
  • available(): Phương thức này trả về một ước lượng về số byte có thể được đọc hoặc bỏ qua từ luồng đầu vào. int available().
  • close(): Phương thức này đóng luồng đầu vào và giải phóng bất kỳ tài nguyên hệ thống liên quan đến luồng. void close().
  • read(byte[] b): Phương thức này đọc byte.length byte dữ liệu từ luồng đầu vào vào một mảng byte. int read(byte[] b).
  • reset(): Phương thức này đặt lại con trỏ đến vị trí trong luồng khi phương thức mark được gọi lần cuối trên luồng đầu vào. void reset().
  • skip(long n): Phương thức này bỏ qua và loại bỏ n byte dữ liệu từ luồng đầu vào. long skip(long n).
  • read(byte[] b, int off, int len): Phương thức này đọc len byte dữ liệu từ luồng đầu vào vào một mảng byte, bắt đầu từ vị trí đã chỉ định bởi off. int read(byte[] b, int off, int len).

Ví dụ sử dụng lớp FilterInputStream:

java.util.concurrent.Flow.Processor

5

Lớp FilterOutputStream

Lớp FilterOutputStream ghi đè tất cả các phương thức của lớp OutputStream mà chuyển tất cả các yêu cầu đến luồng đầu ra cơ bản. Các lớp con của FilterOutputStream cũng có thể ghi đè một số phương thức và cung cấp các phương thức và trường bổ sung.

Lớp java.io.FilterOutputStream bao gồm trường protected OutputStream out, đây là luồng đầu ra cần được lọc. FilterOutputStream (OutputStream out) là constructor của lớp này. Nó tạo ra một luồng đầu ra bộ lọc tồn tại qua luồng đầu ra đã được xác định.

Ví dụ sử dụng lớp FilterOutputStream:

java.util.concurrent.Flow.Processor

6

Luồng đệm (Buffered Stream)

Bộ đệm là một khu vực lưu trữ tạm thời cho dữ liệu. Bằng cách lưu trữ dữ liệu trong bộ đệm, thời gian được tiết kiệm vì dữ liệu được nhận ngay từ bộ đệm thay vì quay lại nguồn gốc của dữ liệu.

Trong Java, sử dụng đầu vào và đầu ra đệm để tạm thời lưu trữ dữ liệu được đọc từ hoặc được ghi vào một luồng. Điều này giúp chương trình đọc hoặc ghi lượng dữ liệu nhỏ mà không ảnh hưởng xấu đến hiệu suất của hệ thống. Bộ đệm cho phép bỏ qua, đánh dấu và thiết lập lại luồng.

Bộ lọc hoạt động trên bộ đệm, nằm giữa chương trình và đích của luồng được đệm.

Lớp BufferedInputStream

Lớp BufferedInputStream cho phép người lập trình bọc bất kỳ lớp InputStream nào thành một luồng được đệm. BufferedInputStream hoạt động như một bộ nhớ đệm cho đầu vào bằng cách tạo ra mảng byte được sử dụng cho việc đọc trong tương lai. Cách đơn giản nhất để đọc dữ liệu từ một đối tượng của lớp BufferedInputStream là gọi phương thức read() của nó. Lớp BufferedInputStream cũng hỗ trợ các phương thức mark() và reset().

Phương thức markSupported() sẽ trả về true nếu nó được hỗ trợ.

Lớp BufferedInputStream định nghĩa hai constructor:

  • BufferedInputStream(InputStream in): Constructor này tạo một luồng đầu vào được đệm cho một đối tượng InputStream cụ thể. Kích thước mặc định của bộ đệm là 2048 byte.

java.util.concurrent.Flow.Processor

7

  • BufferedInputStream(InputStream in, int size): Constructor này tạo một luồng đầu vào được đệm với kích thước cụ thể cho đối tượng InputStream đã chỉ định.

java.util.concurrent.Flow.Processor

8

Một số phương thức của lớp này được liệt kê trong bảng dưới

Phương thứcMô tảint available()Phương thức trả về số byte đầu vào có sẵn để đọc.void mark(int readlimit)Phương thức đặt một đánh dấu tại vị trí hiện tại trong luồng đầu vào.int read()Phương thức đọc dữ liệu từ luồng đầu vào cơ bản. Nó ném một ngoại lệ nếu có lỗi I/O.int read(byte[] b)Phương thức đọc byte vào mảng byte được chỉ định từ vị trí bắt đầu. Nó ném ngoại lệ I/O nếu có lỗi.void reset()Phương thức đặt lại con trỏ trong luồng đến điểm mà phương thức mark được gọi lần cuối.

Ví dụ:

java.util.concurrent.Flow.Processor

9

Lớp BufferedOutputStream

BufferedOutputStream tạo ra một bộ đệm được sử dụng cho một luồng đầu ra. Nó cung cấp cùng lợi ích về hiệu suất như BufferedInputStream. Khái niệm chính vẫn giống nhau, tức là thay vì mỗi lần đi đến hệ điều hành để ghi một byte, nó được lưu vào bộ đệm. Nó giống như OutputStream, ngoại trừ việc phương thức flush() đảm bảo rằng dữ liệu trong bộ đệm được ghi vào thiết bị đầu ra vật lý thực sự.

Các constructor của lớp này như sau:

  • BufferedOutputStream(OutputStream os): Constructor này tạo ra một luồng đầu ra được đệm cho đối tượng OutputStream cụ thể với kích thước mặc định là 512 byte.

java.util.concurrent.SubmissionPublisher

0

  • BufferedOutputStream(OutputStream os, int size): Constructor này tạo ra một luồng đầu ra được đệm với kích thước cụ thể cho đối tượng OutputStream đã chỉ định.

java.util.concurrent.SubmissionPublisher

1

Bảng dưới liệt kê các phương thức của lớp BufferedOutputStream.

Phương thứcMô tảvoid flush()Phương thức này đẩy bộ đệm của luồng đầu ra để đảm bảo dữ liệu được ghi vào thiết bị đầu ra thực tế.

Ví dụ:

java.util.concurrent.SubmissionPublisher

2

Luồng ký tự (Character Streams)

Các lớp luồng byte cung cấp các phương thức để xử lý bất kỳ loại thao tác I/O nào ngoại trừ ký tự Unicode. Luồng ký tự cung cấp chức năng để xử lý các thao tác đầu vào/đầu ra dựa trên ký tự. Chúng hỗ trợ ký tự Unicode và có thể được quốc tế hóa.

Reader và Writer là các lớp trừu tượng ở đầu của thứ bậc lớp mà hỗ trợ đọc và viết các luồng ký tự Unicode. Tất cả các lớp luồng ký tự được xuất phát từ Reader và Writer.

Hình dưới mô tả các lớp luồng ký tự

So sánh size của 2 file txt trong java năm 2024

Các Lớp Reader

Lớp Reader là một lớp trừu tượng được sử dụng để đọc các luồng ký tự. Các lớp con của lớp này ghi đè một số phương thức trong lớp này để tăng hiệu suất và chức năng của chúng. Tất cả các phương thức của lớp này đều ném một ngoại lệ IOException. Phương thức read() trả về -1 khi gặp cuối tệp.

Có hai constructor cho lớp Reader. Chúng là như sau:

  • Reader(): Constructor này tạo ra một đọc ký tự và đồng bộ hóa độc giả và phần quan trọng của độc giả mới.

java.util.concurrent.SubmissionPublisher

3

  • Reader(Object lock): Constructor này tạo ra một đọc ký tự và đồng bộ hóa độc giả mới với đối tượng được chỉ định.

java.util.concurrent.SubmissionPublisher

4

Bảng dưới liệt kê một số phương thức của lớp Reader.

Phương thứcMô tảint read()Phương thức đọc một ký tự duy nhất.int read(char[] buffer, int offset, int count)Phương thức đọc ký tự vào một phần của mảng và trả về số ký tự đã đọc.int read(char[] buffer)Phương thức đọc ký tự vào một mảng và trả về số lượng ký tự đã đọc.long skip(long count)Phương thức bỏ qua một số lượng ký tự cụ thể.boolean ready()Phương thức trả về true nếu độc giả đã sẵn sàng để đọc.void close()Phương thức đóng luồng đầu vào và giải phóng tài nguyên hệ thống.boolean markSupported()Phương thức thông báo xem luồng có hỗ trợ phương thức mark() không.void mark(int readAheadLimit)Phương thức đánh dấu vị trí hiện tại trong luồng.void reset()Phương thức đặt lại luồng.

Các Lớp Writer

Lớp Writer là một lớp trừu tượng và hỗ trợ việc viết các ký tự vào luồng thông qua các phương thức có thể được ghi đè bởi các lớp con của nó. Các phương thức của lớp java.io.Writer giống như các phương thức của lớp java.io.OutputStream. Tất cả các phương thức của lớp này đều ném một ngoại lệ IOException trong trường hợp có lỗi.

Có hai constructor cho lớp Writer. Chúng là như sau:

  • Writer(): Constructor này tạo ra một bộ viết ký tự mới mà các phần quan trọng của nó sẽ đồng bộ hóa trên bộ viết chính nó.

java.util.concurrent.SubmissionPublisher

5

  • Writer(Object lock): Constructor này tạo ra một bộ viết ký tự mới mà các phần quan trọng của nó sẽ đồng bộ hóa trên đối tượng được chỉ định.

java.util.concurrent.SubmissionPublisher

6

Bảng dưới liệt kê một số phương thức của lớp Writer.

Phương thứcMô tảvoid write(int c)Phương thức viết một ký tự.void write(char[] text)Phương thức viết một mảng đầy đủ các ký tự vào luồng đầu ra.void write(char[] text, int offset, int length)Phương thức viết một phần của một mảng ký tự vào luồng đầu ra, bắt đầu từ vị trí offset. Biến length chỉ định số lượng ký tự cần viết.void write(String s)Phương thức viết một chuỗi vào luồng đầu ra.void write(String s, int offset, int length)Phương thức viết một phần của một chuỗi vào luồng đầu ra, bắt đầu từ vị trí offset. Biến length chỉ định số lượng ký tự cần viết.void flush()Phương thức làm sạch luồng đầu ra để xóa bộ đệm.void close()Phương thức đóng luồng đầu ra.

Lớp PrintWriter

Lớp PrintWriter là một lớp dựa trên ký tự hữu ích cho việc xuất ra màn hình console. Nó thực hiện tất cả các phương thức in của lớp PrintStream và không có phương thức nào để viết các byte nguyên thô. Trong trường hợp đó, một chương trình sử dụng các luồng byte không mã hóa. Lớp PrintWriter khác biệt từ lớp PrintStream vì có thể xử lý đúng nhiều byte và các bộ ký tự khác.

Lớp này ghi đè phương thức write() của lớp Writer với sự khác biệt là không có phương thức nào ném bất kỳ IOException nào. Đầu ra được in kiểm tra lỗi bằng cách sử dụng phương thức checkError().

Lớp PrintWriter cũng hỗ trợ việc in các loại dữ liệu nguyên thủy, mảng ký tự, chuỗi và đối tượng. Nó cung cấp đầu ra được định dạng thông qua các phương thức print() và println(). Phương thức toString() sẽ cho phép in giá trị của các đối tượng. Các constructor cho lớp PrintWriter như sau:

  • PrintWriter(OutputStream out): Constructor này tạo ra một PrintWriter mới từ một OutputStream hiện có. Nó không hỗ trợ tự động giải phóng(xả).

java.util.concurrent.SubmissionPublisher

7

  • PrintWriter(OutputStream out, boolean autoFlush): Constructor này tạo ra một PrintWriter mới từ một OutputStream hiện có. Một giá trị boolean là true sẽ cho phép println() hoặc printf() làm cho bộ đệm đầu ra được giải phóng.

java.util.concurrent.SubmissionPublisher

8

  • PrintWriter(Writer out): Constructor này tạo ra một PrintWriter mới và không cho phép xả tự động.

java.util.concurrent.SubmissionPublisher

9

  • PrintWriter(Writer out, boolean autoFlush): Constructor này tạo ra một PrintWriter mới. Một giá trị boolean là true sẽ cho phép xả tự động của bộ đệm đầu ra.

default Stream takeWhile(Predicate predicate)

0

Ưu điểm chính của các phương thức print() và println() là bất kỳ đối tượng Java hoặc hằng số hoặc biến nào cũng có thể được in bằng cách truyền nó như một đối số. Nếu tùy chọn autoFlush được đặt thành true, thì việc xả tự động sẽ xảy ra khi phương thức println() được gọi. Phương thức print() không tự động xả luồng. Nếu không, cả hai phương thức này đều giống nhau.

Một số phương thức được nạp chồng của lớp này được liệt kê trong bảng

Phương thứcMô tảboolean checkError()Phương thức xả luồng nếu nó mở và kiểm tra trạng thái lỗi.void print(boolean b)Phương thức in giá trị boolean.void print(char c)Phương thức được sử dụng để in một ký tự.void print(char[] s)Phương thức được sử dụng để in một mảng các ký tự.void print(double d)Phương thức in số thực kiểu double.void print(float f)Phương thức in số thực kiểu float.void print(int i)Phương thức được sử dụng để in một số nguyên.void print(long l)Phương thức được sử dụng để in số nguyên dài.void print(Object obj)Phương thức in một đối tượng và gọi phương thức toString() trên đối số.void print(String s)Phương thức in một chuỗi.void println()Phương thức kết thúc dòng hiện tại bằng cách sử dụng dấu phân cách dòng.void println(boolean x)Phương thức in giá trị boolean và sau đó, kết thúc dòng.void flush()Phương thức xả luồng đầu ra để xóa bộ đệm.void close()Phương thức đóng luồng đầu ra.

Lớp PrintWriter thực hiện và ghi đè phương thức trừu tượng write() từ lớp Writer. Sự khác biệt duy nhất là rằng không có phương thức write() nào của lớp PrintWriter ném một IOException vì nó được bắt trong lớp và một cờ lỗi được đặt.

Ví dụ:

default Stream takeWhile(Predicate predicate)

1

Lớp CharArrayReader

Lớp CharArrayReader là một lớp con của lớp Reader. Lớp này sử dụng một mảng ký tự làm nguồn văn bản để đọc. Lớp CharArrayReader có hai constructor và đọc chuỗi ký tự từ một mảng ký tự.

Các constructor của lớp này như sau:

CharArrayReader(char arr[])

Constructor CharArrayReader(char arr[]) tạo một CharArrayReader từ mảng ký tự được chỉ định, arr.

CharArrayReader(char arr[], int start, int num)

Constructor CharArrayReader(char arr[], int start, int num) tạo một CharArrayReader từ một phần của mảng ký tự, bắt đầu từ ký tự được chỉ định bởi chỉ mục start, và có độ dài num ký tự.

Một số phương thức của lớp này được liệt kê trong Bảng dưới

Phương thứcMô tảlong skip(long n)Phương thức bỏ qua n ký tự trước khi đọc.void mark(int num)Phương thức đánh dấu vị trí hiện tại trong luồng.int read()Phương thức đọc một ký tự.int read(char[] cbuf, int off, int len)Phương thức đọc các ký tự vào mảng ký tự đã chỉ định từ vị trí off.void reset()Phương thức đặt lại con trỏ trong luồng đến vị trí mà phương thức mark được gọi cuối cùng hoặc đến đầu luồng nếu nó chưa được đánh dấu.boolean ready()Phương thức được sử dụng để xác nhận xem luồng này có sẵn để đọc không.void close()Phương thức đóng luồng đầu vào.

Ví dụ:

default Stream takeWhile(Predicate predicate)

2

Lớp CharArrayWriter

Lớp CharArrayWriter là một lớp con của lớp Writer. Lớp này sử dụng một mảng ký tự trong đó các ký tự được ghi. Kích thước của mảng mở rộng theo cần. Các phương thức toCharArray(), toString(), và writeTo() có thể được sử dụng để truy xuất dữ liệu. Lớp CharArrayWriter kế thừa các phương thức được cung cấp bởi lớp Writer.

Các constructor của lớp này như sau:

CharArrayWriter()

Constructor CharArrayWriter() tạo một CharArrayWriter với một bộ đệm có kích thước mặc định là 32 ký tự.

CharArrayWriter(int num)

Constructor CharArrayWriter(int num) tạo một CharArrayWriter với một bộ đệm có kích thước được chỉ định bởi biến num.

Một số phương thức của lớp này được liệt kê trong Bảng dưới

Phương thứcMô tảvoid close()Phương thức đóng luồng.void flush()Phương thức xả luồng.void write(char c)Phương thức ghi một ký tự vào mảng.void write(char[] cbuf, int off, int length)Phương thức ghi các ký tự vào bộ đệm.void reset()Phương thức đặt lại con trỏ trong bộ đệm đến vị trí mà phương thức mark được gọi cuối cùng hoặc đến đầu bộ đệm nếu nó chưa được đánh dấu.int size()Phương thức trả về kích thước hiện tại của bộ đệm.char[] toCharArray()Phương thức trả về một bản sao của dữ liệu.String toString()Phương thức được sử dụng để chuyển đổi dữ liệu đầu vào thành chuỗi.void writeTo(Writer out)Phương thức được sử dụng để ghi nội dung của bộ đệm vào một luồng ký tự.

Ví dụ:

default Stream takeWhile(Predicate predicate)

3

Ví dụ 2:

default Stream takeWhile(Predicate predicate)

4

Serialization (Tuần tự hóa)

Sự bền vững (persistence) là quá trình lưu trữ dữ liệu vào một bộ nhớ lưu trữ cố định. Một đối tượng bền vững có thể được lưu trữ trên đĩa hoặc gửi đến máy khác để lưu trữ dữ liệu của nó. Ngược lại, một đối tượng không bền vững tồn tại miễn là JVM đang chạy. Java là một ngôn ngữ hướng đối tượng và do đó cung cấp các tiện ích để đọc và viết đối tượng. Serialization là quá trình đọc và viết đối tượng vào một luồng byte.

Một đối tượng triển khai giao diện Serializable sẽ lưu trạng thái của nó và khôi phục lại bằng cách sử dụng các tiện ích serialization và deserialization. Khi một lớp hoặc lớp cha của đối tượng Java thực hiện giao diện java.io.Serializable hoặc là subinterface của nó, java.io.Externalizable, đối tượng Java trở nên có thể tuần tự hóa. Giao diện java.io.Serializable không định nghĩa bất kỳ phương thức nào. Nó chỉ cho biết rằng lớp nên được xem xét để tuần tự hóa.

Nếu một lớp cha có thể tuần tự hóa, thì các lớp con của nó cũng có thể tuần tự hóa. Ngoại trừ duy nhất khi một biến là transient và static; trạng thái của nó không thể được lưu trữ bằng các tiện ích serialization. Khi dạng tuần tự của một đối tượng được chuyển đổi trở lại thành một bản sao của đối tượng, quá trình này được gọi là deserialization.

Khi một đối tượng được tuần tự hóa, tệp lớp không được ghi lại. Tuy nhiên, thông tin xác định lớp của nó được ghi lại trong luồng tuần tự hóa. Hệ thống deserialization chỉ định cách định vị và tải các tệp lớp cần thiết. Ví dụ, một ứng dụng Java có thể tải định nghĩa lớp bằng cách sử dụng thông tin được lưu trữ trong thư mục.

Việc tuần tự hóa là bắt buộc để triển khai Phương thức Gọi Phương thức từ xa (RMI), nơi một đối tượng Java trên một máy có thể gọi phương thức của một đối tượng khác có mặt trên một máy khác. Trong cuộc gọi phương thức từ xa này, máy nguồn có thể tuần tự hóa đối tượng và truyền nó, trong khi máy nhận sẽ deserialization đối tượng.

Nếu nhà cung cấp dịch vụ cơ sở hạ tầng hỗ trợ, một đối tượng có thể tuần tự hóa được lưu trữ trong thư mục.

Một ngoại lệ, NotSerializableException, được ném khi một trường có tham chiếu đối tượng chưa triển khai java.io.Serializable. Các trường được đánh dấu bằng từ khóa transient không nên được tuần tự hóa. Giá trị được lưu trữ trong các trường static không được tuần tự hóa. Khi một đối tượng được deserialization, các giá trị trong các trường static được đặt thành các giá trị được khai báo trong lớp và các giá trị trong các trường transient không phải static được đặt thành giá trị mặc định của chúng.

Một số thể hiện của lớp serialVersionUID được liên kết với một lớp có thể tuần tự hóa khi nó không rõ ràng khai báo số phiên bản. Số phiên bản được tính toán dựa trên các khía cạnh khác nhau của lớp. Một lớp có thể tuần tự hóa có thể khai báo số phiên bản của chính nó bằng cách khai báo một trường có tên là serialVersionUID của kiểu static, long và final.

Lớp ObjectOutputStream

Lớp ObjectOutputStream mở rộng từ lớp OutputStream và triển khai giao diện ObjectOutput. Nó ghi các loại dữ liệu nguyên thủy và đối tượng vào luồng đầu ra.

Các hàm khởi tạo của lớp này như sau:

ObjectOutputStream()

Hàm khởi tạo ObjectOutputStream() ngăn chặn các lớp con mà hoàn toàn cài đặt ObjectOutputStream từ cấp phát dữ liệu riêng tư chỉ được sử dụng bởi cài đặt này của ObjectOutputStream.

Chữ ký của nó như sau:

default Stream takeWhile(Predicate predicate)

5

ObjectOutputStream(OutputStream out)

Hàm tạo ObjectOutputStream(OutputStream out) tạo ra một ObjectOutputStream ghi vào OutputStream được chỉ định.

Chữ ký của nó như sau:

default Stream takeWhile(Predicate predicate)

6

Các Phương Thức trong Lớp ObjectOutputStream

Các phương thức trong lớp ObjectOutputStream giúp ghi đối tượng vào luồng đầu ra. Các phương thức trong lớp ObjectOutputStream bao gồm:

default Stream takeWhile(Predicate predicate)

7

Phương thức writeFloat(float value) ghi giá trị kiểu float vào luồng đầu ra.

Chữ ký của nó như sau:

default Stream takeWhile(Predicate predicate)

8

default Stream takeWhile(Predicate predicate)

9

Phương thức writeObject(Object obj) ghi một đối tượng obj vào luồng đầu ra.

Chữ ký của nó như sau:

public static final PrintStream out;

00

public static final PrintStream out;

01

Phương thức defaultWriteObject() ghi các trường không phải là static và không phải là transient vào luồng đầu ra.

Chữ ký của nó như sau:

public static final PrintStream out;

02

Ví dụ:

public static final PrintStream out;

03

Lớp ObjectInputStream

Lớp ObjectInputStream mở rộng lớp InputStream và triển khai giao diện ObjectInput. Giao diện ObjectInput mở rộng giao diện DataInput và có các phương thức hỗ trợ việc tuần tự hóa đối tượng. Lớp ObjectInputStream chịu trách nhiệm đọc các đối tượng và kiểu dữ liệu nguyên thủy từ một luồng đầu vào cơ sở. Nó có phương thức readObject() để khôi phục một đối tượng chứa các trường không phải là static và không phải là transient.

Các constructor của lớp này như sau:

ObjectInputStream()

Constructor ObjectInputStream() giúp các lớp con tái hiện lớp ObjectInputStream để tránh phải cấp phát dữ liệu riêng tư được sử dụng bởi việc triển khai của ObjectInputStream. Chữ ký của nó như sau:

public static final PrintStream out;

04

ObjectInputStream(InputStream in)

Constructor ObjectInputStream(InputStream in) tạo ra một ObjectInputStream đọc từ InputStream đã chỉ định. Các đối tượng được tuần tự hóa được đọc từ luồng đầu vào in. Chữ ký của nó như sau:

public static final PrintStream out;

05

Các Phương thức trong Lớp ObjectInputStream

Các phương thức trong lớp ObjectInputStream giúp đọc đối tượng từ luồng. Một số phương thức trong lớp ObjectInputStream là như sau:

readFloat()

Phương thức readFloat() đọc và trả về một số thực từ luồng đầu vào. Chữ ký của nó như sau:

public static final PrintStream out;

06

readBoolean()

Phương thức readBoolean() đọc và trả về một giá trị boolean từ luồng đầu vào. Chữ ký của nó như sau:

public static final PrintStream out;

07

readByte()

Phương thức readByte() đọc và trả về một byte từ luồng đầu vào. Chữ ký của nó như sau:

public static final PrintStream out;

08

readChar()

Phương thức readChar() đọc và trả về một ký tự từ luồng đầu vào. Chữ ký của nó như sau:

public static final PrintStream out;

09

readObject()

Phương thức readObject() đọc và trả về một đối tượng từ luồng đầu vào. Chữ ký của nó như sau:

public static final PrintStream out;

10

Ví dụ:

public static final PrintStream out;

11

Lớp Console

Java cung cấp lớp Console để cải thiện và đơn giản hóa quá trình phát triển các ứng dụng dòng lệnh. Lớp Console là một phần của gói java.io và có khả năng đọc văn bản từ terminal mà không hiển thị nó trên màn hình. Đối tượng Console cung cấp đầu vào và đầu ra của các luồng ký tự thông qua các lớp Reader và Writer của nó.

Lớp Console cung cấp các phương thức khác nhau để truy cập thiết bị dòng lệnh dựa trên ký tự. Không có hàm tạo công khai cho lớp Console. Để có một thể hiện của lớp Console, bạn cần gọi phương thức System.console(). Phương thức System.console() trả về đối tượng Console nếu nó khả dụng; nếu không, nó trả về null. Hiện tại, các phương thức của lớp Console chỉ có thể được gọi từ dòng lệnh và không thể từ Môi trường Phát triển Tích hợp (IDEs) như Eclipse, NetBeans, và như vậy.

Lớp Console cung cấp các phương thức để thực hiện các thao tác đầu vào và đầu ra trên các luồng ký tự. Phương thức readLine() đọc một dòng văn bản từ bảng điều khiển. Phương thức readPassword() đọc mật khẩu từ bảng điều khiển mà không hiển thị trên màn hình. Phương thức trả về một mảng ký tự và không phải là một đối tượng String để cho phép sửa đổi mật khẩu. Mật khẩu được xóa khỏi bộ nhớ khi không còn cần thiết nữa.

Bảng dưới liệt kê các phương thức khác nhau có sẵn trong lớp Console.

Phương thứcMô tảformat(String fmt, Object… args)Phương thức hiển thị dữ liệu được định dạng trên đầu ra của bảng điều khiểnprintf(String fmt, Object… args)Phương thức hiển thị dữ liệu được định dạng trên đầu ra của bảng điều khiển một cách thuận tiện hơnreader()Phương thức trả về một đối tượng java.io.Reader duy nhất liên kết với bảng điều khiểnreadLine()Phương thức chấp nhận một dòng văn bản từ bảng điều khiểnreadLine(String fmt, Object… args)Phương thức cung cấp đầu ra được định dạng và chấp nhận một dòng văn bản từ bảng điều khiển

Ví dụ:

public static final PrintStream out;

12

Các Lớp trong java.util.zip

Java SE 6 đã giới thiệu một số thay đổi trong các tệp JAR và ZIP. Trong các phiên bản trước của các tệp JAR, timestamp (ngày và giờ) của các tệp được giải nén thường được đặt là thời gian hiện tại thay vì thời gian được lưu trữ trong tệp nén. Trong Java SE 6, công cụ JAR đã được cải tiến để timestamp của các tệp được giải nén phù hợp với thời gian lưu trữ. Điều này là cần thiết vì các công cụ giải nén khác phụ thuộc vào thời gian lưu trữ chứ không phải thời gian hiện tại để giải nén các tệp.

Tên tệp ZIP hiện có thể dài hơn 256 ký tự trong các phiên bản gần đây của hệ điều hành Windows.

Sau khi sử dụng các tệp ZIP hàng ngày, các tệp quan trọng nên được lưu trữ và nén để tiết kiệm không gian đĩa quan trọng. Các tệp có thể được nén và giải nén bằng cách sử dụng các tiện ích phổ biến như WinRar và WinZip.

Trong gói java.util.zip, Java cung cấp các lớp có thể nén và giải nén tệp. Bảng 5.11 liệt kê một số lớp trong gói java.util.zip cùng với mô tả của chúng.

Tên LớpMô TảCheckedInputStreamDuy trì checksum của dữ liệu đang được đọcCheckedOutputStreamDuy trì checksum của dữ liệu cần được ghiDeflaterThực hiện việc nén dữ liệuDeflaterInputStreamĐọc dữ liệu nguồn và sau đó nén nó theo định dạng nén ‘deflate’DeflaterOutputStreamĐọc dữ liệu nguồn, nén nó theo định dạng nén ‘deflate’ và sau đó ghi dữ liệu nén vào dòng đầu raInflaterThực hiện việc giải nén dữ liệuInflaterInputStreamĐọc dữ liệu được nén và sau đó giải nén nó theo định dạng nén ‘deflate’InflaterOutputStreamĐọc dữ liệu được nén, giải nén nó theo định dạng nén ‘deflate’ và sau đó ghi dữ liệu giải nén vào dòng đầu raZipInputStreamThực hiện một bộ lọc dòng đầu vào để đọc các tệp trong định dạng tệp ZIP. Hỗ trợ cả các mục được nén và không được nén.ZipOutputStreamĐọc dữ liệu nguồn, nén nó theo định dạng tệp ZIP và ghi dữ liệu vào dòng đầu ra

Ví dụ:

public static final PrintStream out;

13

Lớp Deflater và Inflater

Các lớp Deflater và Inflater là các lớp mở rộng từ lớp Object. Các lớp này được sử dụng để nén và giải nén dữ liệu.

Lớp Deflater

Lớp Deflater nén dữ liệu có sẵn trong một luồng đầu vào. Nó nén dữ liệu bằng cách sử dụng thư viện nén ZLIB.

Constructor của lớp Deflater được sử dụng để tạo các thể hiện của lớp Deflater.

Cú pháp:

public static final PrintStream out;

14

Constructor tạo một thể hiện với mức nén mặc định.

Các Phương thức:

Bảng dưới liệt kê các phương thức khác nhau trong lớp Deflater cùng với mô tả của chúng.

Phương ThứcMô Tảdeflate(byte[] buffer)Điền bộ đệm đầu ra bằng dữ liệu được nén và trả về kích thước thực tế của dữ liệu được nén dưới dạng số nguyên.deflate(byte[] buffer, int offset, int len)Điền bộ đệm đầu ra bằng dữ liệu được nén và trả về kích thước thực tế của dữ liệu được nén dưới dạng số nguyên. Ở đây, buffer là bộ đệm được chỉ định để lưu trữ dữ liệu được nén, offset là vị trí bắt đầu của dữ liệu và len là số byte tối đa của dữ liệu được nén.setInput(byte[] buffer)Đặt dữ liệu đầu vào có sẵn trong bộ đệm để nén.setInput(byte[] buffer, int offset, int len)Đặt dữ liệu đầu vào có sẵn trong bộ đệm để nén. Ở đây, buffer là bộ đệm được chỉ định để lưu trữ các byte dữ liệu đầu vào, offset là vị trí bắt đầu của dữ liệu và len là độ dài của dữ liệu đầu vào.finish()Cho biết rằng quá trình nén nên kết thúc với nội dung hiện tại của bộ đệm đầu vào.end()Đóng máy nén và loại bỏ dữ liệu đầu vào chưa được xử lý.

Ví dụ:

public static final PrintStream out;

15

Lớp Inflater

Lớp Inflater giải nén dữ liệu đã được nén. Lớp này hỗ trợ giải nén bằng cách sử dụng thư viện nén ZLIB.

Cú pháp:

public static final PrintStream out;

16

Constructor tạo một thể hiện với mức nén mặc định.

Bảng dưới liệt kê các phương thức khác nhau trong lớp Inflater cùng với mô tả của chúng.

Phương ThứcMô Tảinflate(byte[] buffer)Điền bộ đệm đầu ra bằng dữ liệu được giải nén và trả về kích thước thực tế của dữ liệu giải nén dưới dạng số nguyên.inflate(byte[] buffer, int offset, int len)Điền bộ đệm đầu ra bằng dữ liệu được giải nén và trả về kích thước thực tế của dữ liệu giải nén dưới dạng số nguyên. Ở đây, buffer là bộ đệm được chỉ định để lưu trữ dữ liệu giải nén, offset là vị trí bắt đầu của dữ liệu và len là số byte tối đa của dữ liệu giải nén.setInput(byte[] buffer)Đặt dữ liệu đầu vào có sẵn trong bộ đệm để giải nén.setInput(byte[] buffer, int offset, int len)Đặt dữ liệu đầu vào có sẵn trong bộ đệm để giải nén. Ở đây, buffer là bộ đệm được chỉ định để lưu trữ các byte dữ liệu đầu vào, offset là vị trí bắt đầu của dữ liệu và len là độ dài của dữ liệu đầu vào.end()Đóng máy giải nén.

Ví dụ:

public static final PrintStream out;

17

Các Lớp DeflaterInputStream và DeflaterOutputStream

Các lớp DeflaterInputStream và DeflaterOutputStream được thừa kế từ các lớp FilterInputStream và FilterOutputStream tương ứng.

Lớp DeflaterInputStream

Lớp DeflaterInputStream đọc dữ liệu nguồn từ một luồng đầu vào và sau đó nén nó theo định dạng nén ‘deflate’. Lớp này cung cấp các constructor và phương thức của riêng mình. Cú pháp cho một số constructor được giải thích dưới đây.

Cú pháp:

public static final PrintStream out;

18

Constructor tạo một luồng đầu vào của byte để đọc dữ liệu nguồn với một máy nén và bộ đệm mặc định.

public static final PrintStream out;

19

Constructor tạo một luồng đầu vào mới với kích thước bộ đệm mặc định và máy nén được chỉ định.

public static final PrintStream out;

20

Constructor tạo một luồng đầu vào mới với kích thước bộ đệm và máy nén được chỉ định.

Bảng dưới liệt kê các phương thức khác nhau có sẵn trong lớp DeflaterInputStream cùng với mô tả của chúng.

Phương ThứcMô Tảread()Trả về một byte dữ liệu đã được nén đọc từ một luồng đầu vào.read(byte[] buffer, int offset, int bufSize)Trả về số byte dữ liệu đã được nén được đọc vào một mảng byte bắt đầu từ vị trí được chỉ định bởi offset và với kích thước bộ đệm là bufSize.close()Đóng luồng đầu vào sau khi đọc dữ liệu nguồn còn lại.markSupported()Trả về giá trị false. Điều này là do luồng đầu vào không hỗ trợ các phương thức mark() và reset().available()Trả về 0 sau khi đã đọc hết EOF. Nếu chưa đọc hết, nó trả về 1.long skip(long n)Bỏ qua và loại bỏ dữ liệu từ luồng đầu vào.

Ví dụ:

public static final PrintStream out;

21

Ví dụ 2:

public static final PrintStream out;

22

Lớp DeflaterOutputStream

Lớp DeflaterOutputStream đọc dữ liệu nguồn, nén nó theo định dạng nén ‘deflate’ và sau đó, viết dữ liệu nén vào một luồng đầu ra được xác định trước đó. Nó cũng làm nhiệm vụ cơ bản cho các loại bộ lọc nén khác, chẳng hạn như GZIPOutputStream.

Cú pháp:

public static final PrintStream out;

23

Constructor tạo một luồng đầu ra của byte để viết dữ liệu nén vào với máy nén và kích thước bộ đệm mặc định.

Bảng dưới liệt kê các phương thức khác nhau có sẵn trong lớp DeflaterOutputStream cùng với mô tả của chúng.

Phương ThứcMô Tảwrite(int buffer)Ghi một byte dữ liệu đã được nén vào luồng đầu ra.write(byte[] buffer, int offset, int bufSize)Ghi một mảng byte dữ liệu đã được nén vào luồng đầu ra. Ở đây, buffer là dữ liệu đầu vào cần được ghi dưới dạng byte, offset là vị trí bắt đầu, và bufSize là kích thước của buffer.deflate()Nén dữ liệu nguồn và sau đó, ghi khối dữ liệu nén tiếp theo vào luồng đầu ra.close()Đóng luồng đầu ra sau khi đã ghi xong dữ liệu nén còn lại.finish()Hoàn thành quá trình viết dữ liệu nén vào luồng đầu ra mà không đóng nó.

Ví dụ:

public static final PrintStream out;

24

Ví dụ 2:

public static final PrintStream out;

25

Lớp InflaterInputStream và InflaterOutputStream

Lớp InflaterInputStream và InflaterOutputStream được kế thừa từ các lớp FilterInputStream và FilterOutputStream tương ứng.

Lớp InflaterInputStream

Lớp InflaterInputStream đọc dữ liệu được nén và giải nén nó trong định dạng nén ‘deflate’.

Cú pháp

public static final PrintStream out;

26

Constructor tạo ra một luồng đầu vào của các byte để đọc dữ liệu được nén với decompressor và kích thước bộ đệm mặc định.

Bảng dưới liệt kê các phương thức khả dụng trong lớp InflaterInputStream cùng với mô tả của chúng.

Phương thức read()Trả về một byte dữ liệu giải nén được đọc từ luồng đầu vào.read(byte[] buffer, int offset, int buffSize)Trả về số byte dữ liệu giải nén được đọc vào một mảng byte từ vị trí bắt đầu được chỉ định bởi offset và kích thước buffSize.

Ví dụ:

public static final PrintStream out;

27

Lớp InflaterOutputStream

Lớp InflaterOutputStream đọc dữ liệu được nén, giải nén dữ liệu được lưu trữ trong định dạng nén ‘deflate’ và sau đó, viết dữ liệu giải nén vào một luồng đầu ra. Lớp này cũng là lớp cơ sở cho lớp giải nén có tên GZIPInputStream.

Lớp InflaterOutputStream cung cấp các phương thức để giải nén các tệp được nén.

Cú pháp

public static final PrintStream out;

28

Constructor tạo một luồng đầu ra của các byte để viết dữ liệu giải nén với decompressor và kích thước bộ đệm mặc định.

Phương thức:

  • close(): Đóng luồng đầu ra sau khi viết xong dữ liệu giải nén còn lại.
  • finish(): Hoàn thành việc viết dữ liệu giải nén vào luồng đầu ra mà không đóng luồng đầu ra cơ bản.

Ví dụ:

public static final PrintStream out;

29

Gói java.nio

API Java New Input/Output (NIO) đã được giới thiệu vào năm 2002 với J2SE 1.4 để tăng cường các nhiệm vụ xử lý đầu vào/đầu ra trong phát triển ứng dụng Java. Mặc dù, nó chưa được sử dụng đến tối đa, Java SE 7 đã giới thiệu thêm API New Input/Output (NIO.2). Java SE 16 tiếp tục hỗ trợ điều này.

Mục tiêu chính cho cả NIO và NIO.2 vẫn giữ nguyên, đó là tăng cường các nhiệm vụ xử lý I/O trong phát triển ứng dụng Java. Sử dụng của chúng có thể giảm thời gian cần thiết cho một số thao tác I/O thông thường,

Lưu ý: Cả NIO và NIO.2 đều rất phức tạp để làm việc.

Cả hai API NIO và NIO.2 đều tiết lộ các điểm nhập hệ thống cấp thấp phụ thuộc vào hệ điều hành (OS). Chúng cũng cung cấp kiểm soát lớn hơn về I/O. Một khía cạnh khác của NIO là sự chú ý đến sự biểu đạt của ứng dụng.

NIO phụ thuộc vào nền tảng và khả năng tăng cường hiệu suất ứng dụng của nó phụ thuộc vào các yếu tố sau:

  • Hệ điều hành cụ thể (OS)
  • JVM cụ thể
  • Đặc điểm lưu trữ lớn
  • Dữ liệu
  • Ngữ cảnh ảo hóa máy chủ

Dưới đây là những tính năng chính của các API NIO:

Bảng mã và Bộ giải mã, Bộ mã hóa liên quan của Chúng: Chúng dịch dữ liệu giữa byte và ký tự Unicode. API bảng mã được định nghĩa trong gói java.nio.charset. Gói charset linh hoạt hơn so với phương thức getBytes(), dễ triển khai hơn và mang lại hiệu suất xuất sắc,

Bộ đệm: Đây là các container cho dữ liệu. Các lớp bộ đệm được định nghĩa trong gói ong NIO, các đối tượng của lớp và được sử dụng bởi tất cả các API NIO.

Các Loại Kênh: Đại diện cho các kết nối với các thực thể có thể thực hiện các hoạt động I/O. Các kênh là các tệp trừu tượng và socket và hỗ trợ I/O không đồng bộ.

Bộ chọn và khóa lựa chọn: Cùng với các kênh có thể chọn, chúng xác định một cơ sở dữ liệu I/O không đồng bộ được nhiều lựa chọn. I/O không đồng bộ dựa trên sự kiện, điều này có nghĩa là có một bộ chọn được định nghĩa cho một kênh I/O và sau đó, quá trình xử lý xảy ra. Khi một sự kiện xảy ra như sự xuất hiện của một đầu vào, trên bộ chọn, bộ chọn sẽ thức dậy và thực thi. Điều này có thể thực hiện bằng một luồng đơn. Các API kênh và bộ chọn được định nghĩa trong gói java.nio.channels.

Lưu ý: Mỗi gói con có gói cung cấp dịch vụ (SPI) riêng giúp mở rộng triển khai mặc định của nền tảng. Nó cũng giúp xây dựng các triển khai thay thế.

Gói java.nio.file và gói java.nio.file.attribute hỗ trợ đầu vào/đầu ra tệp tin. Chúng cũng giúp truy cập hệ thống tệp mặc định.

Hệ Thống Tệp, Đường Dẫn và Tệp Tin

Hệ thống tệp lưu trữ và tổ chức các tệp tin trên phương tiện truyền thông, thường là ổ đĩa cứng. Những tệp tin này có thể dễ dàng được truy xuất. Mỗi tệp tin đều có một đường dẫn thông qua hệ thống tệp.

Hệ Thống Tệp

Thường, các tệp tin được lưu trữ trong một cấu trúc phân cấp, trong đó có một nút gốc. Dưới nút này là các tệp tin và thư mục. Mỗi thư mục có thể chứa các tệp tin và thư mục con, và cứ như vậy. Không có giới hạn về cấu trúc phân cấp. Hệ thống tệp có thể có một hoặc nhiều thư mục gốc. Hệ thống tệp có các đặc điểm khác nhau đối với bộ phân cách đường dẫn.

Trong NIO, các đối tượng của lớp java.nio.file.Path đại diện cho vị trí tương đối hoặc tuyệt đối của một tệp hoặc thư mục.

Đường Dẫn

Mỗi tệp tin được xác định thông qua đường dẫn của nó. Nói cách khác, đường dẫn chỉ định một vị trí duy nhất trong hệ thống tệp. Nó bắt đầu từ nút gốc, Microsoft Windows hỗ trợ nhiều nút gốc. Mỗi nút gốc tương ứng với một ổ đĩa, chẳng hạn như D:. Hệ điều hành Solaris hỗ trợ một nút gốc duy nhất, được biểu thị bằng ký tự gạch chéo, /.

Hệ thống tệp bao gồm các đặc điểm khác nhau đối với bộ phân cách đường dẫn. Ký tự phân cách tên thư mục được gọi là ký tự ngăn cách. Điều này là đặc trưng cho hệ thống tệp. Ví dụ, Microsoft Windows sử dụng dấu gạch chéo () và hệ điều hành Solaris sử dụng dấu gạch chéo xuôi (/).

hình ảnh dưới mô tả cấu trúc thư mục

So sánh size của 2 file txt trong java năm 2024

Dựa trên hình, xem xét những điều sau:

Trong hệ điều hành Solaris, đường dẫn cho tệp dailySalesReport sẽ được biểu thị là /home/user/dailySalesReport. Trong Microsoft Windows, đường dẫn cho dailySalesReport sẽ được biểu thị là C:\home\user\dailySalesReport.

Một đường dẫn có thể là tương đối hoặc tuyệt đối. Một đường dẫn tuyệt đối bao gồm phần tử gốc và danh sách thư mục đầy đủ để định vị tệp tin. Ví dụ, /home/user/dailySalesReport là một đường dẫn tuyệt đối. Trong đó, tất cả thông tin cần để định vị tệp tin đều được bao gồm trong chuỗi đường dẫn.

Một đường dẫn tương đối không bao gồm danh sách thư mục đầy đủ. Ví dụ, user/dailySalesReport. Nó phải được sử dụng với một đường dẫn khác để truy cập một tệp tin. Mà không có thông tin thêm, một chương trình sẽ không thể định vị tệp tin.

Tệp Tin

NIO.2 bao gồm các gói và lớp mới sau:

  • java.nio.file.Path: Sử dụng một đường dẫn phụ thuộc vào hệ thống để định vị một tệp tin hoặc thư mục.
  • java.nio.file.Files: Sử dụng một đối tượng Path để thực hiện các hoạt động trên các tệp tin và thư mục.
  • java.nio.file.FileSystem: Cung cấp một giao diện cho hệ thống tệp tin. Nó cũng giúp tạo ra một đối tượng Path và các đối tượng khác để truy cập hệ thống tệp tin.
  • Lưu ý: Tất cả các phương thức truy cập hệ thống tệp tin đều ném ra IOException hoặc một lớp con của nó.

    Sự khác biệt giữa NIO.2 và java.io.File là cách truy cập hệ thống tệp tin. Trong lớp java.io, các phương thức để điều chỉnh thông tin đường dẫn nằm trong cùng một lớp cũng chứa các phương thức để đọc và ghi tệp tin và thư mục.

    Với NIO.2, hai quá trình đã được tách rời. Trong NIO.2, là giao diện Path giúp tạo và kiểm soát các đường dẫn. Là lớp Files thực hiện các hoạt động trên các tệp tin và thư mục. Lớp Files chỉ hoạt động trên các đối tượng Path. Các phương thức của lớp Files hoạt động trực tiếp trên hệ thống tệp tin sẽ ném IOException.

    Giao Diện Path

    Đối tượng giao diện java.nio.file.Path có thể giúp định vị một tệp tin trong hệ thống tệp tin. Thông thường, giao diện đại diện cho một đường dẫn tệp tin phụ thuộc vào hệ thống. Nói cách khác, nó cung cấp điểm nhập cho việc điều chỉnh tệp tin và thư mục.

    Một đường dẫn là phân cấp. Nó bao gồm một chuỗi các thư mục và tên tệp tin. Những thư mục và tên tệp tin này được phân tách bằng một dấu phân cách. Dưới đây là những đặc điểm của một Path:

    • Có thể có một thành phần gốc. Điều này đại diện cho một hệ thống tệp tin phân cấp.
    • Tên của một tệp tin hoặc thư mục là thành phần tên cách xa nhất từ gốc của cấu trúc thư mục.
    • Các thành phần tên khác bao gồm các tên thư mục.

    Một Path có thể đại diện cho những điều sau:

    • Một gốc
    • Một gốc và một chuỗi tên
    • Một hoặc nhiều thành phần tên

    Một Path là trống nếu nó chỉ bao gồm một thành phần tên trống.

    Lưu ý: Việc truy cập một tệp tin bằng cách sử dụng một đường dẫn trống tương tự như truy cập thư mục mặc định của hệ thống tệp tin.

    Gói java.nio.file cũng cung cấp một lớp trợ giúp có tên là Paths. Lớp này là tĩnh và cuối cùng và có phương thức getDefault().

    Dưới đây là một số phương thức của giao diện Path có thể được nhóm dựa trên chức năng chung:

    • Để truy cập các thành phần đường dẫn hoặc một chuỗi con của các thành phần tên của nó, có thể sử dụng các phương thức getFileName(), getParent(), getRoot(), và subpath().
    • Để kết hợp các đường dẫn, giao diện Path định nghĩa các phương thức resolve() và resolveSibling() có thể được sử dụng.
    • Để xây dựng một đường dẫn tương đối giữa hai đường dẫn, có thể sử dụng phương thức relativize().
    • Để so sánh và kiểm tra các đường dẫn, có thể sử dụng các phương thức startsWith() và endsWith().
      Lưu ý: Một thư mục được đặt tại một đường dẫn có thể được theo dõi dịch vụ và các mục trong thư mục có thể được quan sát.

    Để có được một đối tượng Path, hãy lấy một phiên bản của hệ thống tệp tin mặc định. Tiếp theo, gọi phương thức getPath().

    Ví dụ:

    public static final PrintStream out;

    30

    Đối tượng Path sau khi được tạo ra không thể thay đổi. Nói cách khác, chúng là không thay đổi.

    Đối với các hoạt động trên Path, nếu hệ thống tệp tin mặc định được sử dụng thì cần sử dụng tiện ích Paths. Hệ thống tệp tin mặc định là hệ thống tệp tin mà JVM đang chạy trên đó. Đó là cách ngắn gọn hơn. Đối với các hệ thống tệp tin khác (không phải hệ thống mặc định), hãy lấy một phiên bản của hệ thống tệp tin và xây dựng các đối tượng Path để thực hiện các hoạt động trên Path.

    Dưới đây là một số phương thức phổ biến của lớp Path:

    subpath()

    Một phần của đường dẫn có thể được lấy bằng cách sử dụng phương thức subpath().

    Cú pháp là:

    public static final PrintStream out;

    31

    Ở đây,

    • startIndex: đại diện cho giá trị bắt đầu.
    • endIndex: đại diện cho giá trị kết thúc (index cuối cùng là endIndex – 1).

    Đoạn mã dưới thể hiện cách sử dụng phương thức subpath():

    public static final PrintStream out;

    32

    Trong đoạn mã này, tên phần tử gần nhất với root có giá trị index là 0. Phần tử xa root nhất có giá trị index là index count – 1. Do đó, kết quả của đoạn mã sẽ là Java/Hello.txt.

    resolve()

    Phương thức resolve() được sử dụng để kết hợp hai đường dẫn. Nó chấp nhận một đường dẫn không đầy đủ và nối đường dẫn không đầy đủ này vào đường dẫn gốc. Đoạn mã dưới sử dụng phương thức resolve() để kết hợp hai đường dẫn.

    public static final PrintStream out;

    33

    Kết quả của đoạn mã này sẽ là /java/test/bar.

    Nếu bạn truyền một đường dẫn tuyệt đối cho phương thức resolve(), nó sẽ trả về đường dẫn được truyền. Đoạn mã dưới trả về /java/test:

    public static final PrintStream out;

    34

    relativize()

    Phương thức relativize() giúp xây dựng một đường dẫn từ một vị trí trong hệ thống tệp tin đến một vị trí khác. Đoạn mã dưới minh họa điều này.

    public static final PrintStream out;

    35

    Kết quả sẽ là /sales.

    Lưu ý: Đường dẫn mới là tương đối với đường dẫn gốc. Đường dẫn bắt nguồn từ đường dẫn gốc và kết thúc tại vị trí được xác định bởi đường dẫn được truyền vào.

    Theo dõi Thay Đổi Hệ Thống Tệp và Thư Mục bằng lớp java.nio.file.Files

    Lớp java.nio.file.Files chứa các phương thức tĩnh thực hiện các chức năng chính cho các đối tượng Path. Những phương thức này có thể nhận diện và quản lý các liên kết biểu tượng tự động.

    Dưới đây là một số thao tác quan trọng:

    Sao Chép Một Tệp hoặc Thư Mục:

    Để sao chép một tệp hoặc thư mục, bạn có thể sử dụng phương thức copy(Path, Path, CopyOption…). Cân nhắc những điểm sau khi sao chép:

    • Nếu tệp đích đã tồn tại, quá trình sao chép sẽ thất bại trừ khi có tùy chọn REPLACE_EXISTING.
    • Khi sao chép một thư mục, các tệp bên trong thư mục sẽ không được sao chép.
    • Khi sao chép một liên kết biểu tượng, đích của liên kết sẽ được sao chép. Để chỉ sao chép liên kết, hãy sử dụng tùy chọn NOFOLLOW_LINKS hoặc REPLACE_EXISTING.

    Tùy Chọn Sao Chép:

    • public static final PrintStream out;

      53: Tùy chọn này sao chép các thuộc tính của tệp nguồn sang tệp đích. Các thuộc tính của tệp phụ thuộc vào hệ thống tệp và phụ thuộc vào nền tảng. Tuy nhiên, thời gian sửa đổi cuối cùng được hỗ trợ trên mọi nền tảng và được sao chép sang tệp đích.
    • public static final PrintStream out;

      54: Sử dụng tùy chọn này khi các liên kết biểu tượng không nên được theo dõi. Nó chỉ sao chép liên kết nếu tệp cần sao chép là một liên kết biểu tượng và đích của liên kết không được sao chép.
    • public static final PrintStream out;

      55: Tùy chọn này sao chép tệp ngay cả khi tệp đích đã tồn tại. Nếu đích là một liên kết biểu tượng, liên kết sẽ được sao chép, nhưng đích của liên kết sẽ không được sao chép. Nếu đích là một thư mục không rỗng, quá trình sao chép sẽ thất bại và ném một

      public static final PrintStream out;

      56.
    • Files.copy(InputStream in, Path target, CopyOption… options):
    • Mô tả: Phương thức này sao chép tất cả byte từ một

      public static final PrintStream out;

      52 đến một tệp được chỉ định bởi tham số

      public static final PrintStream out;

      58 (

      public static final PrintStream out;

      59).
    • Tham số:
      • public static final PrintStream out;

        60: Đại diện cho

        public static final PrintStream out;

        52 để đọc từ.
      • public static final PrintStream out;

        59: Đại diện cho đường dẫn đến tệp.
      • public static final PrintStream out;

        63: Chỉ định cách thức sao chép. Đây là tham số tùy chọn, bạn có thể cung cấp một hoặc nhiều giá trị

        public static final PrintStream out;

        64.
    • Ngoại lệ: Phương thức này ném các ngoại lệ như

      public static final PrintStream out;

      65,

      public static final PrintStream out;

      56,

      public static final PrintStream out;

      67,

      public static final PrintStream out;

      68, và

      public static final PrintStream out;

      69. Ví dụ:

    public static final PrintStream out;

    36

    1. Files.copy(Path source, OutputStream out):
    2. Mô tả: Phương thức này sao chép tất cả byte từ một tệp được chỉ định bởi tham số

      public static final PrintStream out;

      58 (

      public static final PrintStream out;

    3. đến một

      public static final PrintStream out;

      72.
    4. Tham số:
      • public static final PrintStream out;

        71: Đại diện cho đường dẫn đến tệp.
      • public static final PrintStream out;

        74: Đại diện cho

        public static final PrintStream out;

        72 mà byte sẽ được ghi vào.
    5. Ngoại lệ: Phương thức này ném

      public static final PrintStream out;

      65 và

      public static final PrintStream out;

      69. Ví dụ:

    public static final PrintStream out;

    37

    Ví dụ:

    public static final PrintStream out;

    38

    Chuyển một tập tin hoặc thư mục

    Để thực hiện việc này, sử dụng phương thức

    public static final PrintStream out;

    78. Nếu tập tin đích tồn tại, tùy chọn

    public static final PrintStream out;

    55 nên được sử dụng. Nếu không, quá trình di chuyển sẽ thất bại. Phương thức này nhận một đối số biến đổi.

    Các thư mục trống có thể được di chuyển. Nếu thư mục không trống, nó có thể được di chuyển mà không di chuyển nội dung.

    Phương thức

    public static final PrintStream out;

    80 hỗ trợ các hằng số liệt kê

    public static final PrintStream out;

    81 sau:

    • public static final PrintStream out;

      55: Thay thế tập tin đích ngay cả khi tập tin đích tồn tại cho một thư mục không trống. Nếu thư mục đích là một liên kết tượng trưng, chỉ có liên kết tượng trưng được thay thế. Thư mục mục tiêu không được thay thế.
    • public static final PrintStream out;

      83: Di chuyển thư mục và tập tin như một hoạt động hệ thống tệp hợp nhất. Sử dụng tùy chọn này để di chuyển một tập tin vào một thư mục. Bất kỳ quy trình nào sau đó quan sát các thư mục này sẽ truy cập một tập tin hoàn chỉnh.

    Chú ý:

    • Ngoại lệ được ném nếu hệ thống tệp không hỗ trợ di chuyển nguyên tử.

    Cú pháp dưới đây thể hiện phương thức

    public static final PrintStream out;

    84.

    public static final PrintStream out;

    39

    Trong đó:

    • public static final PrintStream out;

      71 đại diện cho đường dẫn đến tập tin cần di chuyển.
    • public static final PrintStream out;

      59 đại diện cho đường dẫn đến tập tin đích.
    • public static final PrintStream out;

      63 chỉ định cách di chuyển nên được thực hiện.

    Dưới đây là các hướng dẫn cho việc di chuyển:

    • Nếu đường dẫn đích là một thư mục và thư mục đó trống rỗng, thì việc di chuyển sẽ thành công nếu

      public static final PrintStream out;

      55 được đặt.
    • Nếu thư mục đích không tồn tại, thì quá trình di chuyển sẽ thành công.
    • Nếu thư mục đích tồn tại nhưng không trống, thì sẽ ném ra ngoại lệ

      public static final PrintStream out;

      67.
    • Nếu nguồn là một tập tin, thư mục đích tồn tại và

      public static final PrintStream out;

      55 được đặt, thì quá trình di chuyển sẽ đổi tên tập tin thành tên thư mục mong muốn.

    Ví dụ:

    public static final PrintStream out;

    40

    Kiểm tra một tập tin hoặc thư mục

    Để làm điều này, hệ thống tệp cần được truy cập bằng cách sử dụng các phương thức của

    public static final PrintStream out;

    91 để xác định xem một đường dẫn cụ thể có tồn tại không. Các phương thức trong lớp

    public static final PrintStream out;

    58 hoạt động trên đối tượng

    public static final PrintStream out;

    58.

    Dưới đây là các phương thức của

    public static final PrintStream out;

    91 để kiểm tra sự tồn tại của đối tượng

    public static final PrintStream out;

    58:

    • public static final PrintStream out;

      96: Phương thức này kiểm tra xem tập tin có tồn tại không. Mặc định, nó sử dụng các liên kết tượng trưng.
    • public static final PrintStream out;

      97: Phương thức này kiểm tra xem tập tin có không tồn tại.

      public static final PrintStream out;

      98 không tương đương với

      public static final PrintStream out;

      99. Khi kiểm tra sự tồn tại của một tập tin, có thể có một trong những kết quả sau:
    • Tập tin được xác minh không tồn tại.
    • Tập tin được xác minh tồn tại.
    • Sự tồn tại của tập tin không thể được xác minh. Điều này xảy ra nếu cả

      public static final PrintStream err;

      00 và

      public static final PrintStream err;

      01 đều trả về false.
    • Tình trạng của tập tin là không xác định. Điều này xảy ra khi chương trình không có quyền truy cập vào tập tin.

    Một hệ thống tệp có thể sử dụng hai đường dẫn khác nhau để xác định cùng một tập tin. Điều này xảy ra khi hệ thống tệp sử dụng các liên kết tượng trưng. Phương thức

    public static final PrintStream err;

    02 có thể giúp so sánh hai đường dẫn để kiểm tra xem chúng có trỏ đến cùng một tập tin trên hệ thống tệp hay không.

    Ví dụ:

    public static final PrintStream out;

    41

    Xóa một tập tin hoặc thư mục

    Phương thức

    public static final PrintStream err;

    03 có thể được sử dụng để xóa một tập tin, thư mục hoặc liên kết. Việc xóa sẽ thất bại nếu thư mục không trống. Phương thức ném một ngoại lệ nếu quá trình xóa thất bại. Nếu tập tin không tồn tại, sẽ được ném một

    public static final PrintStream err;

    04. Để xác định lý do thất bại,

    public static final PrintStream out;

    42

    Ví dụ phương thức deleteIfExists()

    public static final PrintStream out;

    43

    Liệt kê nội dung thư mục

    Để làm điều này, sử dụng lớp

    public static final PrintStream err;

    05 để lặp qua tất cả các tập tin và thư mục từ bất kỳ

    public static final PrintStream out;

    58 thư mục nào. Cân nhắc về các điểm sau:

    • public static final PrintStream err;

      07 được ném nếu có lỗi /O trong quá trình lặp qua các mục trong thư mục đã chỉ định.
    • public static final PrintStream err;

      08 được ném khi biểu thức chính quy không hợp lệ.

    Ví dụ:

    public static final PrintStream out;

    44

    Tạo mới thư mục

    public static final PrintStream err;

    09 là phương thức được sử dụng để tạo một thư mục mới.

    Phương thức

    public static final PrintStream err;

    10 có thể được sử dụng để tạo các thư mục từ trên xuống. Đoạn mã dưới minh họa điều này.

    public static final PrintStream out;

    45

    Khi thực thi, nó sẽ tạo ra các thư mục theo thứ tự đã cho:

    public static final PrintStream err;

    11,

    public static final PrintStream err;

    12, và

    public static final PrintStream err;

    13. Thư mục

    public static final PrintStream err;

    12 sẽ được tạo bên trong

    public static final PrintStream err;

    11 và

    public static final PrintStream err;

    13 sẽ được tạo bên trong thư mục

    public static final PrintStream err;

    12.

    Để tạo một tập tin, sử dụng phương thức

    public static final PrintStream err;

    18.

    Đọc và ghi tệp tin

    Để đọc từ tệp tin, sử dụng các phương thức

    public static final PrintStream err;

    19 hoặc

    public static final PrintStream err;

    20 để đọc toàn bộ nội dung của tệp.

    Đoạn mã 46 thể hiện cách sử dụng phương thức

    public static final PrintStream err;

    19:

    public static final PrintStream out;

    46

    Để viết bytes hoặc dòng vào một tệp tin, sử dụng các phương thức sau:

    • public static final PrintStream err;

      22: Phương thức này ghi bytes vào một tệp tin.

    public static final PrintStream out;

    47

    Một số

    public static final PrintStream err;

    23 hỗ trợ bao gồm

    public static final PrintStream err;

    24,

    public static final PrintStream err;

    25,

    public static final PrintStream err;

    26,

    public static final PrintStream err;

    27, và

    public static final PrintStream err;

    28.

    • public static final PrintStream err;

      29: Phương thức này ghi các dòng văn bản vào một tệp tin.

    public static final PrintStream out;

    48

    Cả hai phương thức trên đều ném ra các ngoại lệ như

    public static final PrintStream out;

    65,

    public static final PrintStream out;

    68, và

    public static final PrintStream out;

    69.

    java.nio.file package hỗ trợ I/O theo kiểu channel.

    Ví dụ:

    public static final PrintStream out;

    49

    Đọc tệp tin bằng cách sử dụng Buffered Stream

    Phương thức

    public static final PrintStream err;

    33 mở một tệp tin để đọc. Nó trả về một đối tượng

    public static final PrintStream err;

    34 giúp đọc văn bản từ một tệp tin một cách hiệu quả.

    Ví dụ:

    public static final PrintStream out;

    50

    Ghi tệp tin bằng cách sử dụng Buffered Stream

    Phương thức

    public static final PrintStream err;

    35 có thể được sử dụng để ghi vào một tệp tin bằng cách sử dụng

    public static final PrintStream err;

    36.

    Ví dụ:

    public static final PrintStream out;

    51

    Đọc ghi chuỗi từ tệp tin

    Lớp

    public static final PrintStream err;

    37 được sử dụng để ghi dữ liệu vào các tệp văn bản trong Java. Để đọc dữ liệu từ các tệp văn bản, hãy sử dụng

    public static final PrintStream err;

    38. Cả hai lớp này đều thuộc về các lớp dòng ký tự.

    public static final PrintStream err;

    39 và

    public static final PrintStream err;

    40 không nên được sử dụng để đọc/ghi dữ liệu văn bản vì chúng là các lớp dòng byte không phù hợp cho các hoạt động dựa trên ký tự.

    FileWriter

    Các Constructor của

    public static final PrintStream err;

    37:

    1. FileWriter(File file): Xây dựng một đối tượng

      public static final PrintStream err;

      37 cho một đối tượng tệp cụ thể.
    2. FileWriter(File file, boolean append): Xây dựng một đối tượng

      public static final PrintStream err;

      37 cho một đối tượng tệp cụ thể, với giá trị boolean chỉ định liệu có nối dữ liệu hay không.
    3. FileWriter(FileDescriptor fd): Xây dựng một đối tượng

      public static final PrintStream err;

      37 liên kết với một bộ mô tả tệp cụ thể.
    4. FileWriter(String fileName): Xây dựng một đối tượng

      public static final PrintStream err;

      37 cho một tên tệp cụ thể.
    5. FileWriter(String fileName, boolean append): Xây dựng một đối tượng

      public static final PrintStream err;

      37 cho một tên tệp cụ thể, với giá trị boolean chỉ định liệu có nối dữ liệu hay không.

    Các Phương thức của FileWriter:

    1. public void write(int c) throws IOException: Sử dụng để ghi một ký tự duy nhất.
    2. public void write(char[] cbuf) throws IOException: Sử dụng để ghi một mảng ký tự.
    3. public void write(String str) throws IOException: Sử dụng để ghi dữ liệu của một chuỗi.
    4. public void write(String str, int off, int len) throws IOException: Sử dụng để ghi một phần của một chuỗi.
    5. public void flush() throws IOException: Sử dụng để làm rỗng luồng.
    6. public void close() throws IOException: Sử dụng để đóng người ghi sau khi làm rỗng.

    public static final PrintStream err;

    37 ghi một ký tự mỗi lần và tương tự, đọc mỗi ký tự một lần dẫn đến sự tăng của các quy trình I/O. Do đó, nó ảnh hưởng đến hoạt động của hệ thống. Sử dụng

    public static final PrintStream err;

    36 với

    public static final PrintStream err;

    37 tăng tốc độ thực thi.

    FileReader

    public static final PrintStream err;

    38 đọc từng ký tự từ một tệp văn bản:

    • public static final PrintStream err;

      38 được kế thừa từ lớp

      public static final PrintStream err;

      52.
    • public static final PrintStream err;

      38 giả định rằng bảng mã mặc định và kích thước bộ đệm byte là phù hợp. Bạn có thể chỉ định các giá trị này bằng cách xây dựng một

      public static final PrintStream err;

      52 qua một

      public static final PrintStream out;

      52.
    • public static final PrintStream err;

      38 được sử dụng để đọc luồng ký tự, trong khi

      public static final PrintStream err;

      39 đọc luồng dữ liệu byte thô.

    Các Constructor của FileReader:

    1. FileReader(File file): Sử dụng để tạo

      public static final PrintStream err;

      38 cho tệp đã cho để đọc.
    2. FileReader(FileDescriptor fd): Sử dụng để tạo

      public static final PrintStream err;

      38 mới cho bộ mô tả tệp đã cho.
    3. FileReader(String fileName): Sử dụng để tạo

      public static final PrintStream err;

      38 mới cho tên tệp đã cho.

    Các Phương thức của

    public static final PrintStream err;

    38:

    1. public int read() throws IOException: Sử dụng để đọc một ký tự duy nhất, chặn cho đến khi có một ký tự có sẵn, có lỗi I/O xảy ra hoặc nó đến cuối luồng.
    2. public int read(char[] cbuf) throws IOException: Đọc ký tự vào một mảng, chặn cho đến khi đầu vào có sẵn, có lỗi I/O xảy ra, hoặc nó tìm thấy cuối luồng.
    3. public abstract int read(char[] buff, int off, int len) throws IOException: Đọc ký tự vào một phần của một mảng, chặn cho đến khi đầu vào có sẵn, có lỗi I/O xảy ra, hoặc nó gần cuối luồng.

    Các tham số cho các phương thức

    public static final PrintStream err;

    38 bao gồm:

    • cbuf (bộ đệm đích)
    • off (điểm bắt đầu để lưu trữ ký tự)
    • len (số ký tự tối đa để đọc).

    Ngoài ra, phương thức

    public static final PrintStream err;

    63 được sử dụng để đóng người đọc, và phương thức

    public static final PrintStream err;

    64 được sử dụng để bỏ qua các ký tự, chặn cho đến khi có một ký tự có sẵn, có lỗi I/O xảy ra, hoặc nó gần cuối