java.io包中几乎包含了所有操作输入、输出所需要的类。
一个流(stream)可以理解为一个数据序列,输入流表示从一个源读取数据,输出流表示向一个目标写数据。
此程序演示用read()方法从控制台不断读取字符,直到用户输入'a'。
//使用BufferedReader在控制台读取字符
import java.io.*;
public class FirstTest {
public static void main(String args[]) throws IOException{//是java中的throws语句
char c;
//使用system.in创建BufferedReader
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
// BufferedReader类从字符输入流中读取文本并缓冲字符,以便有效地读取字符,数组和行
System.out.println("输入字符,按下‘a’键退出");
do{
c = (char)br.read();
//调用read方法时,它从输入流读取一个字符并把该字符作为一个整数值返回
//当流结束时返回-1,该方法抛出IOException
System.out.println(c);
}while(c!='a');
}
}
运行结果
以下为涉及知识点。
1.throws关键字
如果一个方法没有捕获到检查性异常,那么该方法必须使用throws关键字来声明。throws关键字放在方法签名的尾部。
2.InputStreamReader流
API文档说明:InputStreamReader 是字节流通向字符流的桥梁:它使用指定的
读取字节并将其解码为字符。它使用的字符集可以由名称指定或显式给定,或者可以接受平台默认的字符集。charset
每次调用 InputStreamReader 中的一个 read() 方法都会导致从底层输入流读取一个或多个字节。要启用从字节到字符的有效转换,可以提前从底层流读取更多的字节,使其超过满足当前读取操作所需的字节。
为了达到最高效率,可要考虑在 BufferedReader 内包装 InputStreamReader。例如:
BufferedReader in
= new BufferedReader(new InputStreamReader(System.in));
3.read()方法
API文档说明:
public int read()
throws IOException
读取单个字符。
覆盖:
类 Reader
中的 read
返回:
作为一个整数(其范围从 0 到 65535 (0x00-0xffff))读入的字符,如果已到达流末尾,则返回 -1
抛出:
IOException
- 如果发生 I/O 错误(当某个方法抛出了异常时,如果当前方法没有捕获异常,异常就会被抛到上层调用方法,直到遇到某个try ... catch
被捕获为止)
从标准输入读取一个字符串,需要使用BufferedReader 的 readLine() 方法。
//使用BufferedReader在控制台读取字符
import java.io.*;
public class FirstTest {
public static void main(String args[])throws IOException{
String ch;
//使用System.in创建BufferedReader
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.println("Enter lines of text.");
System.out.println("Enter 'end' to quit.");
do{
ch = br.readLine();
System.out.println(ch);
}while(!ch.equals("end"));
}
}
1.readLine() 方法
API文档说明:
public String readLine()
throws IOException
读取一个文本行。通过下列字符之一即可认为某行已终止:换行 ('\n')、回车 ('\r') 或回车后直接跟着换行。
返回:
包含该行内容的字符串,不包含任何行终止符,如果已到达流末尾,则返回 null
抛出:
IOException
- 如果发生 I/O 错误
2.equals
public boolean equals(Object anObject)
将此字符串与指定的对象比较。当且仅当该参数不为 null
,并且是与此对象表示相同字符序列的 String
对象时,结果才为 true
。
覆盖:
类 Object
中的 equals
参数:
anObject
- 与此 String
进行比较的对象。
返回:
如果给定对象表示的 String
与此 String
相等,则返回 true
;否则返回 false
。
另请参见:
compareTo(String)
, equalsIgnoreCase(String)
3.为什么String类不需要引入java.lang包
因为java.lang包是唯一的,它被自动引入每个java程序,所以不必import.
用write把字符'a'和换行符输出到屏幕上(write方法不常用,因为print和println使用起来更方便)
//演示System.out.write()
import java.io.*;
public class FirstTest {
public static void main(String args[]){
int ch;
ch = 'a';
System.out.write(ch);
System.out.write('\n');
}
}
1.write
public void write(int b)
throws IOException
将指定 byte
写入此输出流。
FilterOutputStream
的 write
方法调用其基础输出流的 write
方法,也就是说,它执行 out.write(b)。
实现 OutputStream 的抽象 write 方法。
指定者:
类 OutputStream
中的 write
参数:
b
- byte
。
抛出:
IOException
- 如果发生 I/O 错误。
描述输入流和输出流的类层次图
该字节流用于从文件中读取数据,它的对象可以用关键字new来创建。有多种构造方法可用来创建对象。
可以使用字符串类型的文件名来创建一个输入流对象来读取文件:
InputStream f = new FileInputStream("c:/java/hello");
也可以使用文件对象来创建一个输入流对象来读取文件。我们首先使用File()方法来创建一个文件对象:
File f = new File("c:/java/hello");
InputStream out = new FileInputStream(f);
该流用来创建一个文件并向文件中中写入数据。如果该流在打开文件进行输出前,目标文件不存在,那么该流会创建该文件。
有两个构造方法可以用来创建FileOutputStream对象。
使用字符串类型的文件名来创建一个输出流对象:
OutputStream f = new FileOutputStream("c:/java/hello");
也可以使用一个文件对象来创建一个输出流来写文件。我们首先得使用File()方法来创建一个文件对象:
File f = new File("C:/java/hello");
OutputStream f = FileOutputStream(f);
下面是一个演示 InputStream 和 OutputStream 用法的例子:
//演示System.out.write()
import java.io.*;
public class FirstTest {
public static void main(String[] args)throws IOException{
File f = new File("a.txt");
//用File方法来创建一个文件对象
FileOutputStream fp = new FileOutputStream(f);//字节流
//构建FileOutputStream对象,文件不存在会自动新建
OutputStreamWriter writer = new OutputStreamWriter(fp,"UTF-8");
//字符流通往字节流的桥梁:字符输出流输出字符到流中,然后通过指定的字符集把流中的字符编码成字节输出到字节流中
// 其作用就是一个桥梁,使得双方链接起来
// 构建OutputStreamWriter对象,参数可以指定编码,默认为操作系统默认编码,windows上是gbk
writer.append("中文输入");
//写入到缓冲区
writer.append("\r\n");
writer.append("english");
writer.close();
//关闭写入流,同时会把缓冲区内容写入文件
fp.close();
//关闭输出流
FileInputStream fip = new FileInputStream(f);
// 构建FileInputStream对象
InputStreamReader reader = new InputStreamReader(fip,"UTF-8");
// 构建InputStreamReader对象,编码与写入相同
StringBuffer sb = new StringBuffer();
while(reader.ready()){
sb.append((char)reader.read());
}
System.out.println(sb.toString());//返回此序列中数据的字符串表现形式
reader.close();
fip.close();
}
}
1. FileInputStream和InputStreamReader区别
FileInputStream是读取字节流,读取字节流的对象要获取文本文件的位置
InputStreamReader是读取字符流,读取字符流要设置字符的编码格式,字节转换成字符使用UTF-8编码格式
2.字节流和字符流的区别
InputStream是所有字节输入流的祖先,而OutputStream是所有字节输出流的祖先。
Reader是所有读取字符串输入流的祖先,而writer是所有输出字符串的祖先。
InputStream,OutputStream,Reader,writer都是抽象类。所以不能直接new
具体实现:
字节流 FileInputStream FileOutputStream
字符流 FileReader FileWriter
字节流是最基本的,所有的InputStream和OutputStream的子类都是,主要用在处理二进制数据,它是按字节来处理的,但实际中很多的数据是文本,又提出了字符流的概念,它是按虚拟机的Encode来处理,也就是要进行字符集的转化。这两个之间通过 InputStreamReader,OutputStreamWriter来关联,实际上是通过byte[]和String来关联。在从字节流转化为字符流时,实际上就是byte[]转化为String时。
3.字符流缓冲区
缓冲区可以理解为一段特殊的内存区域。某些情况下,如果一个程序频繁地操作一个资源(如文件或数据库),则性能会很低,此时为了提升性能,就可以将一部分数据暂时读入到内存的一块区域之中,以后直接从此区域中读取数据即可,因为读取内存速度会比较快,这样可以提升程序的性能。