文章目录
- 概念
- InputStream字节输入流
- FileInputStream文件字节输入流
- FileOutputStream字节输出流
- 相关的方法(write)和构造器
- 构造器注意事项
- 文件拷贝
概念
在Java中,字节流一般适用于处理字节数据(诸如图片、视频),InputStream/OutPutStream为字节流基类(超类或父类),字节流的类通常以stream结尾。它们的子类都是字节流,主要用在按字节来处理二进制数据。字节流是最基本的,采用ASCII编码
如果对输入流和输出流有疑问,可查看此博客或自行百度!
Java IO流(基础详解,快速上手!)
如有疑问,欢迎评论区留言私信。
InputStream字节输入流
InputStream是抽象类,无法实例化,需要实现子类。
是所有类字节输入流的超类(父类)
InputStream常用的子类
- FileInputStream:文件字节输入流
- BufferedInputStream:缓冲字节输入流
- ObjectInputStream:对象字节输入流
注意:其中BufferedInputStream的直接父类是FilterInputStream
FileInputStream文件字节输入流
FileInputStream 是 Java 语言中抽象类 InputStream 用来具体实现类的创建对象。
FileInputStream 流被称为文件字节输入流,意思指对文件数据以字节的形式进行读取操作如读取图片视频等。
构造器和方法
基本常用方法
- 读取文件(文本)中的数据 read(按字节读取)
如果返回-1,表示读取结束
import org.junit.jupiter.api.Test;
import java.io.FileInputStream;
import java.io.IOException;
@Test
public void readFile02() throws FileNotFoundException {
String filePath = "E:\\hello.txt";
int readData = 0;
FileInputStream fileInputStream = null;
try {
fileInputStream = new FileInputStream(filePath);
//如果返回-1,表示读取完毕
while ((readData = fileInputStream.read()) != -1) {
System.out.print((char) readData + " ");
}
} catch (IOException e) {
e.getMessage();//输出异常信息
} finally {//表示finally表示try执行完毕之后,必须执行的,catch是用来捕获异常的
try {
fileInputStream.close();//关闭流,释放连接
} catch (IOException e) {
e.getMessage();
}
}
}
-
read(按字节数组读取)
如果读取正常返回,返回实际读取的字节数(返回的最大字节数为字符数据容量);如果返回-1,表示读取完毕这里使用了String的构造器用于将buf转换为字符串
import org.junit.jupiter.api.Test;
import java.io.FileInputStream;
import java.io.IOException
@Test
public void readFile02() throws FileNotFoundException {
String filePath = "E:\\hello.txt";
//字节数据
byte[] buf = new byte[8];//一次读取八个
int readLen = 0;
FileInputStream fileInputStream = null;
try {
fileInputStream = new FileInputStream(filePath);
//如果返回-1,表示读取完毕
while ((readLen = fileInputStream.read(buf)) != -1) {
System.out.print(new String(buf, 0, readLen));
}
} catch (IOException e) {
e.getMessage();//输出异常信息
} finally {//表示finally表示try执行完毕之后,必须执行的,catch是用来捕获异常的
try {
fileInputStream.close();//关闭流,释放连接
} catch (IOException e) {
e.getMessage();
}
}
}
读取E盘下的hello.txt文本,此时文本的内容为:h e l l o , w o r l d (这是我文件的内容,可自定义)
如果文件中有汉字可能会造成乱码(字节大小不匹配,可以使用字符流)
读取之后返回的内容是ASCII码值!
注意:操作完之后,需要关闭这个流,否则造成资源浪费,引用close方法即可
FileOutputStream字节输出流
FileOutputStream流是指文件字节输出流,专用于输出原始字节流如图像数据等,其继承OutputStream类,拥有输出流的基本特性
- OutputStream 抽象类,所有输出字节字节流的父类
- FileOutputStream 向文件输出数据的输出字节流。
使用FileOutputStream步骤:
- 找到目标文件
- 建立数据的输出通道
相关的方法(write)和构造器
FileOutputStream提供了4个常用构造方法,用于实例化FileOutputStream对象(不同场景使用不同的构造方法)
- new FileOutputStream 的时候,如果目标文件不存在,那么会先创建目标文件,然后再写入。(如果目标文件所在的文件夹不存在,则抛出异常)
- new FileOutputStream(file) 如果目标文件已经存在,那么会先清空 目标文件的数据,然后再写入新的数据
- 写入数据的时候如果需要以追加的形式写入,那么需要使用new FileOutputStream(file,true) 这个构造函数
操作演示
根据不同的场景选择方法!
- 将指定的字节写入该文件输出流中:
public void write(int b) throws IOException
import org.junit.jupiter.api.Test;
import java.io.FileOutputStream;
import java.io.IOException;
@Test
public void writeFile() {
String filePath = "E:\\hello.txt";
FileOutputStream fileOutput = null;
try {
fileOutput = new FileOutputStream(filePath);
//写入一个字节
fileOutput.write('a');//char和int可以互用
} catch (IOException e) {
e.getMessage();
} finally {//执行完try,无异常时执行finally,有异常,先执行catch,在执行finally
try {
fileOutput.close();
} catch (IOException e) {
e.getMessage();//输出异常
}
}
}
此时E盘下的hello.txt文件中的内容为a
- 将多个字节写入到此文件输出流(字节数组)
这里使用了String中的 getByres 方法(可以将字符串转换为一个字节byte数组) public void write(byte[] b) throws IOException
@Test
public void writeFile() {
String filePath = "E:\\hello.txt";
FileOutputStream fileOutput = null;
try {
fileOutput = new FileOutputStream(filePath);
//写入多个字节
String str = "hello,world";
fileOutput.write(str.getBytes());
} catch (IOException e) {
e.getMessage();
} finally {//执行完try,无异常时执行finally,有异常,先执行catch,在执行finally
try {
fileOutput.close();
} catch (IOException e) {
e.getMessage();//输出异常
}
}
}
此时E盘下的hello.txt文件中的内容为:hello,world
- 该方法将len个字节的数据,并从数组b的off位置开始写入到输出流
public void write(byte[] b, int off, int len) throws IOException
@Test
public void writeFile() {
String filePath = "E:\\hello.txt";
FileOutputStream fileOutput = null;
try {
fileOutput = new FileOutputStream(filePath);
//写入多个字节
String str = "hello,world";
fileOutput.write(str.getBytes(), 2, str.length()-5);
} catch (IOException e) {
e.getMessage();
} finally {//执行完try,无异常时执行finally,有异常,先执行catch,在执行finally
try {
fileOutput.close();
} catch (IOException e) {
e.getMessage();//输出异常
}
}
}
此时E盘下的hello.txt的内容为 llo,wo
构造器注意事项
- 如果使用的是这种的创建方式,当写入内容时,会覆盖原来的内容
public FileOutputStream(File file)
创建一个文件输出流写入指定的 File对象表示的文件。一个新的 FileDescriptor对象来表示这个文件连接
- 参数:file -要打开以进行写入的文件
- 异常
- FileNotFoundException -如果文件存在,但是是一个目录而不是常规文件,不存在但不能被创造,也不能打开任何其他原因
- SecurityException -如果存在一个安全管理及其 checkWrite方法拒绝写访问文件
- 不覆盖原来的内容,在结尾后面追加
public FileOutputStream(File file,boolean append)
创建一个文件输出流写入指定的 File对象表示的文件。如果第二 true,然后字节将被写入到文件的末尾而不是开头。一个新的 FileDescriptor对象来表示这个文件连接。
- 参数
- file:要打开以进行写入的文件
- append -如果 true,然后字节将被写入到文件的末尾而不是开头
- 异常
- FileNotFoundException -如果文件存在,但是是一个目录而不是常规文件,不存在但不能被创造,也不能打开任何其他原因
- SecurityException -如果存在一个安全管理及其 checkWrite方法拒绝写访问文件。
文件拷贝
将 D盘下的test.txt文件拷贝到E盘目录下
- 创建文件的输入流,将文件读入到Java的程序(内存)
- 创建文件的输出流,将读入到的文件数据写入到指定的文件
在完成程序时,应该是读取部分数据,就写入到程序(防止文件过大),所以使用循环操作
以下代码为基础知识(有其他方案),也可以拷贝视频、图片等
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class FileCopy {
public static void main(String[] args) {
String srcFilePath = "D:\\test.txt";//要拷贝的文件路径
String destFilePath = "E:\\test.txt";//拷贝到的路径,文件名可以自定义
FileInputStream fileInputStream = null;
FileOutputStream fileOutputStream = null;
try {
fileInputStream = new FileInputStream(srcFilePath);
fileOutputStream = new FileOutputStream(destFilePath);
//定义一个字节数组提高效率
byte[] bytes = new byte[1024];
int readLen = 0;//一次读取多少个
while ((readLen = fileInputStream.read(bytes)) == -1) {
//写入文件,边读边写
fileOutputStream.write(bytes,0,readLen);
}
System.out.println("拷贝成功");
} catch (IOException e) {
e.getMessage();//输出异常
} finally {
try {//关闭输入流和输出流,释放资源
if (fileInputStream!=null){
fileInputStream.close();
}
if (fileOutputStream!=null){
fileOutputStream.close();
}
} catch (IOException e) {
e.getMessage();//输出异常
}
}
}
}