Java程序中,对于数据的输入/输出操作以“流(stream)” 的方式进行。
一般来说关于流的特性有下面几点:
1.先进先出:最先写入输出流的数据最先被输入流读取到。
2.顺序存取:可以一个接一个地往流中写入一串字节,读出时也将按写入顺序读取一串字节,不能 随机访问中间的数据。(RandomAccessFile除外)
3.只读或只写:每个流只能是输入流或输出流的一种,不能同时具备两个功能,输入流只能进行读 操作,对输出流只能进行写操作。在一个数据传输通道中,如果既要写入数据,又要读取数据, 则要分别提供两个流。
按操作数据单位不同分为:字节流(8 bit),字符流(16 bit)(字节流可以实现字符流的东西,一般是用来传输超文本比如图片,视频等等,字节流可以处理任何的文本文件,而字符流一般是用来传输文本)
按数据流的流向不同分为:输入流,输出流
按流的角色的不同分为:节点流,处理流
问题:既然有了字节流可以处理任何文件那为什么还要有字符流呢?
答:字符是JVM将字节转换得到的,这个过程还是非常耗时,所以用字符流专门来处理纯文本文件的而且不知道编码的方式就会乱码,比如Unicode的中文和英文是两个字节,而utf-8是三个字节
问题:字节流和字符流的区别是什么?
答:1.定义不同,字节流执行基本单元是8bit的字节,字符流是执行基本单元是16bit的字符
2、结尾
字节流以stream结尾(如FileInputStream和FileOutputStream);而字符流以reader和writer结尾(FileReader和FileWriter)
3、处理方式
字节流是最基本的,采用ASCII编码;它通常用于处理二进制数据,它是按字节来处理的,实际上它可以处理任意类型的数据,但它不支持直接写入或读取Unicode码元。
字符流采用Unicode编码,它是按虚拟机的encode来处理,也就是要进行字符集的转化;它通常处理文本数据,它支持写入及读取Unicode码元。
4、缓冲区
字节流默认不使用缓冲区;字符流使用缓冲区。
问题:缓冲区是什么,有什么用?
答:程序与磁盘的交互相对于内存运算是很慢的,缓冲区就像垃圾回收站,没有垃圾回收站的话,一旦有垃圾你就过来清理,假如有人丢三次垃圾那你就要过来处理三次,但有垃圾处理站的话,你设置这个垃圾处理站可以存三次垃圾,满了通知你,那你就可以用下来一次处理垃圾就可以了
输入输出的主体来说是电脑
输入input:对于电脑来说就是读取文件的数据保存到内存里面
输出output:对于电脑来说就是将数据输出到硬盘,其他文件
问题:处理流和节点流的区别?
答:节点流是在数据源读取数据,处理流是在已有的流上面封装读写功能这里使用了一个设计模式——修饰模式(就是为一个类新增加一个新的功能,当不用这个功能的时候就会使用这个类原本的功能),一般节点流可以一次性输入或输出大量的数据(缓存的原理)
路径分隔符和系统有关:
- windows和DOS系统默认使用“\”来表示
- UNIX和URL使用“/”来表示
IO流一般使用在文件上面
File 能新建、删除、重命名文件和目录,但 File 不能访问文件内容本身。如果需要访问文件内容本身,则需要使用输入/输出流
File filename=new File("路径名字");
这个File里面也有很多方法,有判断文件是否存在和是否可读可写等等
接下来的是如何显示一个文件的内容在控制台上
package com.zhq;
import java.io.File;
import java.io.FileReader;
import java.io.Reader;
import java.util.Arrays;
public class FileTest1 {
public static void main(String[] args) {
//获取已知文件
FileReader fileReader=null;
File file = new File("zhq2");
try {
//读取文件的内容,因为是纯文本使用字符流去读
fileReader = new FileReader("zhq2");
char[] chars=new char[6];
int len=0;
// len=fileReader.read(chars);
// System.out.println(len);
// len=fileReader.read(chars);
// System.out.println(len);
while ((len=fileReader.read(chars))!=-1){
System.out.print(new String(chars,0,len));
}
}catch (Exception e){
if (!file.exists()) {
System.out.println("文件不存在");
}
else {
System.out.println("文件路径错误");
}
}
finally {
try {
if (fileReader != null) {
fileReader.close();
}
}catch (Exception e){
e.printStackTrace();
}
}
}
}
这里值得注意的是FileReader是有异常的要去解决,然后是流的话就要关掉
这里是判断字符流有没有关闭,没有的话要关闭,关闭的话那就自然不用关了
if (fileReader != null) {
fileReader.close();
}
这段代码是读取文件内容到char数组里,如果文件里有内容他就会返回读到末尾的字符数,当读到末尾再读的话就返回-1,这个可以看作有个光标
while ((len=fileReader.read(chars))!=-1){
System.out.print(new String(chars,0,len));
}
FileWriter后面要加true才会追加,到时里面的write方法也是追加
fileOutputStream=new FileWriter("blank",true);
字节流读取文件是用FileInputStream,写入同理,其中因为都是字节所以可以用str.getBytes方法来使字符串变成字节,也可以使用new String()来让字节数组变字符串
BufferReader和BufferWriter是处理流(处理节点流的FileReader和FileWriter)这两个的变化是他们用了缓冲区这样就效率提高了
他们写入和读取的办法和FileWriter,FileReader差不多,BufferReader用readline(没有内容返回null)读取更好;