1.定义
I:input 输入(读取)
O:output 输出(写入)
流:数据(字符,字节)1个字符=2个字节=8个二进制位
字节: 输入流inputStream 输出流OutputStream
字符: 输入流Reader 输出流Writer
2.创建FileOutputStream
1)一次写一个字节
public static void main(String[] args) throws IOException {
//创建一个文件输出流,将字节输出到fos.dat文件中
FileOutputStream fos = new FileOutputStream("fos.dat");
fos.write(13);
fos.close();
}
2)一次写多个字节
public static void main(String[] args) throws IOException {
//创建一个文件输出流,将字节输出到fos.dat文件中
FileOutputStream fos = new FileOutputStream("fos.dat");
byte[] bytes = {65, 66, 67, 68};
//写入字符数组
fos.write(bytes);
//写入从第一位开始,长度为2的两个字符
fos.write(bytes, 1, 2);
//写入字符串
byte[] bytes2 = "您好".getBytes();
fos.write(bytes2);
fos.close();
}
3)追加写,换行写
FileOutputStream (String name, boolean append)
String name:写入数据的目的地
boolean append:追加写开关
true:常见对象不会覆盖原文件,继续在文件末尾追加写数据;
false:创建一个新文件,覆盖原文件
换行符:Windows:\r\n
linux:/n
mac:/r
public static void main(String[] args) throws IOException {
//创建一个文件输出流,将字节输出到fos.dat文件中
FileOutputStream fos = new FileOutputStream("fos.dat", true);
for(int i = 1; i <= 10; i++) {
fos.write("你好".getBytes());
fos.write("\r\n".getBytes());
}
fos.close();
}
3.创建FileInputStream
1)一次读取一个字节
public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream("fos.dat");
/*int len = fis.read();
System.out.println(len)
len = fis.read();
System.out.println(len);
len = fis.read();
System.out.println(len);*/
int len = 0;
while((len = fis.read()) != -1) {
System.out.println(len);
}
fis.close();
}
2)一次读取多个字节
public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream("fos.dat");
byte[] bytes = new byte[2*1024];
//int len = fis.read(bytes);
int len = 0;
while(len = fis.read(bytes)!= -1){
System.out.println(new String(bytes, 0, len);//读取有效的数据
}
System.out.println(new String(bytes));
fis.close();
}
4.文件的复制(练习)
public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream("fos.dat");
FileOutputStream fos = new FileOutputStream("fos-copy.dat");
byte[] bytes = new byte[2*1024];
int len = 0;
while((len = fis.read(bytes)) != -1){
fos.write(bytes, 0, len);
}
System.out.println(new String(bytes));
fos.close();
fis.close();
}
5.文件字符输入流FileReader
public static void main(String[] args) throws IOException {
FileReader fr = new FileReader("dos.data");
/*int len =0;
while((len = fr.read()) != -1) {
System.out.println((char)len);
}*/
char[] cs = new char[2*1024];
int len = 0;
while((len = fr.read(cs)) !=-1) {
System.out.println(new String(cs, 0, len));
}
fr.close();
}
6.文件字符输出流FileWriter
flush方法和close方法的区别:
flush:刷新缓冲区,流对象可以继续使用
close:先刷新缓冲区,然后通知系统释放资源。流对象不可以再被使用了。
public static void main(String[] args) throws IOException {
FileWriter fw = new FileWriter("dos.data");
//fw.write(97);//写一个字符
char[] cs = {'a', 'b', 'c', 'd'};
fw.write(cs);//abcd
fw.write(cs, 1, 3);//bcd
fw.write("我爱你");//我爱你
fw.write("我爱你", 2, 2);//爱你
fw.flush();
fw.close();
}
3)追加写,换行写
FileWriter (String name, boolean append)
String name:写入数据的目的地
boolean append:追加写开关
true:常见对象不会覆盖原文件,继续在文件末尾追加写数据;
false:创建一个新文件,覆盖原文件
换行符:Windows:\r\n
linux:/n
mac:/r
public static void main(String[] args) throws IOException {
FileWriter fw = new FileWriter("dos.data", true);
for(int i = 0; i <= 10; i++) {
fw.write("hello" + i + "\r\n");
}
fw.close();
}
7.有了字节输入流为什么还要字符输入流?
字符流处理的单元为2个字节的Unicode字符,分别操作字符、字符数组或字符串,而字节流处理单元为1个字节, 操作字节和字节数组。所以字符流是由Java虚拟机将字节转化为2个字节的Unicode字符为单位的字符而成的,所以它对多国语言支持性比较好!如果是 音频文件、图片、歌曲,就用字节流好点,如果是关系到中文(文本)的,用字符流好点.
所有文件的储存是都是字节(byte)的储存,在磁盘上保留的并不是文件的字符而是先把字符编码成字节,再储存这些字节到磁盘。在读取文件(特别是文本文件)时,也是一个字节一个字节地读取以形成字节序列.
字节流可用于任何类型的对象,包括二进制对象,而字符流只能处理字符或者字符串; 2. 字节流提供了处理任何类型的IO操作的功能,但它不能直接处理Unicode字符,而字符流就可以。
简单的说,假如一个一个字节的往文件里输入,一个文件读写次数太大了,很毁硬盘,但如果一个一个字符的保存,硬盘读写次数就会少很多,甚至可以一行一行的保存。