本文将介绍键盘IO、文本文件IO等
键盘输入输出
用Scanner获得键盘输入
//System.in 代表标准输入输出,即键盘输入。默认将空格作为输入分隔符
Scanner s=new Scanner(System.in);
//循环输出输入的内容
while(s.hasNext()){
System.out.println("键盘输入的内容是:"+s.next());
}
Scanner不仅可以读取用户的键盘输入,还可以读取文件内容。
//Scanner文件输入测试
//将file文件对象作为Scanner的构造器参数,则Scanner读取文件内容
try {
Scanner e = new Scanner(new File("D:\\temp\\a.txt"));
while(e.hasNextLine()){
System.out.println(e.nextLine());
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
使用BufferReader获取键盘输入
BufferReader是javaIO流中的一个字符、包装流,它必须建立在另一个字符流的基础上。而标准输入:System.in是字节流,我们需要用转换流InputStreamReader将其包装成字符流:
BufferReader br=new BufferReader(new InputStreamReader(System.in));
string buffer=null;
//逐行读取键盘输入
while((buffer=br.readLine())!=null){
System.out.println("用户键盘输入是:"+buffer);
}
文件的输入输出
字节流和字符流
字节流:最小操作数据单元为字节,8位。在Java中用InputStream和OutPutStream的子类来操作。
字符流:最小操作数据单元为字符,16位。在Java中用Reader和Writer的子类来操作。
节点流和处理流
节点流:向特定的IO设备读/写数据的流
处理流:对一个已经存在的流进行封装,通过封装后流来实现读/写功能(典型的装饰器设计模式)
Java的IO流涉及类
Java的IO流共涉及到40多个类,它们都是从4个抽象基类派生出来的:
InputStream/Reader:所有输入流的基类,前者是字节输入流,后者是字符输入流
OutputStream/Writer:所有输出流的基类,前者是字节输出流,后者是字符输出流
InputStream和Reader
InputStream和Reader是抽象类,本身不能创建实例来操作流。而他们派生的子类则可以。它们用于操作文件的子类分别是FileInputStream和FileReader
InputStream中包含三个方法:
int read():从流中读取单个字节,返回读取的字节数据(字节可直接转换成int)
int read(byte[ ]b):从输入流中读取最多b.length个字节的数据,并将其存储在字节数组b中,返回实际读取的字节数
int read(byte[ ]b,int off,int len):从流中读取最多len字节的数据,并将其存储在字节数组b中,放入数组时,并不是从数组起点开始,而是从offset位置开始,返回实际读取的字节数。
//创建字节输入流
FileInputStream fis=new FileInputStream("D:\\temp\\a.txt");
//创建一个长度为1024的“竹筒”,用来盛“水”
byte[] bbuf=new byte[1024];
//用来保存实际读取的字节数
int hasread=0;
//循环读取文件,直至最后;
while ((hasread=fis.read(bbuf))>0){
//取出竹筒中“水滴”(字节),将字节数组转换成字符串输入
System.out.println(new String(bbuf,0,hasread));
}
fis.close();
Read中包含的三个方法:
int read():从流中读取单个字符,返回读取的字符数据(字节可直接转换成int)
int read(char[ ]b):从输入流中读取最多b.length个字符的数据,并将其存储在字符数组b中,返回实际读取的字符数
int read(char[ ]b,int off,int len):从流中读取最多len字符的数据,并将其存储在字符数组b中,放入数组时,并不是从数组起点开始,而是从offset位置开始,返回实际读取的字节数。
//创建字符输入流
FileReader fr=new FileReader("D:\\temp\\c.txt");
//创建一个长度为32的“竹筒”,用来盛“水”
char[] cbuf=new char[32];
//用来保存实际读取的字符数
int hasread=0;
//循环读取文件,直至最后;
while ((hasread=fr.read(cbuf))>0){
//取出竹筒中“水滴”(字符),将字符数组转换成字符串输入
System.out.println(new String(cbuf,0,hasread));
}
fr.close();
OutputStream和Writer
OutputStream与Writer也非常相似,两个流都提供了如下三个方法:
void write(int c):将指定的字节/字符输入到输出流中
void write(byte[ ]/char[ ] buf):将字节数组/字符数组中的数据输入到制定输入流中
void write(byte[ ]/char[ ] buf,int off, int len):将字节数组/字符数组中从off位置开始,长度为len的字节/字符输出到输出流中
因为字符流直接以字符为操作单位,所以Writer可以用字符串来代替字符数组,即以String对象作为参数,所以Writer里还包括下面两个方法:
void write(String str):将字符串中的字符输出到输出流中
void write(string str,int off,int len):将str字符串中的字符输出到输出流,从off开始,长为len
//创建字节输入输出流
FileInputStream fis=new FileInputStream("D:\\temp\\c.txt");
FileOutputStream fos=new FileOutputStream("D:\\temp\\d.txt");
//创建一个长度为1024的“竹筒”,用来盛“水”
byte[] bbuf=new byte[32];
//用来保存实际读取的字节数
int hasread=0;
//循环读取文件,直至最后;
while ((hasread=fis.read(bbuf))>0){
//取出竹筒中“水滴”(字节),将字节数组转换成字符串输入到文件中
fos.write(bbuf,0,hasread);
System.out.println("输入了:"+(new String(bbuf,0,hasread)));
}
fis.close();
fos.close();
writer更写入字符串更简单:
FileWriter fr=new FileWriter("d:\\temp\\e.txt");
fr.write("锄禾\r\n");
fr.write("锄禾日当午,汗滴禾下土\r\n");
fr.write("谁知盘中餐,粒粒皆辛苦\r\n");
fr.close();
处理流的用法
通过上面四个基类的学习,我们发现输入输出操作有些繁琐,而我们上面提到的处理流现在就可以发挥作用了:使用处理流包装节点流,其特点是“流的构造器参数不是一个物理存储地址,而是一个已经存在的流”
下面使用PrintStream处理流来包装InputStream,使用处理流后的输入输出将更加方便:
FileOutputStream fos=new FileOutputStream("d:\\temp\\f.txt");
PrintStream ps=new PrintStream(fos);
ps.println("处理流测试");
ps.println(new MathMethods());
ps.close();
PrintStream类的输出功能很强大,可输出字符串、类等等,所以输出文本内容时,用PrintStream很方便。
JavaIo处理有这么多类,其实主要分为字节流与字符流,如果输入\输出的是文本内容,则应考虑用字符流;如果输入\输出的是二进制内容,则应考虑使用字节流。
转换流
IO中提供了两个转换流:
InputStreamReader:将字节输入流转换成字符输入流
OutputStreamWriter:将字节输出流转换成字符输出流
文章最开始提到键盘输入的第二种处理方法,我们知道键盘输入是System.in,即标准输入,它是InputStream的实例,即字节输入实例,而键盘输入是文本输入,所以可以用InputStreamReader将其转换为字符输入流;普通Reader读取输入内容时依然不太方便,我们可以讲普通Reader再次包装成BufferReader,利用BufferReader的readLine方法可以一次读取一行内容
//将System.in对象转换成Reader对象
InputStreamReader reader=new InputStreamReader(System.in);
//将普通Reader包装成bufferReader
BufferedReader br=new BufferedReader(reader);
String buffer=null;
//采用循环方式一行一行读取
while((buffer=br.readLine())!=null){
System.out.println("输入内容为:"+buffer);
}
br.close();