Lớp ByteArrayInputStream
(Class ByteArrayInputStream)
Lớp ByteArrayInputStream trong Java là một phần của gói java.io và được sử dụng để đọc dữ liệu từ một mảng byte (byte array) trong bộ nhớ như thể nó là một input stream. Điều này rất hữu ích khi bạn muốn xử lý dữ liệu mà bạn đã lưu trữ trong một mảng byte mà không cần phải truy cập đến hệ thống tệp.
Lớp ByteArrayInputStream chứa một bộ nhớ đệm nội bộ chứa các byte có thể được đọc từ luồng. Bộ nhớ đệm của ByteArrayInputStream không tự động tăng theo kích thước dữ liệu. Nó sử dụng một mảng byte cố định do bạn cung cấp khi khởi tạo, và không thể tự động mở rộng kích thước.
Đặc điểm chính của lớp ByteArrayInputStream
↳ Nguồn dữ liệu trong bộ nhớ: ByteArrayInputStream không đọc dữ liệu từ file hoặc thiết bị bên ngoài, mà đọc trực tiếp từ một mảng byte đã được cung cấp.
↳ Không cần đóng luồng: Vì ByteArrayInputStream làm việc với dữ liệu trong bộ nhớ, không có tài nguyên hệ thống nào cần được giải phóng. Do đó, bạn không cần gọi phương thức close() khi sử dụng ByteArrayInputStream.
Khai báo lớp ByteArrayInputStream trong Java
Để sử dụng lớp ByteArrayInputStream, bạn cần import gói java.io bạn cần thêm câu lệnh import vào đầu file Java của mình. Gói này cung cấp các lớp và giao diện để thực hiện các hoạt động nhập xuất (I/O) trong Java.
Cú pháp câu lệnh import:
Cú pháp
import java.io.ByteArrayInputStream;
Cú pháp khai báo lớp ByteArrayInputStream:
Cú pháp
public class ByteArrayInputStream extends InputStream
Dưới đây là giải thích chi tiết về cú pháp khai báo này:
↳ public class ByteArrayInputStream: Đây là khai báo một lớp công khai (public) tên là ByteArrayInputStream. Lớp này có thể được truy cập từ bất kỳ đâu trong dự án Java, miễn là nó được import hoặc ở cùng gói.
↳ extends InputStream: Lớp ByteArrayInputStream kế thừa từ lớp InputStream. Điều này có nghĩa là ByteArrayInputStream là một lớp con của InputStream và kế thừa tất cả các phương thức và thuộc tính của InputStream.
Các trường (fields) của lớp ByteArrayInputStream
Các trường này là các thành viên nội bộ của lớp ByteArrayInputStream và được sử dụng để quản lý dữ liệu và trạng thái của luồng. Dưới đây là tóm tắt các trường thức chính của lớp ByteArrayInputStream:
↳ protected byte[] buf: Một mảng byte được cung cấp bởi người tạo luồng.
↳ protected int count: Chỉ số lớn hơn một so với ký tự cuối cùng hợp lệ trong bộ đệm luồng đầu vào.
↳ protected int mark: Vị trí được đánh dấu hiện tại trong luồng.
↳ protected int pos: Chỉ số của ký tự tiếp theo để đọc từ bộ đệm luồng đầu vào.
Các constructor của lớp ByteArrayInputStream
Lớp ByteArrayInputStream có hai constructor chính để tạo đối tượng:
↳ ByteArrayInputStream(byte[] buf): Tạo một đối tượng ByteArrayInputStream sử dụng mảng byte buf làm bộ đệm.
↳ ByteArrayInputStream(byte[] buf, int offset, int length): Tạo một đối tượng ByteArrayInputStream sử dụng một phần của mảng byte buf làm bộ đệm, bắt đầu từ vị trí offset và có độ dài length.
Các phương thức của lớp ByteArrayInputStream
Các phương thức này cung cấp các cách khác nhau để tương tác với dữ liệu trong ByteArrayInputStream. Bạn có thể đọc từng byte, đọc một khối byte, kiểm tra số lượng byte còn lại, đánh dấu và đặt lại vị trí trong luồng, và bỏ qua một số byte. Dưới đây là tóm tắt các phương thức chính của lớp ByteArrayInputStream:
↳ int available(): Trả về số lượng byte còn lại có thể đọc (hoặc bỏ qua) từ luồng đầu vào này.
↳ void close(): Đóng một ByteArrayInputStream không có tác dụng.
↳ void mark(int readAheadLimit): Đặt vị trí đánh dấu hiện tại trong luồng.
↳ boolean markSupported(): Kiểm tra xem luồng đầu vào này có hỗ trợ đánh dấu/đặt lại hay không.
↳ int read(): Đọc byte dữ liệu tiếp theo từ luồng đầu vào này.
↳ int read(byte[] b, int off, int len): Đọc tối đa len byte dữ liệu vào một mảng byte từ luồng đầu vào này.
↳ void reset(): Đặt lại bộ đệm về vị trí được đánh dấu.
↳ long skip(long n): Bỏ qua n byte đầu vào từ luồng đầu vào này.
Ví dụ 1
Dưới đây là một ví dụ đơn giản về cách sử dụng lớp ByteArrayInputStream trong Java:
Ví dụ: Example.java
import java.io.ByteArrayInputStream;
import java.io.IOException;
public class Example {
public static void main(String[] args) {
// Tạo một mảng byte với dữ liệu mẫu
byte[] byteArray = { 72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100 };
// Tạo một ByteArrayInputStream từ mảng byte
try (ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArray)) {
int data;
// Đọc từng byte dữ liệu từ ByteArrayInputStream cho đến khi kết thúc (giá trị -1)
while ((data = byteArrayInputStream.read()) != -1) {
// Chuyển byte dữ liệu thành ký tự và in ra màn hình
System.out.print((char) data);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
Kết quả của chương trình là:
Trong ví dụ này, ByteArrayInputStream được sử dụng để đọc dữ liệu từ một mảng byte thay vì từ một file hoặc thiết bị khác.
Ví dụ 2
Dưới đây là một ví dụ về cách sử dụng lớp ByteArrayInputStream để đọc các ký tự đặc biệt:
Ví dụ: Example.java
import java.io.ByteArrayInputStream;
import java.io.IOException;
public class Example {
public static void main(String[] args) {
// Tạo một mảng byte với các ký tự đặc biệt
byte[] byteArray = { 33, 64, 35, 36, 37 }; // !@#$%^&*()
// Tạo một ByteArrayInputStream từ mảng byte
try (ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArray)) {
int data;
// Đọc từng byte dữ liệu từ ByteArrayInputStream cho đến khi kết thúc (giá trị -1)
while ((data = byteArrayInputStream.read()) != -1) {
// Chuyển byte dữ liệu thành ký tự và in ra màn hình
System.out.print((char) data);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
Kết quả của chương trình là:
Trong ví dụ này, ByteArrayInputStream được sử dụng để đọc và hiển thị các ký tự đặc biệt từ một mảng byte. Mỗi byte trong mảng đại diện cho một ký tự đặc biệt cụ thể dựa trên mã ASCII của nó.
Bộ nhớ đệm (buffer) của lớp ByteArrayInputStream
Bộ nhớ đệm (buffer) của ByteArrayInputStream đề cập đến mảng byte nội bộ mà luồng này sử dụng để đọc dữ liệu. Khi bạn tạo một đối tượng ByteArrayInputStream, bạn cung cấp một mảng byte, và ByteArrayInputStream sẽ sử dụng mảng này làm nguồn dữ liệu.
Giải thích chi tiết:
↳ Nguồn dữ liệu: Khác với các loại InputStream khác, như FileInputStream (đọc dữ liệu từ một tệp tin), ByteArrayInputStream đọc dữ liệu từ một mảng byte mà bạn đã cung cấp sẵn.
↳ Bộ nhớ đệm: Mảng byte mà bạn cung cấp khi khởi tạo ByteArrayInputStream chính là bộ nhớ đệm. Luồng này sẽ đọc tuần tự các byte từ mảng này, giống như cách mà nó đọc từ các nguồn dữ liệu khác.
↳ Không tạo thêm bộ nhớ: ByteArrayInputStream không tạo ra một bản sao mới của mảng byte mà nó sử dụng trực tiếp mảng byte do bạn cung cấp. Điều này giúp tiết kiệm bộ nhớ, và cũng đảm bảo rằng bất kỳ thay đổi nào bạn thực hiện trên mảng byte sau khi tạo luồng sẽ được phản ánh khi đọc dữ liệu từ luồng.