一、什么是IO流
- I : Input
- O : Output
通过IO可以完成硬盘文件的读和写。
二、IO流的分类
- 按照
流的方向
进行分类:
以内存作为参照物:
- 往内存中去:叫做输入(Input)。或者叫做读(Read)。
- 从内存中出来:叫做输出(Output)。或者叫做写(Write)。
- 按照
读取数据方式
不同进行分类:
- 按照
字节
的方式读取数据,一次读取1个字节byte,等同于一次读取8个二进制位。
这种流是万能的,什么类型的文件都可以读取。包括:文本文件,图片,声音文件,视频文件
等…
eg.
假设文件file1.txt,采用字节流的话是这样读的:
a中国bc张三fe
第一次读:一个字节,正好读到’a’
第二次读:一个字节,正好读到’中’字符的一半。
第三次读:一个字节,正好读到’中’字符的另外一半。
- 按照
字符
的方式读取数据的,一次读取一个字符.
这种流是为了方便读取 普通文本文件
而存在的,这种流不能读取:图片、声音、视频等文件。只能读取 纯文本文件
,连word文件都无法读取。
注意:
纯文本文件,不单单是.txt文件,还包括 .java、.ini、.py 。总之只要 能用记事本打开
的文件都是普通文本文件。
eg.
假设文件file1.txt,采用字符流的话是这样读的:
a中国bc张三fe
第一次读:'a’字符('a’字符在windows系统中占用1个字节。)
第二次读:'中’字符('中’字符在windows系统中占用2个字节。)
综上所述:流的分类:
输入流、输出流
字节流、字符流
三、IO流四大家族首领
- 字节流
- java.io.InputStream 字节输入流
- java.io.OutputStream 字节输出流
- 字符流
- java.io.Reader 字符输入流
- java.io.Writer 字符输出流
注意:
- 四大家族的首领都是抽象类。(abstract class)
- 所有的流都实现了:
java.io.Closeable接口,都是可关闭的,都有close()
方法。
流是一个管道,这个是内存和硬盘之间的通道,用完之后一定要关闭,不然会耗费(占用)很多资源。养成好习惯,用完流一定要关闭。 - 所有的
输出流
都实现了:
java.io.Flushable接口,都是可刷新的,都有flush()
方法。
养成一个好习惯,输出流在最终输出之后,一定要记得flush()刷新一下。这个刷新表示将通道/管道当中剩余未输出的数据强行输出完(清空管道!)刷新的作用就是清空管道。
ps:如果没有flush()可能会导致丢失数据
。
- 在java中只要“类名”以
Stream
结尾的都是字节流。以“Reader/Writer
”结尾的都是字符流。
四、Java要掌握的流(16个)
- 文件专属:
- java.io.FileInputStream(掌握)
- java.io.FileOutputStream(掌握)
- java.io.FileReader
- java.io.FileWriter
- 转换流:(将字节流转换成字符流)
- java.io.InputStreamReader
- java.io.OutputStreamWriter
- 缓冲流专属:
- java.io.BufferedReader
- java.io.BufferedWriter
- java.io.BufferedInputStream
- java.io.BufferedOutputStream
- 数据流专属:
- java.io.DataInputStream
- java.io.DataOutputStream
- 标准输出流:
- java.io.PrintWriter
- java.io.PrintStream(掌握)
- 对象专属流:
- java.io.ObjectInputStream(掌握)
- java.io.ObjectOutputStream(掌握)
- File文件类
- java.io.File
补充:Windows/Linux小知识点
Windows:D:SoftQQPlugin
Linux:D:/Soft/QQ/Plugin
注意: Windows各个文件之间分隔符为:” “;Linux各个文件之间分割符为:” / “
补充:IDEA默认的当前路径是?
工程Project的根就是IDEA的默认当前路径
五、java.io.FileInputStream
文件字节输入流,万能的,任何类型的文件都可以采用这个流来读
构造方法
构造方法名
备注
FileInputStream(String name)
name为文件路径
FileInputStream(File file)
方法
方法名
作用
int read()
读取一个字节,返回值为该字节ASCII码;读到文件末尾返回-1
int read(byte[] b)
读b数组长度的字节到b数组中,返回值为读到的字节个数;读到文件末尾返回-1
int read(byte[] b, int off, int len)
从b素组off位置读len长度的字节到b数组中,返回值为读到的字节个数;读到文件末尾返回-1
int available()
返回文件有效的字节数
long skip(long n)
跳过n个字节
void close()
关闭文件输入流
public class FileInputStreamTest04 {
public static void main(String[] args) {
FileInputStream fis = null;
try {
fis = new FileInputStream("chapter23/src/tempfile3");
// 开始读,采用byte数组,一次读取多个字节。最多读取“数组.length”个字节。
byte[] bytes = new byte[4];// 准备一个4个长度的byte数组,一次最多读取4个字节。
int readCount = 0;
// 这个方法的返回值是:读取到的字节数量。(不是字节本身);1个字节都没有读取到返回-1(文件读到末尾)
while((readCount = fis.read(bytes)) != -1) {
// 不应该全部都转换,应该是读取了多少个字节,转换多少个。
System.out.print(new String(bytes, 0, readCount));
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
// 在finally语句块当中确保流一定关闭。
if (fis != null) {// 避免空指针异常!
// 关闭流的前提是:流不是空。流是null的时候没必要关闭。
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
public class FileInputStreamTest05 {
public static void main(String[] args) {
FileInputStream fis = null;
try {
fis = new FileInputStream("tempfile");
System.out.println("总字节数量:" + fis.available());
// 读1个字节
//int readByte = fis.read();
// 还剩下可以读的字节数量是:5
//System.out.println("剩下多少个字节没有读:" + fis.available());
// 这个方法有什么用?
byte[] bytes = new byte[fis.available()]; // 这种方式不太适合太大的文件,因为byte[]数组不能太大。
// 不需要循环了。
// 直接读一次就行了。
int readCount = fis.read(bytes); // 6
System.out.println(new String(bytes)); // abcdef
// skip跳过几个字节不读取,这个方法也可能以后会用!
fis.skip(3);
System.out.println(fis.read()); //100
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
六、java.io.FileOutputStream
构造方法
构造方法名
备注
FileOutputStream(String name)
name为文件路径
FileOutputStream(String name, boolean append)
name为文件路径,append为true表示在文件末尾追加;为false表示清空文件内容,重新写入
FileOutputStream(File file)
FileOutputStream(File file, boolean append)
append为true表示在文件末尾追加;为false表示清空文件内容,重新写入
方法
方法名
作用
void write(int b)
将指定字节写入文件中
void write(byte[] b)
将b.length个字节写入文件中
void write(byte[] b, int off, int len)
将b素组off位置开始,len长度的字节写入文件中
void flush()
刷新此输出流并强制写出所有缓冲的输出字节
void close()
关闭文件输出流
public class FileOutputStreamTest01 {
public static void main(String[] args) {
FileOutputStream fos = null;
try {
// myfile文件不存在的时候会自动新建!
// 这种方式谨慎使用,这种方式会先将原文件清空,然后重新写入。
//fos = new FileOutputStream("myfile");
// 以追加的方式在文件末尾写入。不会清空原文件内容。
fos = new FileOutputStream("tempfile3", true);
// 开始写。
byte[] bytes = {97, 98, 99, 100};
// 将byte数组全部写出!
fos.write(bytes); // abcd
// 将byte数组的一部分写出!
fos.write(bytes, 0, 2); // 再写出ab
// 字符串
String s = "我是一个中国人,我骄傲!!!";
// 将字符串转换成byte数组。
byte[] bs = s.getBytes();
// 写
fos.write(bs);
// 写完之后,最后一定要刷新
fos.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
七、java.io.FileReader
FileReader 文件字符输入流,只能读取普通文本。读取文本内容时,比较方便,快捷。
构造方法
构造方法名
备注
FileReader(String fileName)
name为文件路径
FileReader(File file)
方法
方法名
作用
int read()
读取一个字符,返回值为该字符ASCII码;读到文件末尾返回-1
int read(char[] c)
读c数组长度的字节到c数组中,返回值为读到的字符个数;读到文件末尾返回-1
int read(char[] c, int off, int len)
从c素组off位置读len长度的字符到c数组中,返回值为读到的字符个数;读到文件末尾返回-1
long skip(long n)
跳过n个字符
void close()
关闭文件输入流
public class FileReaderTest {
public static void main(String[] args) {
FileReader reader = null;
try {
// 创建文件字符输入流
reader = new FileReader("tempfile");
// 开始读
char[] chars = new char[4]; // 一次读取4个字符
int readCount = 0;
while((readCount = reader.read(chars)) != -1) {
System.out.print(new String(chars,0,readCount));
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
八、java.io.FileWriter
FileWriter文件字符输出流。写。只能输出普通文本。
构造方法
构造方法名
备注
FileWriter(String fileName)
name为文件路径
FileWriter(String fileName, boolean append)
name为文件路径,append为true表示在文件末尾追加;为false表示清空文件内容,重新写入
FileWriter(File file)
FileWriter(File file, boolean append)
append为true表示在文件末尾追加;为false表示清空文件内容,重新写入
方法
方法名
作用
void write(int c)
将指定字符写入文件中
void write(char[] c)
将c.length个字符写入文件中
void write(char[] c, int off, int len)
将c素组off位置开始,len长度的字符写入文件中
void write(String str)
将字符串写入文件中
void write(String str, int off, int len)
从字符串off位置开始截取len长度的字符串写入文件
void f