Java: Data Stream


Khóa học qua video:
Lập trình Python All Lập trình C# All SQL Server All Lập trình C All Java PHP HTML5-CSS3-JavaScript
Đăng ký Hội viên
Tất cả các video dành cho hội viên

Data stream hỗ trợ các hoạt động I/O nhị phân đối với các giá trị có kiểu dữ liệu nguyên thủy và các giá trị kiểu chuỗi (String). Tất cả các data stream đều thực thi một trong hai giao diện là DataInput hoặc DataOutput. Bài viết này tập trung vào việc thực thi các giao diện DataInputStream và DataOutputStream.

Ví dụ có tên DataStreams dưới đây trình bày data stream bằng cách ghi ra một tập hợp các bản ghi dữ liệu, và sau đó đọc chúng.

package solutions;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.EOFException;

public class DataStreams {
  static final String dataFile = "invoicedata";

  static final double[] prices = {19.99, 9.99, 15.99, 3.99, 4.99};
  static final int[] units = {12, 8, 13, 29, 50};
  static final String[] names = {"Java Core",
    "Java OOP",
    "Java App Desktop",
    "Java App Mobile",
    "Java Web"};

  public static void main(String[] args) throws IOException {

    DataOutputStream out = null;

    try {
      out = new DataOutputStream(new
        BufferedOutputStream(new FileOutputStream(dataFile)));

      for (int i = 0; i < prices.length; i++) {
        out.writeDouble(prices[i]);
        out.writeInt(units[i]);
        out.writeUTF(names[i]);
      }
    } finally {
      out.close();
    }

    DataInputStream in = null;
    double total = 0.0;
    try {
      in = new DataInputStream(new
        BufferedInputStream(new FileInputStream(dataFile)));

      double price;
      int unit;
      String name;

      try {
        while (true) {
          price = in.readDouble();
          unit = in.readInt();
          name = in.readUTF();
          System.out.format("You ordered %d units of %s at $%.2f%n",
            unit, name, price);
          total += unit * price;
        }
      } catch (EOFException e) {
      }
      System.out.format("For a TOTAL of: $%.2f%n", total);
    } finally {
      in.close();
    }
  }
}

Mỗi bản ghi bao gồm ba giá trị liên quan đến một sản phẩm trên một hóa đơn, như thể hiện trong bảng sau:

Thứ tự Loại dữ liệu Mô tả dữ liệu Phương thức output Phương thức input Giá trị mẫu
1 double Giá sản phẩm DataOutputStream.writeDouble DataInputStream.readDouble 19.99
2 int đơn vị tính DataOutputStream.writeInt DataInputStream.readInt 12
3 String Mô tả sản phẩm DataOutputStream.writeUTF DataInputStream.readUTF "Java T-Shirt"

Hãy kiểm tra mã số rất quan trọng trong DataStreams. Đầu tiên, chương trình định nghĩa một số hằng số chứa tên của các tập tin dữ liệu và dữ liệu sẽ được ghi vào nó:

static final String dataFile = "invoicedata";

static final double[] prices = {19.99, 9.99, 15.99, 3.99, 4.99};
static final int[] units = {12, 8, 13, 29, 50};
static final String[] names = {"Java Core",
  "Java OOP",
  "Java App Desktop",
  "Java App Mobile",
  "Java Web"};

Sau đó DataStreams mở một output stream. Vì mỗi DataOutputStream chỉ có thể được tạo ra như là một wrapper cho một đối tượng byte stream hiện có, nên DataStreams sẽ cung cấp một tập tin được đệm để output byte stream.

out = new DataOutputStream(new
  BufferedOutputStream(new FileOutputStream(dataFile)));

for (int i = 0; i < prices.length; i++) {
  out.writeDouble(prices[i]);
  out.writeInt(units[i]);
  out.writeUTF(names[i]);
}

Phương thức writeUTF sẽ ghi ra các giá trị String theo định dạng UTF-8 đã sửa đổi, đây là một mã ký tự chiều rộng thay đổi mà chỉ cần một byte duy nhất cho các ký tự phương Tây thông thường.

Bây giờ DataStreams đọc dữ liệu trở lại. Đầu tiên nó phải cung cấp một input stream và các biến để lưu dữ liệu đầu vào. Giống như DataOutputStreamDataInputStream phải được xây dựng như là một wrapper cho một byte stream.

in = new DataInputStream(new
  BufferedInputStream(new FileInputStream(dataFile)));

double price;
int unit;
String name;

Bây giờ DataStreams có thể đọc mỗi bản ghi trong stream, báo cáo về dữ liệu mà nó gặp.

try {
  while (true) {
    price = in.readDouble();
    unit = in.readInt();
    name = in.readUTF();
    System.out.format("You ordered %d units of %s at $%.2f%n",
      unit, name, price);
    total += unit * price;
  }
} catch (EOFException e) {
}

Chú ý rằng DataStreams phát hiện một điều kiện cuối tập tin bằng cách bắt ngoại lệ EOFException thay vì kiểm tra một giá trị trả về không hợp lệ. Tất cả các thực thi của các phương thức của DataInput đều sử dụng EOFException thay vì các giá trị trả về.

Cũng lưu ý rằng mỗi phương thức write cụ thể trong DataStreams được kết hợp chính xác với một phương thức read tương ứng. Vậy nên, lập trình viên cần đảm bảo rằng các kiểu output và input phải tương thích với nhau theo cách thức sau: Các input stream bao gồm các dữ liệu nhị phân đơn giản, không cần chỉ ra các loại giá trị riêng, hoặc vị trí bắt đầu của chúng trong stream.

Ở đây, DataStreams sử dụng một kỹ thuật lập trình rất tồi là: nó sử dụng các số dấu chấm động (số thực) để thể hiện các giá trị tiền tệ, mà kiểu dấu chấm động không thích hợp cho giá trị chính xác. Nó đặc biệt tồi khi áp dụng cho các phân số thập phân, bởi vì những ước số chung (như là 0.1 chẳng hạn) không thể hiện được ở dạng nhị phân.

Các kiểu chuẩn áp dụng cho các giá trị tiền tệ là java.math.BigDecimal. Tuy nhiên, BigDecimal là một kiểu đối tượng, vì vậy nó sẽ không làm việc với data stream. Tuy nhiên, BigDecimal sẽ làm việc với object stream, được trình bày ở bài viết tiếp theo.

» Tiếp: Object Stream
« Trước: I/O từ Command Line
Khóa học qua video:
Lập trình Python All Lập trình C# All SQL Server All Lập trình C All Java PHP HTML5-CSS3-JavaScript
Đăng ký Hội viên
Tất cả các video dành cho hội viên
Copied !!!