Чтение и запись файлов. FileInputStream и FileOutputStream

Последнее обновление: 08.03.2023

Запись файлов и класс FileOutputStream

Класс FileOutputStream предназначен для записи байтов в файл. Он является производным от класса OutputStream, поэтому наследует всю его функциональность.

Через конструктор класса FileOutputStream задается файл, в который производится запись. Класс поддерживает несколько конструкторов:

FileOutputStream(String filePath)
FileOutputStream(File fileObj)
FileOutputStream(String filePath, boolean append)
FileOutputStream(File fileObj, boolean append)

Файл задается либо через строковый путь, либо через объект File. Второй параметр - append задает способ записи: eсли он равен true, то данные дозаписываются в конец файла, а при false - файл полностью перезаписывается

Например, запишем в файл строку:

import java.io.*;

public class Program {
 
    public static void main(String[] args) {
         
        String text = "Hello world!"; // строка для записи
        try(FileOutputStream fos=new FileOutputStream("notes.txt"))
        {
            // перевод строки в байты
            byte[] buffer = text.getBytes();
             
            fos.write(buffer, 0, buffer.length);
			System.out.println("The file has been written");
        }
        catch(IOException ex){
             
            System.out.println(ex.getMessage());
        }
    }
}

Для создания объекта FileOutputStream используется конструктор, принимающий в качестве параметра путь к файлу для записи. Если такого файла нет, то он автоматически создается при записи. Так как здесь записываем строку, то ее надо сначала перевести в массив байтов. И с помощью метода write строка записывается в файл.

Для автоматического закрытия файла и освобождения ресурса объект FileOutputStream создается с помощью конструктции try...catch.

При этом необязательно записывать весь массив байтов. Используя перегрузку метода write(), можно записать и одиночный байт:

fos.write(buffer[0]); // запись первого байта

Чтение файлов и класс FileInputStream

Для считывания данных из файла предназначен класс FileInputStream, который является наследником класса InputStream и поэтому реализует все его методы.

Для создания объекта FileInputStream мы можем использовать ряд конструкторов. Наиболее используемая версия конструктора в качестве параметра принимает путь к считываемому файлу:

FileInputStream(String fileName) throws FileNotFoundException

Если файл не может быть открыт, например, по указанному пути такого файла не существует, то генерируется исключение FileNotFoundException.

Считаем данные из ранее записанного файла и выведем на консоль:

import java.io.*;

public class Program {
 
    public static void main(String[] args) {

		try(FileInputStream fin=new FileInputStream("notes.txt"))
        {    
            int i;
            while((i=fin.read())!=-1){
             
                System.out.print((char)i);
            }   
        }
        catch(IOException ex){
             
            System.out.println(ex.getMessage());
        } 
    }
}

В данном случае мы считываем каждый отдельный байт в переменную i:

while((i=fin.read())!=-1){

Когда в потоке больше нет данных для чтения, метод возвращает число -1.

Затем каждый считанный байт конвертируется в объект типа char и выводится на консоль.

Подобным образом можно считать данные в массив байтов и затем производить с ним манипуляции:

import java.io.*;
 
public class Program {
  
    public static void main(String[] args) {
 
        try(FileInputStream fin=new FileInputStream("notes.txt"))
        {
            byte[] buffer = new byte[256];
            System.out.println("File data:");
            
            int count;
            while((count=fin.read(buffer))!=-1){
              
                for(int i=0; i<count;i++){
            
                    System.out.print((char)buffer[i]);
                }
            }   
        }
        catch(IOException ex){
              
            System.out.println(ex.getMessage());
        } 
    }
}

В данном случае с помощью метода read() считываем данные в массив buffer длиной 256 байтов. Метод возвращает количество считанных байтов.

Поскольк файл может быть больше 256 байтов, то считываем в цикле while до конца файла. Когда больше не останется файлов для считывания, то метод возвратит -1.

while((count=fin.read(buffer))!=-1){

Поскольку количество считанных байтов/размер файла могут быть меньше 256 байт, то реальное количество считанных байт сохраняем в переменную count. Затем выводим считанное количество данных на консоль в цикле for.

for(int i=0; i<count;i++){
            
    System.out.print((char)buffer[i]);
}

Совместим оба класса и выполним чтение из одного и запись в другой файл:

import java.io.*;
 
public class Program {
 
    public static void main(String[] args) {
         
        try(FileInputStream fin=new FileInputStream("notes.txt");
                FileOutputStream fos=new FileOutputStream("notes_new.txt"))
        {
            byte[] buffer = new byte[256];
            
            int count;
            // считываем буфер
            while((count=fin.read(buffer))!=-1){
              
                // записываем из буфера в файл
                fos.write(buffer, 0, count);
            }
            System.out.println("File has been written");
        }
        catch(IOException ex){
             
            System.out.println(ex.getMessage());
        } 
    } 
}

Классы FileInputStream и FileOutputStream предназначены прежде всего для записи двоичных файлов, то есть для записи и чтения байтов. И хотя они также могут использоваться для работы с текстовыми файлами, но все же для этой задачи больше подходят другие классы.

Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850