开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第1天,[点击查看活动详情]
IO流
流:就是搭建内存到硬盘之间的一个数据交互的桥梁。
按流向划分:输入流,硬盘->内存;输出流,内存->硬盘。
按数据划分:字节流,字符流。
文件:二进制文件,文本文件...最终都以二进制的形式存储在硬盘里。以字节操作二进制文件,以字符操作文本文件。
字符=字节+码表。
字符流=字节流+编码【无论是文本文件还是二进制文件,对文件的最终操作都是以字节流的形式操作】
基本的流:字节输入流InputStream,字节输出流OutputStream,字符输入流Reader,字符输出流Write。
FileReader=FileInputStream+InputStreamReader.
字节流
InputStream:抽象类,字节输入流,超类。\
OutputStream:抽象类,字节输出流,超类。
1,创建一个文件的输入流
2,read()读取了一个字节数据。和迭代器的next有些像。
3,write(int b),write(byte[] b),写入
FileOutputStream s=new FileOutputStream("a.txt",true);
String q="Hello word";
s.write(q.getBytes());
有true在文件的原基础上增加,没有的话直接覆盖。
FileOutputStream :文件不存在,先创建。
FileInputStream:文件存在,报错。
BufferedInputStream:提高读入效率BufferedInputStream fos=new BufferedInputStream(fis).创建了一个字节输入流的缓冲流。
BufferedOutputStream:提高写出效率
接下来:
byte[] buf =new byte[1024];
int len = 0;
while((len=bis.read(buf))!=-1){
bos.write(buf,0,len);
bos.flush();//可选操作,刷新
}
bis.close();
bos.close();
编码与解码
编码:将String 转化成byte[]
解码:将byte[]转化成String.
ASCII每个字符用1个字节表示,没有中文。
Unicode每一个字符用2个字节存储,有部分中文。
GBK主要存的是中文,每一个字符用2个字节存储。
UTF-8每个字符的存储字节数不确定的,如果能够用1个字节来存储,就用1个字节。如果要用2个字节来存储,就用2个字节。如果要用3个字节来存储,就用3个字节(中文)。有所有常用的字符
ISO-8859-1:一种编码表,用Unicode字符表示一个汉字。
编码出现负数:表示没有完毕的意思,不是一个整体。
使用指定的编码集进行编码:getBytes("utf-8")
解码:(b1,"utf-8")
字符流
转换流(防止乱码)
InputStreamReader isr =new InputStreamReader(fis,"UTF-8");//指定
InputStreamReader isr =new InputStreamReader(fis);//默认
不是针对文件的,是针对流来操作。
InputStreamReader:父类:Reader(字符输入流的父类,抽象类)是字节流通向字符流的桥梁。
->FileReader:用来读取字符文件的便捷类.里自带字节输入流+转换流功能
OutputStreamWriter:Writer(写入字符流的抽象类)。
->FileWriter:用来写入字符文件的便捷类
FileReader fr=new FileReader("a.txt");从a中复制
FileWriter fw= new FileWriter("b.txt");到b中
char[] cbuf=new char[10];
int len=0;
while
fw.write(cbuf,0,len):并不是立刻写入文件中,而是写入缓冲里当流关闭时才将数据写入文件。
fw.flush();:刷新,将数据刷新到文件中。相当于保存,对于字符输入流特有的。
BufferedReader:提高读取效率.是字符后的缓冲。
BufferedWriter:提高写入效率
FileReader
FileWriter
BufferedReader br= new BufferedReader(fr);
BufferedWriter bw=new BufferedWriter(fw);
String line=null;
while((line= br.readLine())!=null){
bw.write(line);
bw.newLine();//换行
bw.flush();
}
br.close();
bw.close();
流的操作规律
1,明确操作的数据类型。
源:InputStream, Reader ,字节,字符
目的:OutputStream, Writer,字节,字符。
2,明确数据的具体设备(数据的载体——文件数据,数组数据,字符串数据,输入的数据,Socket数据)。
3,明确需不需提高效率——Buffered xxx;
需不需要转换流--InputStream xxx;.
Properties类
表示了一个持久的属性集。以流的形式把数据写出来或加载进去。key:String;是hashtable的子类。默认使用 ISO-8859-1。默认将.properties文件编码为ISO-8859-1。 .properties文件是种配置文件。
IO的其他常用流
SequenceInputStream 序列字节输入流。
1,流对象的有序排列,
2,将多个输入流合并成一个输入流,将多个源合并成一个源,对于多个源的操作会比较简单。
3,对多个文件进行合并时使用。
ObjectInputStream 对象反序列化流 ObjectOutputStream 对象序列化流
1,主要针对对象操作的流
2,解决的就是对象序列化与反序列化的问题。
3,序列化就是将对象的数据写入到硬盘,反序列化就是将硬盘中对象的数据读取到内存。
一个对象想要实现序列化,要实现Serializable接口。
如果该对象中某个属性不想被序列化的话,加瞬态关键字。(transient).被瞬态,再进行反序列化得到默认值。别把所有属性都瞬态,会报InvalidClassException错误。如果都有多个同名称的类,在反序列化的时候也会出现InvalidClassException错误,需要加serialVersionUID. JVM
静态变量没有被序列化。
DataInputStream 基本数据类型输入流 DataOutputStream 基本数据类型输出流
类似于ObjectStream.只是不能写对象。
DataOutputStream dos =new DataOutputStream (new FileOutputStream("a.txt"));
dos.writeDouble(3.14);
dos.writeInt(10);
dos.close();
DataInputStream dis=new DataInputStream (new FileInputStream("a.txt"));
double d=double.readDouble();
int i = dis.readInt();
System.out.print();
打印流——PrintStream 字节打印流 PrintWriter 字符打印流
属于输出流,向控制台输出,类似于System.out
方便打印各种数据值表示形式。写的==打印出的
FileOutputStream fos= new FileOutputStream("a.txt");
PrintStream ps=new PrintStream(fos);
ps.print("Hi")
ps.flush();
ps.close();
RandomAccessFile 随机访问文件
1,可读,可写。兼顾了输入输出。以字节
2,可随机访问文件的位置。
RandomAccessFile raf=new RandomAccessFile("a.txt","rw");
raf.write("张三".getBytes());
raf.writeInt(97);
raf.seek(8);//指针跳转到8
NIO 新IO技术
JVM-高并发。