สามารถใช้คลาส ByteArrayInputStream ใน แพ็คเกจ java.ioเพื่ออ่านอินพุตอาร์เรย์ (จำนวนไบต์)

ในการสร้างสตรีมอินพุตอาร์เรย์แบบไบต์ เราต้องนำเข้าแพ็คเกจjava.io.ByteArrayInputStream ก่อน หลังจากที่เรานำเข้าแพ็คเกจแล้ว เรามีตัวสร้างสองตัวสำหรับสร้างสตรีมอินพุต:
ByteArrayInputStream input = new ByteArrayInputStream(arr);
ByteArrayInputStream input = new ByteArrayInputStream(arr, 2, 2);
มี 4 ฟิลด์ภายในชั้นเรียน:
// Byte array provided by the creator of the stream
protected byte buf[];
// Index of the next character to read from the input stream's buffer
protected int pos;
// Current marked position in the stream
protected int mark = 0;
// Index is one greater than the last valid character in the input stream's buffer
protected int count;
และนี่คือตัวสร้างของเรา:
public ByteArrayInputStream(byte buf[]) {
this.buf = buf;
this.pos = 0;
this.count = buf.length;
}
public ByteArrayInputStream(byte buf[], int offset, int length) {
this.buf = buf;
this.pos = offset;
this.count = Math.min(offset + length, buf.length);
this.mark = offset;
}
เมธอดของคลาส ByteArrayInputStream
วิธี | การกระทำ |
---|---|
int อ่าน () | อ่านข้อมูลไบต์ถัดไปจากสตรีมอินพุตนี้ |
int อ่าน (ไบต์ b [], int ปิด, int len) | อ่านหลายไบต์จากสตรีมอินพุตและเก็บไว้ในอาร์เรย์บัฟเฟอร์b offคือค่าชดเชยในอาร์เรย์เป้าหมายb lenคือจำนวนไบต์สูงสุดที่จะอ่านได้ |
ข้ามยาว(ยาว n) | ข้ามอินพุต n ไบต์จากสตรีมอินพุตนี้ ส่งกลับจำนวนไบต์ที่ข้ามไป (อาจน้อยกว่า n หากเราไปถึงจุดสิ้นสุดของสตรีมอินพุต) |
int ใช้ได้ () | ส่งกลับจำนวนไบต์ที่เหลือที่สามารถอ่าน (หรือข้าม) จากอินพุตสตรีมนี้ |
เป็นโมฆะรีเซ็ต () | รีเซ็ตบัฟเฟอร์ไปยังตำแหน่งที่ทำเครื่องหมายไว้ ตำแหน่งที่ทำเครื่องหมายเป็น 0 เว้นแต่จะมีการทำเครื่องหมายตำแหน่งอื่นหรือระบุออฟเซ็ตอื่นในตัวสร้าง |
เครื่องหมายบูลีนรองรับ () | ตรวจสอบว่าInputStream นี้ รองรับการทำเครื่องหมาย/การรีเซ็ตหรือไม่ คืนค่าจริงสำหรับByteArrayInputStream |
เป็นโมฆะปิด () | ไม่ทำอะไรเลย |
เครื่องหมายเป็นโมฆะ (int readAheadLimit) | ตั้งค่าเครื่องหมายเขตเท่ากับตำแหน่งปัจจุบัน หาก มีการเรียกใช้วิธี การรีเซ็ตการอ่านครั้งต่อไปจะเริ่มจากตำแหน่งนั้น ไม่ได้ใช้ พารามิเตอร์readAheadLimitและไม่ส่งผลต่อลักษณะการทำงานของเมธอด |
ลองมาดูวิธีการเหล่านี้ให้ละเอียดยิ่งขึ้นและดูว่าพวกเขาทำงานอย่างไร
อ่าน()
เมื่อคุณต้องการอ่านไบต์จากByteArrayInputStreamเช่นเดียวกับที่คุณอ่านจากInputStream ทั่วไป คุณสามารถใช้เมธอดread()
public static void main(String[] args) {
byte[] array = {1, 2, 3, 4};
try (ByteArrayInputStream input = new ByteArrayInputStream(array)) {
for (int i = 0; i < array.length; i++) {
int data = input.read();
System.out.print(data + ", ");
}
} catch (IOException e) {
e.printStackTrace();
}
}
มีอยู่()
หากคุณต้องการตรวจสอบว่ามีบางอย่างอยู่ในบัฟเฟอร์ของคุณหรือไม่ คุณสามารถเรียกใช้เมธอดavailable()
public static void main(String[] args) {
byte[] array = {1, 2, 3, 4};
try (ByteArrayInputStream input = new ByteArrayInputStream(array)) {
System.out.println("Bytes available for reading: " + input.available());
input.read();
System.out.println("Bytes available for reading " + input.available());
input.read();
System.out.println("Bytes available for reading " + input.available());
} catch (IOException e) {
e.printStackTrace();
}
}
เราจะเห็นว่าจำนวนไบต์ที่สามารถอ่านได้เปลี่ยนแปลงไปหลังจากอ่านแต่ละครั้งจากบัฟเฟอร์
เอาท์พุต:
ไบต์สำหรับการอ่าน: 3
ไบต์สำหรับการอ่าน: 2
ข้าม (ยาว n)
คุณสามารถใช้ เมธอด การข้าม ()เพื่อข้ามจำนวนไบต์ที่กำหนดและไม่อ่าน
public static void main(String[] args) {
byte[] array = {1, 2, 3, 4};
try (ByteArrayInputStream input = new ByteArrayInputStream(array)) {
input.skip(2);
while (input.available() != 0) {
int data = input.read();
System.out.print(data + ", ");
}
} catch (IOException e) {
e.printStackTrace();
}
}
เอาท์พุต:
รีเซ็ต ()
วิธีนี้จะรีเซ็ตตำแหน่งของสตรีมที่บัฟเฟอร์เป็นตำแหน่งที่ทำเครื่องหมายไว้ล่าสุด เป็นตำแหน่ง 0 เว้นแต่จะกำหนดเครื่องหมายอื่นไว้
public static void main(String[] args) {
byte[] buf = {65, 66, 67, 68, 69};
try (ByteArrayInputStream input = new ByteArrayInputStream(buf)) {
System.out.println("Read: " + input.read());
System.out.println("Read: " + input.read());
System.out.println("Read: " + input.read());
System.out.println("Read: " + input.read());
System.out.println("Calling reset() method");
input.reset();
System.out.println("Read: " + input.read());
System.out.println("Read: " + input.read());
} catch (IOException e) {
e.printStackTrace();
}
}
เราจะเห็นว่าการเรียกใช้เมธอดreset()จะนำเราไปยังจุดเริ่มต้นของสตรีมของเรา
เอาท์พุต:
อ่าน: 66
อ่าน: 67
อ่าน: 68
วิธีรีเซ็ตการโทร ()
อ่าน: 65
อ่าน: 66
ทำเครื่องหมาย (int readAheadLimit)
วิธีการทำ เครื่องหมาย()ของ คลาส ByteArrayInputStreamตั้งค่าเครื่องหมายภายในที่ตำแหน่งไบต์ปัจจุบัน นั่นคือ ทันทีหลังจากไบต์ที่อ่านก่อนหน้านี้ เมธอดนี้ใช้พารามิเตอร์ที่ระบุจำนวนไบต์ที่สามารถอ่านได้หลังจากทำเครื่องหมายก่อนที่สตรีมจะไม่ถูกต้อง ตามค่าเริ่มต้น หากไม่ได้ตั้งค่าเครื่องหมายอย่างชัดเจนByteArrayInputStreamจะทำเครื่องหมายตำแหน่ง 0 หรือตำแหน่งของออฟเซ็ตที่ส่งผ่านไปยังตัวสร้าง โปรดทราบว่า เครื่องหมาย readAheadLimitไม่เกี่ยวข้องกับคลาสนี้
/* Note: For this class, {@code readAheadLimit}
* has no meaning.
*
* @since 1.1
*/
public void mark(int readAheadLimit) {
mark = pos;
}
นี่คือตัวอย่างการตั้งค่าเครื่องหมายในByteArrayInputStreamโดยใช้วิธีmark()และreset() เราจะเพิ่มการเรียกใช้เมธอดmark()ให้กับตัวอย่างก่อนหน้านี้:
public static void main(String[] args) {
byte[] buf = {65, 66, 67, 68, 69};
try (ByteArrayInputStream input = new ByteArrayInputStream(buf)) {
System.out.println("Read: " + input.read());
System.out.println("Read: " + input.read());
System.out.println("Read: " + input.read());
input.mark(5);
System.out.println("Read: " + input.read());
System.out.println("Read: " + input.read());
System.out.println("Calling reset() method");
input.reset();
System.out.println("Read: " + input.read());
System.out.println("Read: " + input.read());
} catch (IOException e) {
e.printStackTrace();
}
}
เราจะเห็นว่าตำแหน่งของกระแสเปลี่ยนไป
เอาท์พุต:
อ่าน: 66
อ่าน: 67
อ่าน: 68
อ่าน: 69
วิธีรีเซ็ตการโทร ()
อ่าน: 68
อ่าน: 69
เครื่องหมายรองรับ ()
วิธี การ markSupported()ช่วยให้คุณตรวจสอบว่าสามารถตั้งค่าเครื่องหมายได้หรือไม่ เพื่อให้เข้าใจว่าค่าส่งคืนมาจากไหน ให้ไปที่โค้ดของเมธอด:
/**
* Tests if this {@code InputStream} supports mark/reset. The
* {@code markSupported} method of {@code ByteArrayInputStream}
* always returns {@code true}.
*
* @since 1.1
*/
public boolean markSupported() {
return true;
}
เมธอดจะคืนค่าtrue เสมอ ลองทดสอบกันในทางปฏิบัติ
public static void main(String[] args) {
byte[] buf = {65, 66, 67, 68, 69};
try (ByteArrayInputStream bais = new ByteArrayInputStream(buf)) {
boolean isMarkSupported = bais.markSupported();
System.out.println("isMarkSupported: " + isMarkSupported);
System.out.println("Read: " + bais.read());
System.out.println("Read: " + bais.read());
bais.mark(1);
System.out.println("Read: " + bais.read());
isMarkSupported = bais.markSupported();
System.out.println("isMarkSupported: " + isMarkSupported);
bais.reset();
isMarkSupported = bais.markSupported();
System.out.println("isMarkSupported: " + isMarkSupported);
} catch (IOException e) {
e.printStackTrace();
}
}
หลังจากใช้เมธอดmark()และreset()สตรีมของเราก็พร้อมเสมอและรองรับการทำเครื่องหมาย:
เอาท์พุต:
อ่าน: 65
Read: 66
Read: 67
isMarkSupported: true
isMarkSupported: true
ปิด()
และเพื่อให้เข้าใจถึง วิธี การปิดลองมาดูข้างในกัน:
/**
* Closing a {@code ByteArrayInputStream} has no effect. The methods in
* this class can be called after the stream has been closed without
* generating an {@code IOException}.
*/
public void close() throws IOException {
}
เอกสารประกอบสำหรับวิธีการปิดบอกเราว่าการปิดByteArrayInputStreamไม่มีผลใดๆ เมธอด คลาสByteArrayInputStream สามารถเรียกได้หลังจากปิดสตรีมโดยไม่ต้องโยนIOException
เราสามารถสรุปอะไรได้บ้าง?
เราต้องการByteArrayInputStreamเมื่อเราต้องการอ่านข้อมูลจากอาร์เรย์แบบไบต์ โดยปกติแล้ว การใช้คลาสนี้ร่วมกับโค้ดอื่นๆ ที่รู้วิธีทำงานกับInputStreamsนั้นสมเหตุสมผลกว่าปกติ
GO TO FULL VERSION