文件流
FileInputStream从文件系统中的文件获取输入字节。哪些文件可用取决于主机环境。
FileInputStream用于读取原始字节流,如图像数据。要读取字符流,请考虑使用FileReader。
一、IO
/*
* 数据结构
* 数据结构是计算机存储和组织不同数据的方式,不同数据结构根据存储的方式、操作以及特性加以区分
* 当前SE基础中接触到有以下几类:
* 数组;有序可重复,查询更改快,添加删除满
* 链表;有序可重复,查询更改满,添加删除快
* 散列表;无序不可重复,存储键值对,key唯一,value不可重复
* tree;无序不可重复,元素按照某种规则自动排序(Comparable、Comparator)
* 根据需求合理选择数据结构进行数据存储
*
* IO:流是一组有顺序,有起点终点的字节集合,是对数据传输的总称或抽象
* 就是数据之间的传递
* 本质:是数据的传输,根据 不同数据的传输特性,抽象为几类,方便操作数据
* 流中的操作对象是指内存中,当前操作的程序所涉及的数据
* 输入:往内存中导入数据
* 输出:从内存中写出数据
* I:input O:output
*
* 分类:
* 按照处理数据类型不同:分为字节流和字符流
* 按数据流向不同:分为输入流和输出流(相对于内存而言)
* 按功能分:分为节点流和处理流
* 节点流:直接操作数据源
* 处理流:对其他流进行处理
*
* 四大抽象类
* InputStream:
* OutputStream:
* Reader:
* Writer:
*
* 文件流
* 原始文件流:用于打开链接,操作数据
* 1 FileInputStream 字节输入
* 2 FileOutputStream 字节输出
* 3 FileReader 字符输入
* 4 FileWriter 字符输出
* */
public class _01_IO_Summary {
public static void main(String[] args) throws IOException {
// System.in是标准输入(控制台)
InputStream in = System.in;
System.out.println("请输入:");
int i = in.read();
// System.out是标准输出(控制台)
PrintStream out = System.out;
out.println(i);
}
}
二、FileInputStream
/*
* java.io.InputStream
* java.io.FileInputStream; 在原始文件中读取数据
* 首先需要找到文件:1 绝对路径 2 相对路径
* */
public class _02_IO_FileInputStream {
public static void main(String[] args){
// 若要在finally中关闭文件流,则需要在try语句块外初始化文件流
// 因为在try中初始化的话,如果try中出现异常,将不会在执行,那么
// finally中就有可能找不到文件流对象
FileInputStream inputStream = null;
try {
// 绝对路径
// FileInputStream inputStream = new FileInputStream("D:\IDEA\JavaSE\SE\src\com\tianl\IO\com\_02_IO_FileInputStream.java");
// FileInputStream inputStream = new FileInputStream("D:\\IDEA\\JavaSE\\SE\\src\\com\\tianl\\IO\\com\\_02_IO_FileInputStream.java");
// 相对路径,idea中是相对于module而言,此处module为SE。 ./ 可以省略
inputStream = new FileInputStream(
"./SE/src/com/tianl/IO/_01_FileInputStream/_02_IO_FileInputStream.java");
// 读取数据
// 读取一个字节,返回下一个字节的值,开始时光标在顶端如果到达文件末尾,就返回-1
int i1 = inputStream.read();
int i2 = inputStream.read();
System.out.println((char) i1);
System.out.println((char) i2);
} catch (IOException e) {
e.printStackTrace();
} finally {
// 此时还应判断文件流对象是否为空,如果为空,相当于使用null(不存在的对象)去调用close()方法
// 会报空指针异常,且这里需要用try catch语句块来处理可能抛出的空指针异常
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
// 使用read循环读取
public class _03_IO_FileInputStream {
public static void main(String[] args) {
// 自动关闭资源写法
try (FileInputStream inputStream = new FileInputStream(
"./SE/src/com/tianl/IO/_01_FileInputStream/_03_IO_FileInputStream.java");){
int temp = 0; // 临时变量
// 只要不读到文件末尾(inputStream.read()=-1),就输出
while (((temp=inputStream.read())!=-1)){
System.out.print((char) temp);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
/*
* read 方法重载
* 可以无参,可以传入一个byte数组
* read(byte[] b):使用字节数组来存储读取的数据,并一次返回
* 要么数组装满,要么达到文件末尾,可以提高读写速率
* 返回值是本次读取的字节个数,如果达到文件末尾,返回-1
* */
public class _04_IO_FileInputStream {
public static void main(String[] args) {
// 自动关闭资源写法
try (FileInputStream inputStream = new FileInputStream(
"./SE/src/com/tianl/IO/_01_FileInputStream/_03_IO_FileInputStream.java");){
// 准备数组
byte[] bytes = new byte[5];
// 返回本次读取的字节个数
int i1 = inputStream.read(bytes);
System.out.println(i1);
// byte[]转换为String输出
System.out.println(new String(bytes));
// 在读取一次
// 再次使用该数组读取的时候,数组内元素不会被清空,而是用新读取的数据替换原来的
int i2 = inputStream.read(bytes);
System.out.println(i2);
// 转换为String
// 如果直接把字节数组转换为String,有可能产生冗余数据(上次读取)
// 为了保证数据不冗余,利用read的返回值(本次读取的字节数)
// 只把本次读取的直接转换为String即可
// String参数(字节数组,从哪里开始(包含关系),字节个数)
System.out.println(new String(bytes,0,i2));
} catch (IOException e) {
e.printStackTrace();
}
}
}
/*
* 循环读取
* */
public class _05_IO_FileInputStream {
public static void main(String[] args) {
// 自动关闭资源
try (FileInputStream inputStream = new FileInputStream(
"./SE/src/com/tianl/IO/_01_FileInputStream/_04_IO_FileInputStream.java"
)){
// 准备数组
byte[] bytes = new byte[1024];
int temp = 0;
System.out.println(inputStream.available());
// 按照字节数组大小循环读,每次读取一个字节数组长度
while ((temp=inputStream.read(bytes))!=-1){
System.out.println(temp);
System.out.println(new String(bytes,0,temp));
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
/*
* 常用方法
* */
public class _06_IO_FileInputStream {
public static void main(String[] args) throws IOException {
// 1 创建流对象
FileInputStream inputStream = new FileInputStream(
"./SE/src/com/tianl/IO/_01_FileInputStream/_03_IO_FileInputStream.java");
// 2 可获得字节数
System.out.println(inputStream.available());;
// 3 读取字节数组
byte[] bytes = new byte[5];
inputStream.read(bytes);
System.out.println(new String(bytes));
System.out.println(inputStream.available());
// 4 跳过不读
inputStream.skip(20);
System.out.println(inputStream.available());
// 5 读取一个
System.out.println((char) inputStream.read());
// 6 关闭资源
inputStream.close();
}
}
三、FileReader
/*
* FileRead: 一次读取一个字符(两个字节),而Unicode编码也是两个字节
* 字符串输入流一般用于读取存文本文件,压缩包、图片等还是使用字节流
* read一样有方法重载
* read(): 读取一个字符,返回下一个字符数据,到达文件末尾返回-1
* read(char[] c): 读取一个字符数组,到达文件末尾返回-1
* 常用方法和FileInputStream一致
* */
public class _01_FileReader {
public static void main(String[] args) {
try (FileReader fileReader = new FileReader(
"./SE/src/com/tianl/IO/_01_FileInputStream/_03_IO_FileInputStream.java")){
// 字符数组
char[] chars = new char[512];
int temp;
// 循环读取
while ((temp=fileReader.read(chars))!=-1){
System.out.println(temp);
System.out.println(new String(chars,0,temp));
}
} catch (Exception e){
e.printStackTrace();
}
}
}
四、FileOutputStream
/*
* java.io.OutputStream
* java.io.FileOutputStream; 将文件中内容写出到硬盘中
* 输入流,找不到文件会报错。但输出流不会报错,会自动创建该文件
* 但不会创建文件夹(目录)
*
* 构造方法:
* FileOutputStream(String): 把内容输出到指定文件中,并覆盖原文件内容
* FileOutputStream(String, boolean): 如果第二个参数为true,把内容输出到指定文件中
* 并在原文件中追加数据
*
* 常用成员方法:
* void close(): 关闭输出流并释放资源
* void flush(): 刷新此输出流并强制写出所有缓冲的输出字节,避免数据遗漏
* void write(byte[] b): 将b.length个字节从指定的字节数组写入此输出流
* 想要输出字符串可以利用字符串的getByte()方法,把字符串转换为字节数组
* void write(byte[] b, int off, int len):
* 将指定直接从偏移量off开始的len个字节写入此输出流
* abstract void write(int b): 将指定字节写入此输出流
* */
public class _01_FileOutputStream {
public static void main(String[] args) throws IOException {
// 创建输出流对象,若没有传Boolean值,默认false,会覆盖原文件内容
// FileOutputStream outputStream = new FileOutputStream(
// "D:/111.txt"
// );
// 追加式写入
FileOutputStream outputStream = new FileOutputStream(
"D:/111.txt",true
);
for (int i = 0; i < 26; i++) {
outputStream.write(97+i);
}
String str = "Hello World\n";
byte[] bytes = str.getBytes(StandardCharsets.UTF_8);
outputStream.write(bytes);
// 刷缓存
outputStream.flush();
// 关闭流
outputStream.close();
}
}