Java day19
IO流
InputStream(输入流),OutputStream(输出流),都是相对于内存来说
流的分类,向内存写入数据为输入流,从内存向外输出为输出流
按照功能划分:
- 字节流
- 字符流
按照流向来划分:
- InputStream 输入流
- OutputStream 输出流
写流要注意的事项:
- 流对象都是java.io包下的
- 在使用流的时候有很多异常要进行处理
- 使用完流之后必须关闭资源
OutputStream:
- 是一个抽象类,不能实例化
- 字节输出流的所有类的超类
子类:
- ByteArrayOutputStream:字节输出流
- FileOutputStream:文件输出流
- FilterOutputStream:过滤器输出流
- ObjectOutputStream:对象输出流
- PipedOutputStream:管道输出流
公有的方法:
- public void close()throws IOException:关闭资源
- public void flush()throws IOException:刷新缓冲区,强制性把内存中的数据刷新到硬盘
- public void write(byte[] b)throws IOException:将数据保存到保存到字节数组中,b就相当于一个缓冲区
- public void write(byte[] b, int off, int len):将数据保存到字节数组中 ,给定开始位置与长度
- public void write(int b):将指定的字节写入此输出流
FileOutputStream:
将数据写入到文件中
构造方法:
- FileOutputStream(File file):file是一个文件对象
- public FileOutputStream(String name)throws FileNotFoundException:name传递的是文件的路径,可以绝对,可以相对
- FileOutputStream(File file, boolean append):append表示是否覆盖,true表示不覆盖 ,默认是表示覆盖的false.
在实例化对象的时候,构造方法做了三件事:
- 实例化FileOutputStream对象
- 会创建一个空的文件
- FileOutputStream对象指向要写入的文件
输出流向文件写入数据的步骤:
- 实例化FileOutputStream对象
- 调用其write()方法
- 关闭资源
注意点:
- 在写数据的数据,如果是负数: 编码格式是gbk的时候,两个负数组成一个中文,编码格式是utf-8的时候,三个负数的时候成功一个中文
- 如果需要使用FileOutputStream写字符串,先必须把字符串转换成一个字节数组
InputStream
- 这是一个抽象类是,肯定也不能实例化
- 是输入字节流的所有类的超类。
子类:
- ByteArrayInputStream:字节输入流
- FileInputStream:文件输入流
- ObjectInputStream:对象输入流
公有的方法:
- public void close()throws IOException:关闭资源
- public int available()throws IOException:返回从该输入流中可以读取的字节数的估计值
- public abstract int read()throws IOException:从输入流读取数据的下一个字节,返回值是当前的数据,如果达到流的末尾,返回-1.
- public int read(byte[] b)throws IOException 从输入流读取一些字节数,并将它们存储到缓冲区b
FileInputStream
将数据写入到文件中
构造方法:
- public FileInputStream(File file)throws FileNotFoundException:file表示要读取的文件对象
- public FileInputStream(String name)throws FileNotFoundException:name表示要读取的文件的路径
在实例化对象的时候会做三件事 :
- 实例化FileInputStream
- 判断这个文件是否存在,(不存在抛异常)
- 把FileInputStream对象指向执行文件
输入流读取文件中的数据的基本步骤:
- 实例化FileInputStream
- 调用其读方法
- 关闭资源
一次性读取多个数据的时候,注意点:
- byte数组一般是1024倍数
- 读取到数据都缓冲到字符数据里,如果一次读取两个字节,如果只存在一个,打印的数据也是两个字节,把前面的数据会填充出来
- read(byte[] b)一次读取多个字节至b字节数组,返回值是读取的字节的有效的个数
两种读取方式的区别:
-
read()
- 一个一个字节进行读取
- 读取的数据就是其返回值
- 返回的是具体的数据
-
read(byte[] b)
- 一次性可以读取多个字节
- 读取的数据就存在 数组
- 返回的是读取字节的有效个数
public class Test {
public static void main(String[] args) throws IOException {
byte[] bytes = "好好学习".getBytes("utf-8");
OutputStream out = new FileOutputStream(new File("E:/test.txt")); //创建输出流
out.write(bytes,0,bytes.length); //数据写入输出流
out.close(); //关闭流
InputStream in = new FileInputStream(new File("E:/test.txt")); //创建输入流
byte[] b1 = new byte[in.available()];
int count = in.read(b1); //数据写入byte数组
System.out.println(new String(b1,"utf-8")); //解析成字符串
in.close(); //关闭流
}
}
//复制文件
public class Test {
public static void main(String[] args) {
FileInputStream in = null;
FileOutputStream out = null;
try {
in = new FileInputStream("t.txt");
out = new FileOutputStream("tt.txt");
byte[] bytes = new byte[1024*8];
int len;
while((len=in.read(bytes))!=-1){ //数据写入byte数组,并记下写入的有效数字
out.write(bytes,0,len); //数据写入输出流
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if(out != null){
out.close(); //关闭输出流
}
if (in!=null){
in.close(); //关闭输入流
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
BufferedInputStream
带缓冲区输入流
- 自带缓冲区,它的底层有一个缓冲的数据 数组的大小是8192个字节
- 本身没有读取的功能,只是对流进行了封装,读写还是借助的InputStream.
构造方法:
- public BufferedInputStream(InputStream in)
BufferedOuputStream
带缓冲区的输出流:
构造方法:
- public BufferedOutputStream(OutputStream out)
方法:
- void flush():刷新缓冲输出流。
- void write(byte[] b, int off, int len):从指定的字节数组写入len个字节,从偏移off开始到缓冲的输出流。
- void write(int b):指定的字节写入缓冲的输出流。自带缓冲区的流对象,写数据的时候,需要刷新缓冲区flush()
flush()与close()
- close()底层调用了flush()
- 调用flush()之后,这个流对象还可以使用,但是调用close之后流对象就不能使用
- close()主要是用于关闭流资源,flush()主要是刷新缓冲区,也就是把内存的数据刷新到磁盘里
public class Test {
public static void main(String[] args) throws IOException {
FileInputStream in = new FileInputStream("tt.txt");
BufferedInputStream bIn = new BufferedInputStream(in);
int bit;
while((bit=bIn.read())!=-1){ //数据写入bit
System.out.println((char)bit); //输出
}
bIn.close(); //依次关闭流
in.close();
}
}