Java中的I/O流
Java中I/O流是实现输入/输出的基础,可以方便的实现输入和输出操作,Java中把不同的输入/输出源抽象表述为“流”,通过流的方式运行Java程序使用相同的方式来访问不同的输入/输出源,这里的流可以理解为字节序列,
流的分类:
流的分类可以从以下两个角度划分:
流向:按照流的流向来分可以分为输入流和输出流,其中输入流只能从中读取数据,而不能向其写入数据;输出流只能向其写入数据,而不能从中读取数据。
读取单元:按照读取单元划分,流可以分为字节流和字符流,顾名思义所谓字节流就是输入和输出的基本单位都是字节,而字符流输入输出的基本单元都是字符。
输入和输出都涉及到方向的问题,这里的输入和输出都是从程序运行所在的内存角度划分的,也就是说从硬盘或者网络读取到程序运行内存中的流叫做输入流,反之从内存中写入硬盘的流则叫做输出流,换句话说,输入流和输出流都是以当前程序运行的内存作为参照物。
Java中输入流主要使用InputStream和Reader作为基类,而输出流主要使用OutputStream和Writer作为基类,它们都是一些抽象类,无法直接创建实例。
流的概念模型
Java把所以的设备里的有序数据抽象成流模型,简化了输入/输出处理,理解了流的概念模型也就了解了Java IO
Java中有关IO流的类都是从如下4个抽象类中派生的。
InputStream/Reader:所有输入流的基类,前者是字节输入流,后者是字符输入流。
OutputStream/Writer:所有输出流的基类,前者是字节输出流,后者是字符输出流。
字节流和字符流的处理方式其实非常相似,只是它们处理的输入/输出单位不同而已。
字节流
InputStream
InputStream是输入流的基类,读取的最小单元是字节。由于InputStream是抽象类,所以其本身并不能创建实例来执行输入。但它们将成为所有输入流的模板,所以它们的方法是所有输入流都可使用的方法。
InputStream里包含如下方法:
int read():从输入流中读取单个字节,返回所读取的字节数据(字节数据可直接转换为int类型)。
int read(byte[]b):从输入流中最多读取b.length个字节的数据,并将其存储在字节数组b中,返回实际读取的字节数。
int read(byte[]b,int off,int len):从输入流中最多读取len个字节的数据,并将其存储在数组b中,放入数组b中时,并不是从数组起点开始,而是从off位置开始,返回实际读取的字节数。
InputStream有个子类用于读取文件的输入流:FileInputStream
/**
*FileInputStream 读取文件的输入流练习
*/
public class IoDemo4 {
public static void main(String[] args) throws IOException {
InputStream is = new FileInputStream("D:\\IoDemo\\test.txt");
int k = 0;
//每次取三个字节 utf-8字节中一个汉字占三个字节
//byte[] bytes = new byte[3];
//小文件可以这样取输入和输出流 但是大文件不可以
byte[] bytes = new byte[is.available()];
//byte[] bytes = new byte[3];
while((k = is.read(bytes))!=-1){
System.out.println(new String(bytes,"utf-8"));
}
}
}
/**
* try-with-resource语法练习
*/
public class IoDemo6 {
public static void main(String[] args) {
//InputStream实现Closeable接口 Closeable接口继承了AutoCloseable接口
//使用try-with-resource语法自动关闭资源
try(InputStream is = new FileInputStream("D:\\IoDemo\\test.txt")){
int k = 0;
byte[] bytes = new byte[1024];
while((k = is.read(bytes))!=-1){
System.out.println(new String(bytes,"utf-8"));
}
}
catch (FileNotFoundException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
OutputStream
OutputStream是输出流的基类,输入的最小单元是字节。它提供了如下方法:
void write(int c):将指定的字节输出到输出流中,其中c既可以代表字节,也可以代表字符。
void write(byte[] buf):将字节数组中的数据输出到指定输出流中。
void write(byte[] buf,int off,int len):将字节数组中从off位置开始,长度为len的字节/字符输出到输出流中。
同样OutputStream也有子类用于输入文件流:FileOutputStream,下面的程序将示范FileOutputStream的使用。
public class FileOutputStreamDemo {
public static void main(String[] args) {
String path = "D:\\IoDemo\\test2.txt";
//如果文件不存在,则自动创建
//append:是指是否在原有内容后追加,默认为FALSE
try(OutputStream os = new FileOutputStream(path)){
char c = '赞';
int a = c;
os.write(a);
}catch (FileNotFoundException e) {
e.printStackTrace();
}catch (IOException e){
e.printStackTrace();
}
}
}