Java. Байтові потоки. Класи DataInputStream, DataOutputStream, FileInputStream, FileOutputStream. Приклади використання

Байтові потоки. Класи DataInputStream, DataOutputStream, FileInputStream, FileOutputStream. Приклади використання

У даній темі продемонстровано використання засобів мови Java для роботи з байтовими потоками. Наведено приклади розв’язку поширених задач для класів DataInputStream, DataOutputStream, FileInputStream, FileOutputStream.


Зміст


Пошук на інших ресурсах:




1. Запис та читання одновимірного масиву типу int[] в байтовий потік. Приклад

Нехай задано одновимірний масив типу int[], який потрібно:

  • записати в байтовий файловий потік;
  • зчитати з байтового файлового потоку.

Для розв’язку даної задачі добре підійдуть класи:

  • DataInputStream – потік вводу, що містить методи для читання даних стандартних типів Java, до яких належить тип int;
  • DataOutputStream – потік виводу, який містить методи для запису даних стандартних типів, визначених в Java;
  • FileInputStream – потік вводу, що містить методи, які читають дані з файлу;
  • FileOutputStream – потік виводу, що містить методи, які записують дані в файл.

Щоб організувати запис даних у файл потрібно:

  • створити файловий потік типу FileOutputStream;
  • створений файловий потік помістити в конструктор DataOutputStream;
  • використати методи класу DataOutputStream для запису даних у файл.

Щоб організувати читання даних з файлу потрібно:

  • створити файловий потік типу FileInputStream;
  • новостворений файловий потік помістити в конструктор DataInputStream;
  • використати методи класу DataInputStream для читання даних з файлу.

Приклад.

import java.io.*;

...

public static void main(String[] args) throws IOException
{
  // Вихідні дані - деякий масив цілих чисел
  int[] arrInt = { 2, 5, -1, 100, 33 };

  // 1. Записати масив arrInt у байтовий файл "integers.bin"
  // 1.1. Створити файловий байтовий потік, що зв'язаний з іменем "integers.bin"
  FileOutputStream fs = new FileOutputStream("integers.bin");

  // 1.2. Створити байтовий потік, що містить методи читання даних примітивних типів
  DataOutputStream ds = new DataOutputStream(fs);

  // 1.3. Записати кількість елементів у масиві - використовується метод write()
  ds.writeInt(arrInt.length);

  // 1.4. Записати масив цілих чисел
  for (int i=0; i<arrInt.length; i++)
    ds.writeInt((int)arrInt[i]);

  // 1.5. Закрити файл "integers.bin"
  fs.close();

  // --------------------------------------------------------------------------
  // 2. Зчитати масив цілих чисел з байтового файлу "integers.bin"
  int[] arrInt2; // масив, у який будуть зчитані дані з файлу "integers.bin"

  // 2.1. Створити файловий потік, що зв'язаний з іменем "integers.bin"
  FileInputStream fs2 = new FileInputStream("integers.bin");

  // 2.2. Створити потік даних, що зв'язаний з файловим потоком fs2
  DataInputStream ds2 = new DataInputStream(fs2);

  // 2.3. Зчитати кількість цілочисельних елементів, що записані у файлі
  int count = ds2.readInt();

  // 2.4. Виділити пам'ять для масиву arrInt2
  arrInt2 = new int[count];

  // 2.5. Цикл читання даних з ds2 та копіювання їх в масив arrInt2
  for (int i=0; i<arrInt2.length; i++)
    arrInt2[i] = ds2.readInt();

  // 2.6. Закрити потік ds2
  ds2.close();

  // --------------------------------------------------------------------------
  // 3. Вивести масив arrInt2 для контролю
  System.out.println("Array arrInt2: ");
  for (int i=0; i<arrInt2.length; i++)
    System.out.println(arrInt2[i]);
}

Результат виконання програми

Array arrInt2:
2
5
-1
100
33

 

2. Запис та читання даних різних типів (double, int, char). Приклад

Нехай потрібно:

  • записати у файл послідовно значення змінних типів double, int, char;
  • зчитати значення змінних типів double, int, char.

 

import java.io.*;

...

public static void main(String[] args) throws IOException
{
  // Вихідні дані - значення double, int, char

  // 1. Запис даних
  // 1.1. Створити файловий байтовий потік, що зв'язаний з іменем "data.bin"
  FileOutputStream fs = new FileOutputStream("data.bin");

  // 1.2. Створити байтовий потік, що містить методи читання даних примітивних типів
  DataOutputStream ds = new DataOutputStream(fs);

  // 1.3. Записати число типу double
  ds.writeDouble(5.85);

  // 1.4. Записати число типу int
  ds.writeInt(2000);

  // 1.5. Записати символ типу char
  ds.writeChar('Z');

  // 1.6. Закрити файл "data.bin"
  fs.close();

  // ------------------------------------------------------------
  // 2. Зчитати дані з байтового файлу "data.bin" у змінні doubleData, intData, charData
  double doubleData;
  int intData;
  char charData;

  // 2.1. Створити файловий потік, що зв'язаний з іменем "data.bin"
  FileInputStream fs2 = new FileInputStream("data.bin");

  // 2.2. Створити потік даних, що зв'язаний з файловим потоком fs2
  DataInputStream ds2 = new DataInputStream(fs2);

  // 2.3. Зчитати число типу double
  doubleData = ds2.readDouble();

  // 2.4. Зчитати число типу int
  intData = ds2.readInt();

  // 2.5. Зчитати число типу char
  charData = ds2.readChar();

  // 2.6. Закрити потік ds2
  ds2.close();

  // --------------------------------------------------------------
  // 3. Вивести дані для контролю
  System.out.println("doubleData = " + doubleData);
  System.out.println("intData = " + intData);
  System.out.println("charData = " + charData);
}

Результат роботи програми

doubleData = 5.85
intData = 2000
charData = Z

 

3. Запис та читання масиву дійсних чисел у байтовий файл. Приклад

У прикладі спочатку в файл записується масив чисел типу double, потім цей масив читається у внутрішні структури даних та виводиться на екран. Використовуються класи FileOutputStream, DataOutputStream, FileInputStream, DataInputStream.

import java.io.*;

...

public static void main(String[] args) throws IOException
{
  // Запис масиву дійсних чисел у байтовий файл

  // 1. Підготувати масив дійсних чисел AD
  double AD[] = new double[5];
  for (int i=0; i<AD.length; i++)
    AD[i] = i*2.5 + 1;

  // 2. Створити екземпляр класу FileOutputStream
  FileOutputStream fOut = new FileOutputStream("array.bin");

  // 3. Використати клас DataOutputStream для виводу в файл
  DataOutputStream dOut = new DataOutputStream(fOut); // зв'язати з файлом

  // 4. Запис даних про масив у байтовий файл
  // 4.1. Спочатку потрібно записати кількість елементів у масиві
  dOut.writeInt(AD.length);

  // 4.2. Цикл запису масиву в файл
  for (int i=0; i<AD.length; i++)
    dOut.writeDouble(AD[i]);

  // 5. Закрити потік dOut
  dOut.close();

  // 6. Вивести в консоль масив AD для контролю
  System.out.println("Array AD:");
  for (int i=0; i<AD.length; i++)
    System.out.println(AD[i]);

  // ----------------------------------
  // Читання дійсних чисел з файлу в масив AD2[]

  // 7. Оголосити результуючий масив
  double AD2[];

  // 8. Створити екземпляр файлу FileInputStream
  FileInputStream fIn = new FileInputStream("array.bin");

  // 9. Створити екземпляр класу DataInputStream та зв'язати його з файлом fIn
  DataInputStream dIn = new DataInputStream(fIn);

  // 10. Прочитати кількість чисел в масиві
  int count;
  count = dIn.readInt();

  // 11. Виділити пам'ять для масиву AD2[]
  AD2 = new double[count];

  // 12. Зчитати числа з файлу в масив AD2[]
  for (int i=0; i<AD2.length; i++)
    AD2[i] = dIn.readDouble();

  // 13. Закрити потік DataInputStream
  dIn.close();

  // 14. Вивести масив AD2[] для контролю
  System.out.println("\nArray AD2:");

  for (int i=0; i<AD2.length; i++)
    System.out.println(AD2[i]);
}

Результат виконання програми

Array AD:
1.0
3.5
6.0
8.5
11.0

Array AD2:
1.0
3.5
6.0
8.5
11.0

 

4. Приклад копіювання файлів з використанням байтового потоку

У прикладі наводиться фрагмент коду, що здійснює копіювання файлів. Використовуються засоби класів FileInputStream та FileOutputStream.

import java.io.*;

...

public static void main(String[] args) throws IOException
{
  // Копіювання файлів.
  // Файл "inputFile.txt" копіюється у файл "outputFile.txt"
  FileInputStream fi = null;
  FileOutputStream fo = null;

  try {
    // Спроба відкрити файли
    fi = new FileInputStream("inputFile.txt"); // вихідний файл
    fo = new FileOutputStream("outputFile.txt"); // результуючий файл

    // Цикл копіювання
    int d;

    do {
      // зчитати байти з fi
      d = fi.read();

      // записати байти в fo
      if (d != -1)
        fo.write(d);
    } while (d != -1);

    System.out.println("Ok!");
  }
  catch (IOException e) {
    // Якщо один з файлів не відкрито, то вивести відповідне повідомлення
    System.out.println("I/O error: " + e);
  }
  finally {
    try {
      // Якщо перший файл відкрито, то закрити його
      if (fi != null)
        fi.close();
    }
    catch (IOException e2) {
      System.out.println("Cannot close file \"inputFile.txt\"");
    }

    try {
      // Якщо другий файл відкрито, то закрити його
      if (fo != null)
        fo.close();
    }
    catch (IOException e2) {
      System.out.println("Cannot close file \"outputFile.txt\"");
    }
  }
}

 


Зв’язані теми