0
点赞
收藏
分享

微信扫一扫

Java编程基础之IO流

juneyale 2022-11-17 阅读 171


IO流

Java编程基础之IO流_字节流

IO流基类

  • InputStream
    输入流基类
    read
  • OutputStream
    输出流基类
    write

IO流分类

  • 流向分类
    输入输出
  • 文件操作处理单元分类
    字节流和字符流
  • FileInputStream
    文件操作输入字节流
  • FileOutputStream
    文件操作输出字节流
  • FileReader
    文件操作输入字符流
  • FileWriter
    文件操作输出字符流

文件操作字节流

文件操作输入字节流

FileInputStream

Constructor构造方法

  • FileInputStream(File file);
    这里是根据提供的File类对象创建对应的文件操作输入字节流
  • FileInputStream(String pathName);
    这里是根据提供的String类型文件路径,创建对应的文件操作输入字节流

两个方法都会抛出FileNotFoundException文件未找到异常

Method成员方法

  • int read();
    从文件中读取一个字节数据返回到方法外
    虽然返回值是一个int类型,但是整个int类型当中存储的数据是一个byte类型,有且只有低8位数据有效
  • int read(byte[] buf);
    读取文件的内容是存储在byte类型数组中,返回值是读取到的字节个数
  • int read(byte[] buf, int offset, int count);
    读取文件的内容是存储在byte类型数组中,要求byte数组offset位置开始,到count长度结束,返回值是读取到的字节个数

这三个方法,如果读取到文件末尾,返回值都是-1 EOF (End Of File),并且都要抛出IOException异常

FileInputStream实例:

package obj_file;

import java.io.File;
import java.io.FileInputStream;

public class Demo6 {
public static void main(String[] args) {
// 打开文件创建句柄
File file = new File("D:\\JavaCode\\test\\1.txt");

// 2.字节输入流读取文件对象
FileInputStream fileInputStream = null;

try {
// 3.根据File类对象创建对应的字节输入流
fileInputStream = new FileInputStream(file);

// 4.准备一个8KB字节缓冲数组
byte[] buf = new byte[1024 * 8];
int length = -1;

// 5.读取数组
while ((length = fileInputStream.read(buf)) != -1) {
System.out.println(new String(buf));
}

} catch (Exception e) {
e.printStackTrace();
} finally {
// 在finally代码中关闭资源
if (fileInputStream != null) {
try {
fileInputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}

Java编程基础之IO流_java_02

使用缓冲区速度会提高很多

FileOutputStream

FileOutputStream 文件操作输出字节流

Constructor构造方法

  • FileOutputStream(File file);
    根据File类对象创建对应的文件的输出字节流对象
  • FileOutputStream(String pathName);
    根据String类型文件路径创建对应的文件输出字节流对象

两个构造方法都是删除写方式,删除原文件后创建新文件写入数据

  • FileOutputStream(File file, boolean append);
    根据File类对象创建对应的文件的输出字节流对象
  • FileOutputStream(String pathName, boolean append);
    根据String类型文件路径创建对应的文件输出字节流对象

append为true表示追加写

Method成员方法

  • void write(int b);
    写入一个字节数据到当前文件中,参数是int类型,但是有且指挥操作对应的第八位数据
  • void write(byte[] buf);
    写入字节数组中的内容到文件中
  • void write(byte[] buf, int offset, int length);
    写入字节数组中的内容到文件中,从指定的offset开始,到指定长度length

以上方法会抛出IOException异常

实例:

Java编程基础之IO流_字节流_03

package obj_file;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class Demo8 {
public static void main(String[] args) {
copyTest();
}

public static void copyTest() {
FileInputStream fis = null;
FileOutputStream fos = null;

try {
// 1.创建文件输入字节流
fis = new FileInputStream("D:\\JavaCode\\test\\1.txt");
// 2.创建文件输出字节流
fos = new FileOutputStream("D:\\JavaCode\\test\\2.txt");

// 3.准备一个缓冲数组8KB
byte[] buf = new byte[1024 * 8];
int length = -1;

// 4.读取文件数据
while ((length = fis.read(buf)) != -1) {
fos.write(buf, 0, length);
}

} catch (IOException e) {
e.printStackTrace();
} finally {
// 先开的后关,先关的后开
if(fos != null) {
try {
fos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

if(fis != null) {
try {
fis.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}

Java编程基础之IO流_数组_04

文件操作字符流

字符流特征

字符流 = 字节流 + 解码过程

字符组合过程 => 对应当前环境编码集的一个字符

如果字符找不到,该数据无效,需要被删除

如果是字符内容操作,效率较高,如果是非字符操作效率较低

Java编程基础之IO流_数组_05

文件操作字符输入流

Constructor构造方法

  • FileInputStream(File file);
    这是根据提供的File类对象创建对应的文件操作输入字节流
  • FileInputStream(String pathName);
    这里是根据提供的String类型文件路径,创建对应的文件操作输入字节流

两个构造方法都会抛出异常,FileNotFoundException文件未找到异常

Method成员方法

  • int read();
    从文件中读取一个字节数据返回到方法外
    虽然返回值是一个int类型,但是在整个int类型中存储的数据是一个byte类型,有且只有低8位数据有效
  • int read(byte[] buf);
    读取文件的内容是存储在byte类型数组中,返回值是读取到的字节个数
  • int read(byte[] buf, int offset, int count);
    读取文件的内容是存储在byte类型数组中,要求从byte数组offset位置开始,到count长度结束,返回值是读取到的字节个数

这三个方法如果读取到文件末尾,返回值都是-1 EOF End Of File,都要抛出异常IOException

实例

统计字符串内每个英文字母的个数

package obj_file;

import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.Arrays;

public class Demo9 {
public static void main(String[] args) throws IOException {
FileReader fileReader = new FileReader(new File("D:\\JavaCode\\test\\1.txt"));

int[] counts = new int[52];
char[] buf = new char[1024];
int length = -1;

length = fileReader.read(buf);

for (int i = 0; i < length; i++) {
if (buf[i] >= 'A' && buf[i] <= 'Z') {
counts[buf[i] - 65] += 1;
} else if (buf[i] >= 'a' && buf[i] <= 'z') {
// 71 = 97 -26
counts[buf[i] - 71] += 1;
}
}

System.out.println(Arrays.toString(counts));
fileReader.close();
}
}

输出结果

Java编程基础之IO流_数组_06

结果有些抽象,但是计算很快,从左到右分别表示大写字母A到Z的个数,小写字母a到z的个数

文件操作字符输出流

Constructor

Java编程基础之IO流_字节流_07

Java编程基础之IO流_字节流_08

写入过程中,发生问题会产生IOException

package obj_file;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

public class Demo10 {
public static void main(String[] args) {
FileWriter fileWriter = null;

try {
fileWriter = new FileWriter(new File("D:\\JavaCode\\test\\test.txt"));

fileWriter.write("O");
fileWriter.write("C");
fileWriter.write("E");
fileWriter.write("A");
fileWriter.write("N");

} catch (IOException e) {
e.printStackTrace();
} finally {
if (fileWriter != null) {
try {
fileWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}

Java编程基础之IO流_数组_09

字符流文件拷贝

如果文件不是文本文件,拷贝可能因为编码方式不同,导致文件损坏

缓冲流

使用缓冲数组以后,整体的读取,写入效率提升很大

降低了CPU通过内存访问硬盘的次数

  • 字节输入缓冲
    BufferInputStream
  • 字节输出缓冲
    BufferInputStream
  • 字符输入缓冲
    BufferedReader
  • 字符输出缓冲
    BufferedWrite

注意:所有的缓冲流都没有任何的读取,写入文件能力,这里都需要对应的输入流和输出流来提供对应的能力

在创建缓冲流对象时,需要传入对应的输入流对象和输出流对象

底层就是提供了一个默认大小的缓冲数组,用于提高效率

字节缓冲流

  • 输入
    BufferedInputStream(InputStream in);
    这里需要的对象是一个字节输入流基类对象,同时也可以传入InputStream子类对象
  • 输出
    BuffedOutputStream(OutputStream out);
    这里需要的对象是一个字节输出流基类对象,同时也可以传入OutputStream子类对象

以上传入的InputStream和OutputStream都是用于提供对应文件的读写能力

实例:

package obj_file;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

public class Demo11 {
public static void main(String[] args) throws IOException {
// 1.找到对应文件
File file = new File("D:\\JavaCode\\test\\1.txt");

// 2.创建对应的FileInputStream输入流
FileInputStream fileInputStream = new FileInputStream(file);

// 3.根据文件操作字节输入流对象,创建对应的缓冲流对象
BufferedInputStream bis = new BufferedInputStream(fileInputStream);

// 4.读取数据过程,读取过程中使用的方法是FileInputStream提供的方法
int content = -1;
while ((content = bis.read()) != -1) {

}

bis.close();
}
}

运行速度大大提升

字节输入流缓冲效率问题

  1. 在BufferedInputStream底层中有一个默认容量为8KB的byte类型缓冲数组
  2. fill方法是一个操作核心
  • 从硬盘中读取数据,读取的数据容量和缓冲数组容量一致
  • 所有read方法,都是从缓冲数组中读取数据
  • 每一次读取数据之前,都会检查缓冲区内是否有数据,如果没有,fill方法执行,填充数据
  1. 利用缓冲,fill方法,可以极大的降低cpu通过内存访问硬盘的次数,同时程序操作的数据是在内存中进行交互的

字节输出缓冲效率问题

  1. BufferedOutputStream类对象,默认有一个8KB的byte类型缓冲数组
  2. 数据写入文件时并不是直接保存到文件中,而是保存在内容8KB字节缓冲数组中
  3. 如果8KB空间填满,会直接flush缓冲区,数据保存到硬盘中,同时清空整个缓冲区
  4. 在BufferedOutputStream关闭时,首先会调用flush方法,保存数据到文件,清空缓冲区,并且规划缓冲区占用内存,同时关闭缓冲流使用的字节输出流

字符缓冲流

  • BufferedReader
    字符缓冲输入流
    BufferedReader(Reader reader);
  • BufferedWriter
    字符缓冲输出流
    BufferedWriter(Writer writer)

实例:

package obj_file;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;import javax.lang.model.type.NullType;

public class Demo12 {
public static void main(String[] args) {
bufferedReader();
bufferedWriter();
}

private static void bufferedWriter() {
BufferedWriter bw = null;

try {
bw = new BufferedWriter(new FileWriter(new File("D:\\JavaCode\\test\\1-1.txt")));
bw.write("ocean");
bw.newLine();
bw.write("ocean");
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
bw.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

}

private static void bufferedReader() {
BufferedReader br = null;

try {
br = new BufferedReader(new FileReader(new File("D:\\JavaCode\\test\\1.txt")));

System.out.println(br.readLine());
System.out.println(br.readLine());
System.out.println(br.readLine());

} catch (IOException e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}

Java编程基础之IO流_数组_10

Java编程基础之IO流_字节流_11


举报

相关推荐

java基础之IO流

# Java基础——IO流

Java基础_IO流

JAVA基础IO流

Java之IO流

Java--IO流.基础

0 条评论