Java-IO Streams - Byte/Character Input/Output Streams

顶层父类:
java.io.OutputStream        字节输入流
java.io.InputStream         字节输出流
java.io.Reader              字符输入流
java.io.Writer              字符输出流


换行符号:
windows:    \r\n
linux:      \n
mac:        \r


使用字节流读取中文文件:
1个中文
GBK(中文码表):            占用2个字节
UTF-8(国际标准码表):      占用3个字节
IO流的选取:

字节输入流:InputStream 所有字节输入流的父类
	- FileInputStream:字节非缓冲输入流,效率低,不推荐直接使用
	- BufferedInputStream:字节缓冲输入流,效率高,推荐使用
	- ObjectInputStream:对象输入流,当需要从文件中读取自定义对象时使用

字节输出流:OutputStream 所有字节输出流的父类
	- FileOutputStream:字节非缓冲输出流 效率低,不推荐直接使用
	- BufferedOutputStream:字节缓冲输出流,效率高,推荐使用
	- ObjectOutputStream:对象输出流,当需要保存自定义对象到文件中时使用
	- PrintStream:字节打印流,当希望原样输出各种数据类型的值时使用

字符输入流:Reader 所有字符输入流的父类
	- FileReader:字符非缓冲输入流,效率低,不推荐直接使用
	- BufferedReader:字符缓冲输入流,效率高,推荐使用
	- InputStreamReader:字符转换输入流,当需要修改默认码表去读数据时使用

字符输出流:Writer 所有字符输出流的父类
	- FileWriter:字符非缓冲输出流 ,效率低,不推荐直接使用
	- BufferedWriter:字符缓冲输出流,效率高,推荐使用
	- OutputStreamWriter:字符转换输出流,当需要修改码表去输出数据时使用
	- PrintWriter:字符打印流,当希望原样输出各种数据类型的值时使用

如何选择流
	 如果清楚要操作的文件类型是文本文件,则强烈推荐字符流。
	 如果不清楚要操作的文件类型是什么类型的,则只能选择字节流
		

 

OutputStream        字节输出流

子类共性的成员方法:
public void close()
public void flush()
public void write(byte[] b)
public void write(byte[] b,int off,int len)
public abstract void write(int b)

写入数据的原理(内存-->硬盘):
java程序-->JVM-->OS-->OS调用写数据的方法-->把数据写入文件中


java.io.FileOutputStream extends OutputStream
FileOutputStream文件字节输出流
作用:把内存中的数据写到硬盘中
构造方法:(作用相同)
FileOutputStream(String name)      创建一个向 具有指定名称的文件 中写入数据的输出文件流
FileOutputStream(File file)        创建一个向 指定File对象表示的文件 中写入数据的文件输出流

追加写(续写)使用两个参数的构造方法
FileOutputStream(String name,boolean append)
FileOutputStream(File file,boolean append)
boolean append:追加写开关
true:      创建对象不会覆盖源文件,继续在文件末尾追加写数据
false:     创建一个新文件,覆盖文件

字节输出流使用步骤:
1.创建一个FileOutputStream对象,构造方法中传递写入数据的目的地
2.使用FileOutputStream对象中的方法write,把数据写入到文件中
3.释放资源(流使用会占用一定的内存,使用完毕要把内存清空,提高程序效率)


写入字符的方法:可以使用String类中的方法,把字符串转换为字节数组
    byte[] getBytes()


windows输入换行:    fos.write("\r\n".getBytes());
InputStream        字节输入流

子类共性成员方法:
int read()
int read(byte[] b)
void close()

读取数据的原理(硬盘-->内存):
java程序-->JVM-->OS-->OS调用读取数据的方法-->读取文件


java.io.FileInputStream extends InputStream
FileInputStream文件字节输入流
作用:把硬盘中的数据读取到内存中使用
构造方法:
FileInputStream(String name)
FileInputStream(File file)

字节输出流使用步骤:
1.创建一个FileInputStream对象,构造方法中绑定要读取的数据源
2.使用FileInputStream对象中的方法read,读取文件
3.释放资源

字节输入流一次读取多个字节的方法:
    int read(byte[] b) 从输入流中读取一定数量的字节,并将其存储在缓冲区数组b中
1.方法的参数byte[]起到缓冲作用,存储每次读到的多个字节.(长度一般定义为1024或1024的整数倍)
2.int返回值是每次读取的有效字节个数


读取字符的方法:使用String类的构造方法:
    String(byte[] bytes)                              把字节数组转换为字符串      
    String(byte[] bytes,int offest,int length)        把字节数组的一部分转换为字符串
Reader      字符输入流

子类共性成员方法:
int read()
int read(char[] cbuf)
void close()

java.io.FileReader extends InputStreamReader extends Reader
FileReader:文件字符输入流
作用:把硬盘文件中的数据以字符的方式读取到内存中

构造方法:
FileReader(String fileName)
FileReader(File file)

字符输入流的使用步骤:
1.创建FileReader对象,构造方法中绑定要读取的数据源
2.使用FileReader对象中的方法read读取文件
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)
void flush()
void close()

java.io.FileWriter extends OutputStreamWriter extends Writer

FileWriter:文件字符输出流
作用:把内存中字符数据写入到文件中

构造方法;
FileWriter(File file)
FileWriter(String filename)

追加写(续写)使用两个参数的构造方法(同字节输出流)
FileWriter(String fileName,boolean append)
FileWriter(File file,boolean append)
boolean append:追加写开关
true:      创建对象不会覆盖源文件,继续在文件末尾追加写数据
false:     创建一个新文件,覆盖文件


注意:字符输出流与字节输出流最大的区别:
字节输出流可以将数据直接写入文件,
字符输出流需要先将文件写入内存缓冲区(字符转换为字节)
再用flush将缓冲区中数据刷新到文件中

字符输出流的使用步骤:
1.创建FileWriter对象,构造方法中绑定要写入数据的目的地
2.使用FileWriter中的write方法,把数据写入到内存缓冲区中(字符转换为字节的过程)
3.使用FileWriter中的flush方法,将内存缓冲区中的数据,刷新到文件中
4.释放资源
因为内置缓冲区的原因,如果不关闭输出流,无法写出字符到文件中。
但是关闭流对象后,就无法继续写出数据。
如果既想写出数据,又想继续使用流,就要使用flush方法

flush方法和close方法的区别;
flush:  刷新缓冲区,流对象可以继续使用
close:  先刷新缓冲区,然后通知系统释放资源,流对象不可以再被使用了
JDK7的新特性:
    在try后可增加一个(),在括号中可以定义流对象
    这个流对象的作用于就在try中有效
    try中的代码执行完毕,会自动把流对象释放,不用写finally
格式:
    try(定义流对象;定义流对象...){
        可能出现异常的代码
    }catch(异常类型名 常量名){
        异常的处理逻辑
    }



JDK9的新特性:
    try的前边可以定义流对象
    在try后的()中可以直接引入流对象的名称(变量名)
    在try代码执行完毕之后,流对象也可以释放掉,不用写finally
格式:
    A a = new A();
    B b = new B();
    try(a,b){
        可能会出现异常的代码
    }catch(异常类变量 变量名){
        异常的处理逻辑
    }

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325810901&siteId=291194637