Java I/O流之FileInputStream类、FileOutputStream类,文件字节的输入输出流以及输入流编码格式

在使用File类创建了文件之后,我们可能需要向该文件写入数据,或者从某一文件中读取数据。这时,我们就需要用到了文件字节的输入输出流。

在Java中,输入、输出流分别使用FileInputStream类和FileOutputStream类,这里需要注意的是,输入流是将文件中的数据拿出来,而输出流则是将某些数据写入文件中。

一、输入流

输入流的四个基本步骤:

  1. 设定输入流的源,也就是需要读取的文件。
  2. 创建指向源的输入流。
  3. 让输入流读取源中的数据。
  4. 关闭输入流。

接着我们开始介绍FileInputStream类,该类是InputStream类的子类,所以该类所使用的的实例方法都是从InputStream类继承而来的。

要点一: 我们可以使用该类的构造方法来创建指向文件的输入流。

FileInputStream(String name);	此构造方法的参数指的是文件名
FileInputStream(File file);     此构造方法的参数为File类的对象

无论是参数name还是参数file,他们都是输入流的源。需要注意的是,在创建输入流的时候,可能会发生错误,比如源(文件)不存在,所以我们需要使用异常机制语句。

创建输入流方法一:

import java.io.FileInputStream;
import java.io.IOException;
public class Main{
	public static void main(String[] args) {
		try {
			FileInputStream name = new FileInputStream("E:\\Java\\text.txt");
			System.out.println("输入流创建成功");
		} catch (IOException e) {
			// TODO: handle exception
			System.out.println("文件不存在");
		}
	}
}

在这里插入图片描述
在这里插入图片描述
假如用一个不存在的文件创建输入流:

import java.io.FileInputStream;
import java.io.IOException;
public class Main{
	public static void main(String[] args) {
		try {
			FileInputStream name = new FileInputStream("E:\\Java\\hello.txt");
			System.out.println("输入流创建成功");
		} catch (IOException e) {
			// TODO: handle exception
			System.out.println("文件不存在");
		}
	}
}

在这里插入图片描述
由于在我的E盘Java目录下,根本不存在hello.txt文件,所以创建输入流失败,文件不存在。

创建输入流方法二:

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
public class Main{
	public static void main(String[] args) {
		File file = new File("E:\\Java\\text.txt");
		try {
			FileInputStream f = new FileInputStream(file);
			System.out.println("输入流创建成功");
		} catch (IOException e) {
			// TODO: handle exception
			System.out.println("输入流创建失败,文件不存在");
		}
	}
}

在这里插入图片描述
要点二: 使用输入流读取字节。
通过第一步,我们很容易的创建了输入流通道,就是为了读取文件中的内容,单位是字节。

文件字节流可以从调用从父类继承的read方法顺序读取文件,在不关闭输入流的情况下,每次调用read方法就能顺序读取文件中的所有内容。
有几种读取的自己的方法:

  • int read() 输入流调用该方法从源中读取单个字节数据,该方法返回字节值。是0~255之间的一个整数,如果未读出字节就返回-1.
  • int read(byte b[]) 输入流调用该方法从源中试图读取b.length个字节到字节数组b中,返回实际读取字节数目,如果未读出字节就返回-1.
  • int read(byte b[],int off,int len) 输入流调用该方法从源中读取len个字节到字节数组b中,并返回实际读取的字节数目。如果到达文件末尾,则返回-1,参数off指定从字节数组的某个位置开始存放读取的数据。

输入流提供了关闭方法close() ,尽管程序结束或者文件中的内容被读取完时,最自动关闭输入流,但是在实际开发中,使用完输入流我们就手动关闭比较好。在没有关闭打开的输入流时,不允许其他程序操作这些流所用的资源。

示例:

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
public class Main{
	public static void main(String[] args) {
		File file = new File("E:\\Java\\text.txt");
		int n = -1;
		byte []b = new byte[100];
		try {
			FileInputStream f = new FileInputStream(file);
			System.out.println("输入流创建成功");
			while ((n = f.read(b,0,50))!=-1) {
				String str = new String(b,0,n,"utf-8");
				System.out.println(str);
			}
			f.close();
		} catch (IOException e) {
			// TODO: handle exception
			System.out.println("输入流创建失败,文件不存在");
		}
	}
}

在这里插入图片描述
在这里插入图片描述
特别需要注意的一点是,在输出流读取数据时,如果文件中有汉字,会出现乱码的情况,这时我们只需要在传入str的参数内加上一个编码格式即可!

二、输出流

输出流的四个基本步骤:

  1. 设定输出流的目的地,也就是要写入数据的文件。
  2. 创建指向目的地的输出流。
  3. 让输出流把数据写入目的地。
  4. 关闭输出流。

与输入流相对应的类那么就是FileOutputStream类了,没错,这就是输出流所需要的类。同样,和输入流一样,单位是字节。就是以字节为单位传输内容。

要点一: 该类是由OutputStream类的子类,该类的实例方法都是从OutputStream类继承而来的。
同样有两种构造方法可以创建输出流:

FileOutputStream(String name);		以文件名创建输出流
FileOutputStream(File file);		以File对象创建输出流

创建输出流方法一:

import java.io.FileNotFoundException;
import java.io.FileOutputStream;

public class Main{
	public static void main(String[] args) {
		try {
			FileOutputStream outfile = new FileOutputStream("E:\\Java\\OutFile.txt");
			System.out.println("输出流创建成功!");
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

在这里插入图片描述
创建输出流方法二:

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

public class Main{
	public static void main(String[] args) {
		File file = new File("E:\\Java\\OutFile.txt");
		try {
			FileOutputStream Outfile = new FileOutputStream(file);
			System.out.println("输出流创建成功!");
		} catch (IOException e) {
			// TODO: handle exception
			System.out.println(e);
		}
	}
}

注意: 在创建输出流时,如果目标文件不存在,则会自动创建一个目标文件,如果存在,就是用存在的文件。 而输入流需要本地确实有这个文件才可以。

要点二: 在使用FileOutputStream类时,我们可以通过选用布尔类型参数append来决定输出流是否刷新所指向的文件。

FileOutputStream(String name,boolean append);
FileOutputStream(File file,boolean append);

当append的值为True时,输出流不会刷新所指向的文件,输出流的write方法将从文件的末尾开始项文件写入数据;为false时输出流会刷新所指向的文件。

接着,我们就通过以下几种write方法来进行写入数据。每次调用write方法就顺序的向文件写入内容,直到输出流被关闭。

  • void write(int n)输出流调用该方法向目的地写数据。
  • void write(byte b[])输出流调用该方法向目的地写入一个字符数组。
  • void write(byte b[],int off,int len)给定字节数组中起始于偏移量off处取len个字节写到目的地。
  • void close()关闭输出流。
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Scanner;

public class Main{
	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		String str = scanner.nextLine();
		byte[] a = str.getBytes();
		File file = new File("E:\\Java\\output.txt");
		try {
			FileOutputStream outfile = new FileOutputStream(file);
			outfile.write(a);
			outfile.close();
			System.out.println("数据写入完毕!");
		} catch (IOException e) {
			// TODO: handle exception
			System.out.println(e);
		}
	}
}

在这里插入图片描述
在这里插入图片描述
接着,我们使用构造方法,不刷新输出流所指向的文件,继续追加内容:

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Scanner;

public class Main{
	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		String str = scanner.nextLine();
		byte[] a = str.getBytes();
		File file = new File("E:\\Java\\output.txt");
		try {
			FileOutputStream outfile = new FileOutputStream(file);
			outfile.write(a);
			outfile.close();
			System.out.println("数据写入完毕!");
			String string = scanner.nextLine();
			byte b[] = string.getBytes();
			FileOutputStream addout = new FileOutputStream(file,true);
			addout.write(b);
			addout.close();
			System.out.println("数据添加完成!");
		} catch (IOException e) {
			// TODO: handle exception
			System.out.println(e);
		}
	}
}

在这里插入图片描述
在这里插入图片描述
接着我们添加完数据后刷新一下输出流所指向的文件,再进行写入,这时文件中只有追加的数据,而没有第一次写入的数据。

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Scanner;

public class Main{
	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		String str = scanner.nextLine();
		byte[] a = str.getBytes();
		File file = new File("E:\\Java\\output.txt");
		try {
			FileOutputStream outfile = new FileOutputStream(file);
			outfile.write(a);
			outfile.close();
			System.out.println("数据写入完毕!");
			String string = scanner.nextLine();
			byte b[] = string.getBytes();
			FileOutputStream addout = new FileOutputStream(file,false);
			addout.write(b);
			addout.close();
			System.out.println("数据添加完成!");
		} catch (IOException e) {
			// TODO: handle exception
			System.out.println(e);
		}
	}
}

在这里插入图片描述
在这里插入图片描述
最后这两段代码最主要的区别就在于第二次写入数据时,使用的构造方法的第二个参数为true还是false,如果是true,就不刷新之前写入的数据,也就是保留之前的数据,如果为false,就代表要刷新之前写入的数据,也就是前面所写入的数据都没了,只有后续写入的数据。

OK,这篇文章到这里就结束啦,能否给个赞呢~
有不足的地方欢迎下方评论补充哦!

发布了89 篇原创文章 · 获赞 207 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/weixin_43729943/article/details/105130546