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\"");
    }
  }
}

 


Связанные темы