1.按照操作类型分类:
2.按照数据流向分类:
1、简述字符流
1、字符流中的对象融合了编码表。使用的是默认的编码,即当前系统的编码。
2、字符流只用于处理文字数据,而字节流可以处理媒体数据。
3、既然IO流是用于操作数据的,那么数据的最常见体现形式是文件。查看API,找到一个专门用于操作文件的Writer子类对象:FileWriter。 后缀是父类名。前缀名是流对象的功能。该流对象一被初始化,就必须有被操作的文件存在。
2、字符流的读写
1、写入字符流步骤
a、创建一个FileWriter对象,该对象一被初始化,就必须要明确被操作的文件。且该目录下如果已有同名文件,则同名文件将被覆盖。其实该步就是在明确数据要存放的目的地。
b、调用write(String s)方法,将字符串写入到流中。
c、调用flush()方法,刷新该流的缓冲,将数据刷新到目的地中。
d、调用close()方法,关闭流资源。但是关闭前会刷新一次内部的缓冲数据,并将数据刷新到目的地中。
close()和flush()区别:
flush()刷新后,流可以继续使用;
而close()刷新后,将会关闭流,不可再写入字符流。
注意:
1、其实java自身不能写入数据,而是调用系统内部方式完成数据的书写,使用系统资源后,一定要关闭资源。
2、文件的数据的续写是通过构造函数 FileWriter(Strings,boolean append),在创建对象时,传递一个true参数,代表不覆盖已有的文件。并在已有文件的末尾处进行数据续写。(windows系统中的文件内换行用\r\n两个转义字符表示,在linux系统中只用\n表示换行)
3、由于在创建对象时,需要指定创建文件位置,如果指定的位置不存在,就会发生IOException异常,所以在整个步骤中,需要对IO异常进行try处理。
3、字符流的缓冲区——BufferedReader和BufferedWriter
1、缓冲区的出现:提高了流的读写效率,所以在缓冲区创建前,要先创建流对象。即先将流对象初始化到构造函数中。
2、缓冲技术原理:此对象中封装了数组,将数据存入,再一次性取出。
3、写入流缓冲区BufferedWriter的步骤:
1)创建一个字符写入流对象。
如:FileWriter fw=newFileWriter("buf.txt");
2)为了提高字符写入流效率。加入缓冲技术。只要将需要被提高效率的流对象作为参数传递给缓冲区的构造函数即可。
如: BufferedWriter bufw =new BufferedWriter(fw);
3)调用write方法写入数据到指定文件
如:bufw.write("adfg");
记住,只要用到缓冲区,就要记得刷新。(关闭流同样会刷新,但为了排除意外事故,保证数据存在,建议写入一次就刷新一次)
如:bufw.flush();
4)其实关闭缓冲区,就是在关闭缓冲区中的流对象。
如: bufw.close();
小知识:BufferedWriter缓冲区中提供了一个跨平台的换行符:newLine();可以在不同操作系统上调用,用作数据换行。
如:bufw.newLine();
4、读取流缓冲区BufferedReader
该缓冲区提供了一个一次读一行的方法readLine,方便于堆文本数据的获取,当返回null时表示读到文件末尾。readLine方法返回的时候,只返回回车符之前的数据内容。并不返回回车符。
readLine方法原理:
无论是读一行。或者读取多个字符。其实最终都是在在硬盘上一个一个读取。所以最终使用的还是read方法一次读一个的方法。
步骤:
1)创建一个读取流对象和文件相关联
如: FileReader fr=newFileReader("buf.txt");
2)为了提高效率。加入缓冲技术。将字符读取流对象作为参数传递给缓冲区对象的构造函数。
如: BufferedReader bufr=new BufferedReader(fr);
3)调用该缓冲区提供的readLine方法一行一行读取,如果到达文件末尾,则返回null
如: String s=bufr.readLine();
4)关闭流资源
如: bufr.close();
字节流读取的时候,读到一个字节就返回一个字节。字符流使用了字节流读到一个或多个字节(中文对应的字节数是两个,在 UTF-8码表中是 3 个字节)时。先去查指定的编码表,将查到的字符返回。
字节流可以处理所有类型数据,除文本数据外如图片,mp3,avi 。而字符流只能处理文本数据
打印流 :一般是打印到控制台,可以进行控制打印的地方。
管道流 :PipedInputStream的一个实例要和PipedOutputStream的一个实例共同使用,共同完成管道的读取写入操作。主要用于线程操作。
序列流 :可以将流合并,可以用于数据的切割和合并。
对象序列化流:对象序列化,把对象直接转换成二进制,写入介质中。使用对象流需要实现Serializable接口,否则会报错。IO流(字节流)
字节流:
输出流:OutputStream(抽象):
|--FileOutputStream:
构造方法:文件可以不存在,会自动创建
FileOutputStream(String name) 创建一个向具有指定名称的文件中写入数据的输出文件流。
FileOutputStream(String name, boolean append) 创建一个向具有指定 name 的文件中写入数据的输出文件流。
FileOutputStream(File file) 创建一个向指定 File 对象表示的文件中写入数据的文件输出流。
FileOutputStream(File file, boolean append) :创建一个向指定 File 对象表示的文件中写入数据的文件输出流。
写入:
void write(int n):写入一个字节;
void write(byte[] byteArray):写入一个字节数组;
void write(byte[] byteArray ,int off,int len):写入一个字节数组的一部分;
输入流:InputStream(抽象):
|--FileInputStream:
构造方法:(文件必须存在,否则抛出异常)
FileInputStream(String fileName):
FileInputStream(File file):
读取:
int read():一次读取一个字节;
int read(byte[] b):一次读取一个字节数组,返回:读取的字节数;
字符流:
输出流:Writer:
输入流:Reader:
例子:
public class Demo {
public static void main(String[] args) throws IOException {
// 1.构造一个BufferedOutputStream
BufferedOutputStream out = new BufferedOutputStream(
new FileOutputStream("bufferdOutput.txt"));
//分开写
/*
FileOutputStream fileOut = new FileOutputStream("aa.txt");
BufferedOutputStream bufOut = new BufferedOutputStream(fileOut);
*/
//2.写入文件
out.write("你好Java".getBytes());
out.write("Hello".getBytes());
out.write("Worlddddddddd".getBytes());
//3.刷新缓冲区
// out.flush();
//4.释放资源
out.close();//先flush(),再close()
}
}
四:字节流四种方式复制MP4并测试效率
--基本流:
1.FileInputStream:
FileOutputStream:
1).一次读、写一个字节; method1()--> 58250 毫秒
2).一次读、写一个字节数组; method2()--> 105 毫秒!
--缓冲流:
2.BufferedInputStream:
BufferedOutputStream:
3).一次读、写一个字节 method3()--> 968 毫秒!
4).一次读、写一个字节数组: method4()--> 70 毫秒!
五:转换流--输出流:
字节流:
输出流:OutputStream
输入流:InputStream
字符流:
输出流:Writer
|-OutputStreamWriter:将字节输出流转换为字符输出流;
输入流:Reader
|--InputStreamReader:将字节流的输入流,转换为字符的输入流;
构造方法:这也是转换流的作用:可以将"字节流"转换为"字符流"
public OutputStreamWriter(OutputStream out)
public OutputStreamWriter(OutputStream out,String charsetName)
写入的方法:
public void write(int c):写入一个字符;
public void write(char[] cbuf):写入一个字符数组
public void write(char[] cbuf,int off,int len):写入一个字符数组的一部分
public void write(String str):写入一个字符串
public void write(String str,int off,int len):写入一个字符串的一部分;
一.数据输入输出流:
DataOutputStream:
DateInputStream:
可以输出任何的Java基本数据类型。所以,读取的时候,要按照
写入时的字节数,读取。
二.内存操作流:
ByteArrayOutputStream:
ByteArrayInputStream:
byte[]数组的缓冲区;就是用来缓存byte[]数组
三.打印流:
1.字符流:PrintWriter:
2.字节流:PrintStream:
特点:
1.只有输出流,没有输入流;
2.可以读写任何的数据类型;
3.部分功能带自动刷新,换行;
4.可以操作文件;
3.标准输入输出流:
System.in : BufferedInputStream:
System.out: PrintStream;
四.字节流转换为字符流:(必须掌握)
字节流 --> 转换流 --> 字符流
PrintStream OutputStreamWriter BufferedWriter
PrintStream ps = System.in;
OutputStreamWriter out = new OutputStreamWriter(ps);
BufferedWriter bw = new BufferedWriter(out);
五.随机访问流:
RandomAccessFile:不属于"流"类。它内部封装了InputStream和OutputStream
对文件进行读写操作:
构造方法:
RandomAccessFile(String fileName,String mode):mode:"r"只读;"rw":读写;
成员方法:
writeXxxx();
readXxxxx();
getFilePointer():获取当前文件指针
seek():设置当前文件指针;
六.序列化和反序列化:
序列化:ObjectOutputStream:
注意:1.序列化的类必须实现:Serializable接口(标记接口)
2.添加一个成员变量:serialVersionUID
成员方法:
writeObject(Object obj):
反序列化:
ObjectInputStream:
成员方法:
readObject();
七.Properties类:
1.它就是一个Map集合,继承自:Hashtable;
2.继承的: pub(Object key,Object value) get(Object key) keySet()
特有的: setProperty(String key,String value) getProperty(String key) stringPropertyNames()
3.操作配置文件相关:
load(Reader read):读取配置文件的信息;
store(Writer out,String com):将集合中的数据写入到配置文件;
八.NIO的一个案例:
1.public static long copy(Path source, OutputStream out) :复制文件
2.public static Path write(Path path, Iterable extends CharSequence> lines, Charset cs, OpenOption... options):