Day18 IO流
1. 流概述
1.1 概念:
数据传递的统称 流
流是一组有顺序的,有起点和终点的字节集合,是对数据传输的 总称或抽象。即数据在两设备间的传输称为流,流的本质是数据传输, 根据数据传输特性将流抽象为各种类,方便更直观的进行数据操作。
代码案例1:
```java
public static void main(String[] args) throws IOException{
//标准输入
InputStream in = System.in;
//读数据,程序到这里,就等待输入
int s = in.read();
//标准输出流,是个打印流,但是Output
PrintStream out = System.out;
out.println(s);
}
1.2 分类
按处理数据的类型不同,分为:**字节流和字符流**
文件——内存——文件
先输入后输出
按功能不同,分为节点流和处理流
节点流:直接操作数据源
处理流:对其他流进行处理
1.3 ***抽象类
字节流 字符流
输入流:InputStream Reader
输出流:OutputStream Writer
1.4 文件流
1.4.1 InputStream
常用方法:
void close() 关闭此输入流并释放与该流关联的索引系统资源
abstract int read() 从输入流读取下一个数据字节
int read(byte[] b) 从输入流中读取一定数量的字节并将其存储在缓 冲区数组b中
int read(byte[] b,int off, int len) 将输入流中最多len个数据字节读入字节数组
public static void main(String[] args) throws IOException{
//创建字节输入流对象
FileInputStream fs = new FileInputStream("E:\\test.txt");
//会匹配当前的操作系统
System.out.println(File.separator);
//read 读取下一个字节,如果到达文件末尾返回-1,默认光标在顶端,向下一位移动,并返回下一位的值。
int i1 = fs.read();
int i2 = fs.read();
int i3 = fs.read();
int i4 = fs.read();
System.out.println((char)i1);
System.out.println((char)i1);
System.out.println((char)i1);
System.out.println((char)i1);
//循环读取
int temp = 0;
if((temp=fs.read())!= -1){
System.out.println((char)temp);
}
}
代码案例2:
```java
public static void main(String[] args){
//提升变量值main方法中,否则finally中访问不到
//局部变量没有默认值。并且try有不执行情况,所以默认值null
FileInputStream fs = null;
try{
//创建对象并获取文件流
fs = new FileInputStream("E:\\test.txt");
//循环读取
int temp = 0;
while((temp=fs.read()) != -1){
System.out.println((char)temp);
}
}catch(Exception e){
e.printStackTrace();
}finally{
//关闭资源
try{
if(fs != null){
fs.close();
}
}catch(IOException e){
e.printStackTrace();
}
}
}
代码案例3 优化案例2:
public static void main(String[] args){
try(
//创建对象并获取文件流
FileInputStream fs = new FileInputStream("E:\\test.txt");
){
//循环读取
int temp = 0;
while((temp=fs.read()) != -1){
System.out.println((char) temp);
}
}catch(Exception e){
e.printStackTrace();
}
}
方法重载:
read():读取下一个字节的值,并返回,如果到达文件结尾返回-1
read(byte[] bytes):可以传入一个字节数组,返回当前次读取到的字节个数,如果到达文件结尾,返回-1
代码案例:
public static void main(String[] args){
try(
//创建文件输入流对象
FileInputStream fs = new FileInputStream("E:\\test.txt");
){
//循环读取
byte[] bytes = new byte[100];
int temp = 0;
while((temp=fs.read(bytes)) != -1){
//不能直接把数组转换为字符串,否则有多种情况导致数据不正确
//当数组长为1000时,字节长为100,此时数组中还有900个0,如果全部转换为字符串数据不准确
//当数组长为100时,字节长为150,此时转换第二次会把第一次的后50个添加到第二次的前50个
//最好是读多少转换多少,该方法返回值就是当前次读取的个数
System.out.println(new String(bytes,0,temp));
}
}catch(Exception e){
e.printStackTrace();
}
}
OutputStream
输出流如果目标文件不存在,会自动创建该文件,注意,不会创建目录,如果目录不存在就会报错;
步骤:1 打开流 2 写出(追加写入/覆盖写入) 3刷缓存 4关闭
构造方法:
FileOutputStream(String):只传递需要写出的文件路径,默认覆盖写出
FileOutputStream(String,boolean):只传递需要写出的文件路径,第二个参数如果是true就追加写出,false是覆盖写出
写出方法:
write(int b) 写出一个字节
write(byte[] bytes):把一个数组内容都写出
write(byte[] bytes,int off,int length):写出数组中一部分,起始值个数
代码案例:
public static void main(String[] args) throws IOException{
//创建对象,默认覆盖写出
//FileOutputStream fs = new FileOutputStream("E:\\test.txt");
//追加
FileOutputStream fs = new FileOutputStream("E:\\test1.txt",true);
//写出单个内容
fs.write(97);
byte[] bytes = {48,49,50,51};
//写出整个数组
fs.write(bytes);
//写出一部分
fs.write(bytes,0,3);
//写出字符串
String str = "你好吗";
bytes = str.getBytes();
fs.write(bytes);
//刷缓存
fs.flush();
//关闭
fs.close();
}
1.4.2 Reader
常用方法:
abstract void close() 关闭该流
int read() 读取单个字符
int read(char[] cbuf) 将字符读入到数组
int read(char[] cbuf, int off,int len) 将字符读入数组的某一部分
FileReader:字符输入流可以解决输入数据汉字的乱码问题
一般用于纯文本文件,像压缩包,图片,视频,音乐,还是要使用字节,使用字符会出问题。
代码案例:
public static void main(String[] args){
try{
//打开字符输入流
FileReader fr = new FileReader("E:\\test.txt");
char[] chars = new char[100];
int temp = 0;
while((temp = fr.read(chars)) != -1){
System.out.println(new String(chars,0,temp));
}
}catch(Exception e){
e.printStackTrace();
}
}
1.4.3 Writer
常用方法:
void write(int c) 写入单个字符
void write(char[] cbuf) 写入字符数组
abstract void write(char[] cbuf,int off,int len) 写入字符数组的某一部分
void write(String str) 写入字符串
void write(String str,int off,int len) 写入字符串的某一部分
Writer append (char c) 将指定字符串添加此Writer
abstract void flush() 刷新该流的缓冲
abstract void close() 关闭此流,但要先刷新
代码案例:
public static void main(String[] args){
//字符输出流,用于同字节输出流,只是写出方法是字符数组和字符串
try(
FileWriter fw = new FileWriter("E:\\test.txt");
){
fw.write("你好吗");
//换行符
fw.write("\n");
fw.write("吃了吗");
fw.flush();
}catch(Exception e){
e.printStackTrace();
}
}