IO流

IO流作用

io流用来操作文件中的数据的,如果文件不存在,可自动创建,不能用来操作文件夹

File用来操作文件或者文件夹的,不能操作文件中的数据。

 

字节流

字节输出流:OutputStream

所有字节输出流的超类

成员方法:

- public void close() :关闭此输出流并释放与此流相关联的任何系统资源。

- public void flush() :刷新此输出流并强制任何缓冲的输出字节被写出。

- public void write(byte[] b):将 b.length字节从指定的字节数组写入此输出流。

- public void write(byte[] b, int off, int len) :将指定 byte 数组中从偏移量 off 开始的

len个字节写入此输出流。

- public abstract void write(int b) :将指定的字节输出流。

文件字节输出流:FileOutputStream extends OuputStream

1.构造方法:

FileOutputStream(String name)创建一个向具有指定名称的文件中写入数据的输出文件流。

FileOutputStream(File file) 创建一个向指定 File 对象表示的文件中写入数据的文件输出流。

2.续写和换行

续写:boolean append 设置为true续写,

FileOutputStream(String name, boolean append)

FileOutputStream(File file, boolean append)

写换行:写换行符号

windows:\r\n

linux:/n

mac:/r

字节输入流:InputStream

所有字节输入流的父类

成员方法:

int read() 从输入流中读取数据的下一个字节,返回的int代表读取的字节

int read(byte[] b) 从输入流中读取一定数量的字节,并将其存储在缓冲区数组 b 中。

返回值int为每次读取到的有效字节个数,结束返回-1

byte[] 数组为我们每次读取到的数据存储的地方

void close() 关闭此输入流并释放与该流关联的所有系统资源。

文件字节输入流:FileInputStream extends OutputSream

构造方法:

FileInputStream(File file)

FileInputStream(String name)

 

案例1:字节流单个字节读写

FileInputStream fis = new FileInputStream(new File(..));

FileOutputStream fos = new FileOutputStream(new File(...))

int len ;

while((len = fis.read()) != -1){

fos.write(len);

}

fos.close();

fis.close();

案例2:字节流字节数组读写

FileInputStream fis = new FileInputStream(new File(..));

FileOutputStream fos = new FileOutputStream(new File(...))

int len ;

byte[] bytes = new byte[1024];

while((len = fis.read(bytes) != -1){

fos.write(bytes, 0, len);

}

fos.close();

fis.close();

 

字符流

需要把字节手动转换为字符的时候,使用字符流

字符输出流:Writer

所有字符输出流的超类

成员方法:

- void write(int c) 写入单个字符。

- void write(char[] cbuf)写入字符数组。

- abstract void write(char[] cbuf, int off, int len)写入字符数组的某一部分,

off数组的开始索引,len写的字符个数。

- void write(String str)写入字符串。

- void write(String str, int off, int len) 写入字符串的某一部分,off字符串的开始索引,

len写的字符个数。

- void flush()刷新该流的缓冲。

- void close() 关闭此流,但要先刷新它。

文件字符输出流:FileWriter extends OutputStreamWriter extends Writer

1.构造方法

FileWriter(File file)根据给定的 File 对象构造一个 FileWriter 对象。

FileWriter(String fileName) 根据给定的文件名构造一个 FileWriter 对象。

2.换行与续写

同字节输出流一样

字符输入流:Reader

所有字符输入流的超类

成员方法:

int read(); 读取的是单个字符在ASCII码中对应的int标号

int read(char[] arr); 从输入流中读取一定数量的字符,并将其存储在缓冲区数组 arr 中。

返回值int为每次读取到的有效字符个数,结束返回-1

char[] 数组为我们每次读取到的数据存储的地方

void close(); 关闭此流,但在关闭前会先刷新它。

文件字符输入流:FileReader extends InputStreamReader extends Writer

1.构造方法

FileReader(String fileName)

FileReader(File file)

 

案例3:字符流单个字符读写

FileWriter fw = new FileWriter(new File(...));

FileReader fr = new FileReader(new File(..));

int len;

while((len = fr.read()) != -1){

fw.write(len);

}

fw.close();

fr.close();

案例4:字符流字符数组读写

FileWriter fw = new FileWriter(new File(...));

FileReader fr = new FileReader(new File(..));

int len;

char[] arr = new char[1024];

while((len = fr.read(arr)) != -1){

fw.write(arr, 0, len);

}

fw.close();

fr.close();

 

Properties集合,唯一一个与流结合的集合

作用:读取配置文件

构造函数:

Properties()

成员方法:

从文件中加载数据方法,通过流参数

void load(InputStream inStream) 从输入流中读取属性列表(键和元素对)。

void load(Reader reader) 按简单的面向行的格式从输入字符流中读取属性列表(键和元素对)

将流中的数据已键值对的形式写入文件中

void store(OutputStream out, String comments)

void store(Writer writer, String comments)

comments - 属性列表的描述。

操作键值对的方法

String getProperty(String key) 用指定的键在此属性列表中搜索属性

Object setProperty(String key, String value) 调用 Hashtable 的方法 put

Set<String> stringPropertyNames() 返回此属性列表中的键集,

 

案例5:读取配置文件

Properties prop = new Properties();

prop.load(new FileInputStream(..));

String value = prop.getProperty(key);

 

 

缓冲流(装饰者模式)

作用:提高读写效率,和我们自己定义的byte[]或者char[]有共通之处

字节缓冲流

字节缓冲输出流 BufferedOutputStream extends OutputStream

成员方法

使用从父类OutputStream继承来的即可

构造方法

BufferedOutputStream(OutputStream out)

BufferedOutputStream(OutputStream out, int size)

参数:

OutputStream out:字节输出流

我们可以传递FileOutputStream,缓冲流会给FileOutputStream增加一个缓冲区,

提高FileOutputStream的写入效率

int size:指定缓冲流内部缓冲区的大小,不指定默认

字节缓冲输入流 BufferedInputStream extends InputStream

成员方法

使用从父类InputStream继承来的即可

构造方法

BufferedInputStream(InputStream in)

BufferedInputStream(InputStream in, int size)

参数:

InputStream in:字节输入流

我们可以传递FileInputStream,缓冲流会给FileInputStream增加一个缓冲区,

提高FileInputStream的读取效率

int size:指定缓冲流内部缓冲区的大小,不指定默认

 

案例6:字节缓冲流读写文件(单个字节,字节数组同上)

BufferedInputStream bis = new BufferedInputStream(new FileInputStream(...));

BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(..));

int len ;

while((len = bis.read()) != -1){

bos.write(len);

}

bos.close();

bis.close();

 

字符缓冲流

字符缓冲输出流 BufferedWriter extends Writer

成员方法

使用从父类Writer继承来的即可

构造方法

BufferedWriter(Writer out)

BufferedWriter(Writer out, int size)

参数:

Writer out:字符输出流

我们可以传递FileWriter,缓冲流会给FileWriter增加一个缓冲区,

提高FileWriter的写入效率

int size : 指定缓冲区的大小,不写默认大小

特有方法

void newLine(); 写入一个系统换行符

字符缓冲出入流 BufferedReader extends Reader

成员方法

使用父类Reader继承来的即可

构造方法

BufferedReader(Reader in)

BufferedReader(Reader in, int size)

参数

Reader in:字符输入流

我们可以传递FileReader,缓冲流会给FileReader增加一个缓冲区,

提高FileReader的读取效率

int size : 指定缓冲区的大小,不写默认大小

特有方法

String readLine() 读取一行文本,不包括换行符,没有返回null

 

案例7:缓冲字符流读写文件(使用特有方法,父类方法同上)

BufferedReader br = new BufferedReader(new FileReader(..));

BufferedWriter bw = new BufferedWriter(new FileWriter(...));

String len ;

while((len = br.readLine()) != null){

bw.writer(len);

bw.newLine();//读取一行时没有换行符,所以要单独写

}

bw.close();

br.close();

 

转换流(字符流)

前提:磁盘中存储的都是:字节(二进制)

码表:ASCII码 基础表,被后面所有码表兼容

GBK 一个中文两个字节

UTF-8 一个中文三个字节

作用:字节流可以操作一切数据,但是在操作中文这种文本文件时,一次读一个字节,会把中文拆开了,无法阅读,不好进行后续操作,要操作的话需要手动进行转换;所以出现字符流,一次读取一个字符,但是磁盘中的都是字节,就涉及到字节和字符之间的转换,我们前面学习的FileWriter和FileReader就可子进行转换,但是他们使用的都是默认码表,无法控制,如果编码和解码不同就会出现乱码;所以出现了转换流,FileWriter和FileReader继承自转换流,如果转换流没有指定编码表,会使用默认码表,效果和FileWriter和FileReader一样。

InputStreamReader:字节转向字符的桥梁

成员方法

使用从父类中继承的即可

构造方法:

OutputStreamWriter(OutputStream out)创建使用默认字符编码的 OutputStreamWriter。

OutputStreamWriter(OutputStream out, String charsetName) 创建使用指定字符集的

OutputStreamWriter。

参数:

OutputStream out:字节输出流,可以用来写转换之后的字节到文件中

String charsetName:指定的编码表名称,不区分大小写

OutputStreamWriter:字符转向字节的桥梁

成员方法

使用从父类中继承的即可

构造方法:

InputStreamReader(InputStream in) 创建一个使用默认字符集的 InputStreamReader。

InputStreamReader(InputStream in, String charsetName) 创建使用指定字符集的

InputStreamReader。

参数:

InputStream in:字节输入流,用来读取文件中保存的字节

String charsetName:指定的编码表名称,不区分大小写,

 

案例8:转换流读写文件(单个字符,字符数组同上)

//读GBK编码的文件,使用UTF-8编码再写

InputStreamReader isr = new InputStreamReader(new FileReader(..), "GBK");

OutputStreamWriter osw = new OutputStreamWriter(new FileWriter(..), "UTF-8");

int len ;

while((len = isr.read()) != -1){

osw.write(len);

}

isr.close();

osw.close();

 

序列化流(字节流)

作用:用来操作对象的,将对象存储到文件中,也可以从文件中读取对象

前提:对象想要能序列化和反序列化,要实现Serializable接口,该接口没有任何方法,只是作为一个能序列化的标记

对象的序列化流:ObjectOutputStream extends OutputStream

作用:把对象以流的方式写到文件中保存

构造方法:

ObjectOutputStream(OutputStream out)

成员方法:

重写了父类方法

特有方法:

void writeObject(Object obj) : 将指定的对象写入 ObjectOutputStream

 

对象的反序列化流:ObjectInputStream extends InputStream

作用:把文件中保存的对象,以流的方式读取出来

构造方法:

ObjectInputStream(InputStream in)

成员方法:

重写父类的方法

特有方法:

Object readObject() : 从 ObjectInputStream 读取对象

 

案例9:序列化和反序列化

ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(..));

ObjectInputStream ois = new ObjectInputStream(new FileInputStream(..))

//Person类已实现Serializable接口

Person person = new Person(...);

oos.writeObject(person);

Object o = ois.readObject();

Person p = (Person)o;

 

打印流

字节打印流(PrintStream)和字符打印流(PrintWriter),操作方法类似,这里介绍一下字节打印流

PrintStream extends OutputStream

特点

1.只负责数据的输出,不负责数据的读取

2.与其他输出流不同,PrintStream不会抛出IOException异常

成员方法

使用继承父类的方法即可

特有方法

void print(任意类型的值)

void println(任意类型的值并换行)

源码:public void print(int i) {

write(String.valueOf(i));

}

构造方法:

PrintStream(File file):输出的目的地是一个文件

PrintStream(OutputStream out):输出的目的地是一个字节输出流

PrintStream(String fileName) :输出的目的地是一个文件路径

注意:

如果使用继承自父类的write方法写数据,那么查看数据的时候会查询编码表 97->a

如果使用自己特有的方法print/println方法写数据,写的数据原样输出 97->97

可以改变数据的流向

默认数据打印在控制台

static void setOut(PrintStream out) 改变流向

用法:

System.out.println("Hello World") //打印在控制台

PrintStream ps = new PrintStream(new FileInputStream("\\a.txt"));

System.setOut(ps);

System.out.println("Hello World") //打印在a.txt中

 

标准流

Java定义了一个标准流,就是流的默认读取和默认输出

System类中

static InputStream in 标准输出流 System.in 默认读取控制台

static OutputStream out 标准输入流 System.out 默认输出到控制台

改变默认的读取或输出的流向

static void setIn(InputStream in)

static void setOut(PrintStream out)

 

IO异常处理

案例10:IOException的处理方式

FileWriter fw = null;

FileReader fr = null;

try{

fw = new FileWriter(new File(...));

fr = new FileReader(new File(..));

int len;

char[] arr = new char[1024];

while((len = fr.read(arr)) != -1){

fw.write(arr, 0, len);

}catch(IOException e){

e.print...

}finally{

if(fw != null){

try{

fw.close();

}catch(IOException e){

e.pej...

}

}

if(fw != null){

try{

fr.close();

}catch(IOException e){

e.pej...

}

}

}

 

 

 

注:

1.flush方法和close方法的区别

flush :刷新缓冲区,流对象可以继续使用。

close : 先刷新缓冲区,然后通知系统释放资源。流对象不可以再被使用了。

缓冲区满了,数据会自动刷新,所以一般我们只会在最后调用一下close方法

2.JDK7的新特性

在try的后边可以增加一个(),在括号中可以定义流对象

那么这个流对象的作用域就在try中有效

try中的代码执行完毕,会自动把流对象释放,不用写finally

格式:

try(定义流对象;定义流对象....){

可能会产出异常的代码

}catch(异常类变量 变量名){

异常的处理逻辑

}

前提:

在try中的对象,必须要去实现Closeable接口,重写close方法.

当我们运行结束之后他会自动调用close();

3.JDK9新特性

try的前边可以定义流对象

在try后边的()中可以直接引入流对象的名称(变量名)

在try代码执行完毕之后,流对象也可以释放掉,不用写finally

格式:

A a = new A();

B b = new B();

try(a,b){

可能会产出异常的代码

}catch(异常类变量 变量名){

异常的处理逻辑

}

4.

FileReader fr = new FileReader("d:\a.txt");

FileWriter fw = new FileWriter("d:\a.txt");

读写操作

。。。。。

结果:空

原因:new FileWriter()时,如果文件不存在,创建新的,如果存在,将文件内容清空,除了续写

5.read()方法返回值int的代表的意义

字节流,一次读取一个字节

int 代表的是读取的字节

字符流,一次读取一个字符

int 代表的是读取的字符

使用数组读取

int 代表的是每次读取的个数

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值