BufferrdReader类
BufferReader类用于从缓冲区中读取内容,所有的输入字节数据都将放在缓冲区中,常用的方法如表所示:
![]()
范例
将System.in变为字符流放入到BufferedReader后,可以通过readLine()方法等待用户输入信息。具体操作的代码如下:
import java.io.* ;
public class BufferedReaderDemo01{
public static void main(String args[]){
BufferedReader buf = null ; // 声明对象
buf = new BufferedReader(new InputStreamReader(System.in)) ; // 将字节流变为字符流
String str = null ; // 接收输入内容
System.out.print("请输入内容:") ;
try{
str = buf.readLine() ; // 读取一行数据
}catch(IOException e){
e.printStackTrace() ; // 输出信息
}
System.out.println("输入的内容为:" + str) ;
}
};
程序运行结果:
请输入内容:李某人
输入的内容为:李某人
Scanner类
在JDK 1.5之后Java提供了专门的输入数据类,此类不只可以完成输入数据操作,也可以方便地对输入数据进行验证。此类存放在java.util包中,其常用方法如表所示:
Scanner类中提供了一个可以接收InputStream类型的构造方法,这就表示只要是字节输入流的子类都可以为Scanner类实例化,以进行方便的读取
范例
- 操作一: 输入int,float
import java.util.* ;
public class ScannerDemo03{
public static void main(String args[]){
Scanner scan = new Scanner(System.in) ; // 从键盘接收数据
int i = 0 ;
float f = 0.0f ;
System.out.print("输入整数:") ;
if(scan.hasNextInt()){ // 判断输入的是否是整数
i = scan.nextInt() ; // 接收整数
System.out.println("整数数据:" + i) ;
}else{
System.out.println("输入的不是整数!") ;
}
System.out.print("输入小数:") ;
if(scan.hasNextFloat()){ // 判断输入的是否是小数
f = scan.nextFloat() ; // 接收小数
System.out.println("小数数据:" + f) ;
}else{
System.out.println("输入的不是小数!") ;
}
}
};
程序运行结果:
输入整数:3
整数数据:3
输入小数:5
小数数据:5.0
- 操作二: 实现日期格式的数据输入
import java.util.* ;
import java.text.* ;
public class ScannerDemo04{
public static void main(String args[]){
Scanner scan = new Scanner(System.in) ; // 从键盘接收数据
String str = null ;
Date date = null ;
System.out.print("输入日期(yyyy-MM-dd):") ;
if(scan.hasNext("^\\d{4}-\\d{2}-\\d{2}$")){ // 判断
str = scan.next("^\\d{4}-\\d{2}-\\d{2}$") ; // 接收
try{
date = new SimpleDateFormat("yyyy-MM-dd").parse(str) ;
}catch(Exception e){}
}else{
System.out.println("输入的日期格式错误!") ;
}
System.out.println(date) ;
}
};
程序运行结果:
输入日期(yyyy-MM-dd):2017-9-24
以上程序使用hasNext()对输入的数据进行正则验证,如果合法,则转换成Date类型。
- 操作三:从文件中得到数据
如果想要从文件中取得数据,则直接就将File类的实例传入到Scanner的构造方法中即可。
import java.util.* ;
import java.text.* ;
import java.io.* ;
public class ScannerDemo05{
public static void main(String args[]){
File f = new File("D:" + File.separator + "test.txt") ; // 指定操作文件
Scanner scan = null ;
try{
scan = new Scanner(f) ; // 从键盘接收数据
}catch(Exception e){}
StringBuffer str = new StringBuffer() ;
while(scan.hasNext()){
str.append(scan.next()).append('\n') ; // 取数据
}
System.out.println("文件内容为:" + str) ;
}
};
程序运行结果:
姓名:李某人;年龄:23;性别:男
数据操作流
在IO包中,提供了两个与平台无关的数据操作流,分别为数据输出流(DataOutputStream)和数据输入流(DateInputStream),通常数据输出流会按照一定的格式将数据输出,再通过数据输入流按照一定的格式将数据读入,这样可以方便地对数据进行处理。
例如,有一组表示订单的数据
如果要将以上数据保存到文件中,就可以使用数据输出流将内容保存到文件,然后再使用数据输入流从文件中读取进来。
DataOutputStream
DateOutputStream是OutputStream的子类,此类的定义如下:
public class DataOutputStream extends FilterOutputStream implements DataOutput
此类继承自FilterOutputStream类(FilterOutputStream是OutputStream的子类),同时实现了DataOutput接口,在DataOutput接口定义了一系列的写入各种数据的方法。
DataOutputStream类的常用方法
范例
- 操作一:将订单数据写入到文件order.txt中
import java.io.DataOutputStream ;
import java.io.File ;
import java.io.FileOutputStream ;
public class DataOutputStreamDemo{
public static void main(String args[]) throws Exception{ // 所有异常抛出
DataOutputStream dos = null ; // 声明数据输出流对象
File f = new File("d:" + File.separator + "order.txt") ; // 文件的保存路径
dos = new DataOutputStream(new FileOutputStream(f)) ; // 实例化数据输出流对象
String names[] = {"衬衣","手套","围巾"} ; // 商品名称
float prices[] = {98.3f,30.3f,50.5f} ; // 商品价格
int nums[] = {3,2,1} ; // 商品数量
for(int i=0;i<names.length;i++){ // 循环输出
dos.writeChars(names[i]) ; // 写入字符串
dos.writeChar('\t') ; // 写入分隔符
dos.writeFloat(prices[i]) ; // 写入价格
dos.writeChar('\t') ; // 写入分隔符
dos.writeInt(nums[i]) ; // 写入数量
dos.writeChar('\n') ; // 换行
}
dos.close() ; // 关闭输出流
}
};
以上程序的结果中的每条数据之间使用“\n”分隔,每条数据中的每个内容之间使用“\t”分隔。写入后就可以利用DataInputStream将内容读取进来。
DataInputStream类
DataInputStream是InputStream的子类,专门负责读取使用DataOutputStream输出的数据,此类定义如下:
public class DataInputStream extends FilterInputStream implements DataInput
此类继承自FilterInputStream类(FilterInputStream是InputStream的子类),同时实现DataInput接口,在DataInput接口中定义了一系列读入各种数据的方法。
DataInputStream类的常用方法
范例
- 操作二:从order.txt中读取数据
import java.io.DataInputStream ;
import java.io.File ;
import java.io.FileInputStream ;
public class DataInputStreamDemo{
public static void main(String args[]) throws Exception{ // 所有异常抛出
DataInputStream dis = null ; // 声明数据输入流对象
File f = new File("d:" + File.separator + "order.txt") ; // 文件的保存路径
dis = new DataInputStream(new FileInputStream(f)) ; // 实例化数据输入流对象
String name = null ; // 接收名称
float price = 0.0f ; // 接收价格
int num = 0 ; // 接收数量
char temp[] = null ; // 接收商品名称
int len = 0 ; // 保存读取数据的个数
char c = 0 ; // '\u0000'
try{
while(true){
temp = new char[200] ; // 开辟空间
len = 0 ;
while((c=dis.readChar())!='\t'){ // 接收内容
temp[len] = c ;
len ++ ; // 读取长度加1
}
name = new String(temp,0,len) ; // 将字符数组变为String
price = dis.readFloat() ; // 读取价格
dis.readChar() ; // 读取\t
num = dis.readInt() ; // 读取int
dis.readChar() ; // 读取\n
System.out.printf("名称:%s;价格:%5.2f;数量:%d\n",name,price,num) ;
}
}catch(Exception e){}
dis.close() ;
}
};
程序运行结果:
名称:衬衣; 价格:98.30; 数量:3
名称:手套; 价格:30.30; 数量:2
名称:围巾; 价格:50.50; 数量:1
在使用数据输入流时,因为每条记录之间使用“\t”作为分隔,每行记录之间使用“\n”作为分隔,所以要分别使用readChar()读取这两个分隔符,才能将数据正确地还原。
合并流
合并流的主要作用是将两个文件的内容合并成一个文件,如图所示:
如果要实现合并流,则必须使用SequenceInputStream类,此类的常用方法如表所示:
范例
- 操作一:合并两个文件
import java.io.File ;
import java.io.SequenceInputStream ;
import java.io.FileInputStream ;
import java.io.InputStream ;
import java.io.FileOutputStream ;
import java.io.OutputStream ;
public class SequenceDemo{
public static void main(String args[]) throws Exception { // 所有异常抛出
InputStream is1 = null ; // 输入流1
InputStream is2 = null ; // 输入流1
OutputStream os = null ; // 输出流
SequenceInputStream sis = null ; // 合并流
is1 = new FileInputStream("d:" + File.separator + "a.txt") ;
is2 = new FileInputStream("d:" + File.separator + "b.txt") ;
os = new FileOutputStream("d:" + File.separator + "ab.txt") ;
sis = new SequenceInputStream(is1,is2) ; // 实例化合并流
int temp = 0 ; // 接收内容
while((temp=sis.read())!=-1){ // 循环输出
os.write(temp) ; // 保存内容
}
sis.close() ; // 关闭合并流
is1.close() ; // 关闭输入流1`
is2.close() ; // 关闭输入流2
os.close() ; // 关闭输出流
}
};
以上程序在实例化SequenceInputStream类时指定了两个输入流,所以SequenceInputStream类在进行读取时实际上是从两个输入流中一起读取内容的。
压缩流
在日常的使用中经常会使用到WinRAR或WinZIP等压缩文件,通过这些软件可以把一个很大的文件进行压缩以方便传输,如图所示
![]()
在Java中为了减少传输时的数据量也提供了专门的压缩流,可以将文件或文件夹压缩成ZIP,JAR,GZIP等文件形式。
ZIP压缩输入/输出流简介
ZIP是一种较为常见的压缩形式,在Java中要实现ZIP的压缩需要导入java.util.zip包,可以使用此包中的ZipFile,ZipOutputStream,ZipInputStream和ZipEntry几个类完成操作。
注意:压缩的输入/输出流也属于InputStream或OutputStream的子类,但是却没有定义在Java.io包中,而是以一种工具类的形式提供的,在操作时还需要使用java.io包的支持。
ZipOutputStream类
如果要完成一个文件或文件夹的压缩,则要使用ZipOutputStream类。ZipOutputStream是OutputStream的子类,常用操作方法如表所示:
现在假设在D盘中存在一个text.txt文件,文件内容为:将文本文件压缩打包成ZIP文件
范例
- 操作一:压缩文件
import java.io.File ;
import java.io.FileInputStream ;
import java.io.InputStream ;
import java.util.zip.ZipEntry ;
import java.util.zip.ZipOutputStream ;
import java.io.FileOutputStream ;
public class ZipOutputStreamDemo01{
public static void main(String args[]) throws Exception{ // 所有异常抛出
File file = new File("d:" + File.separator + "text.txt") ; // 定义要压缩的文件
File zipFile = new File("d:" + File.separator + "text.zip") ; // 定义压缩文件名称
InputStream input = new FileInputStream(file) ; // 定义文件的输入流
ZipOutputStream zipOut = null ; // 声明压缩流对象
zipOut = new ZipOutputStream(new FileOutputStream(zipFile)) ;
zipOut.putNextEntry(new ZipEntry(file.getName())) ; // 设置ZipEntry对象
zipOut.setComment("www.ljz.cn") ; // 设置注释
int temp = 0 ;
while((temp=input.read())!=-1){ // 读取内容
zipOut.write(temp) ; // 压缩输出
}
input.close() ; // 关闭输入流
zipOut.close() ; // 关闭输出流
}
};
运行结果:
- 操作二:压缩文件夹
import java.io.File ;
import java.io.FileInputStream ;
import java.io.InputStream ;
import java.util.zip.ZipEntry ;
import java.util.zip.ZipOutputStream ;
import java.io.FileOutputStream ;
public class ZipOutputStreamDemo02{
public static void main(String args[]) throws Exception{ // 所有异常抛出
File file = new File("d:" + File.separator + "ljz") ; // 定义要压缩的文件夹
File zipFile = new File("d:" + File.separator + "ljzdir.zip") ; // 定义压缩文件名称
InputStream input = null ; // 定义文件输入流
ZipOutputStream zipOut = null ; // 声明压缩流对象
zipOut = new ZipOutputStream(new FileOutputStream(zipFile)) ;
zipOut.setComment("www.ljz.cn") ; // 设置注释
int temp = 0 ;
if(file.isDirectory()){ // 判断是否是文件夹
File lists[] = file.listFiles() ; // 列出全部文件
for(int i=0;i<lists.length;i++){
input = new FileInputStream(lists[i]) ; // 定义文件的输入流
zipOut.putNextEntry(new ZipEntry(file.getName()
+File.separator+lists[i].getName())) ; // 设置ZipEntry对象
while((temp=input.read())!=-1){ // 读取内容
zipOut.write(temp) ; // 压缩输出
}
input.close() ; // 关闭输入流
}
}
zipOut.close() ; // 关闭输出流
}
};
运行结果:
ZipFile类
在Java中,每一个压缩文件都可以使用zipFile表示,还可以使用ZipFile根据压缩后的文件名称找到每一个压缩文件中的ZipEntry并进行解压缩操作,ZipFile类的常用方法如表所示:
ZipFile类实例化需要File指定的路径,下面介绍ZipFile类的基本使用
范例
- 操作一:实例化ZipFile类对象
import java.io.File ;
import java.io.FileInputStream ;
import java.io.InputStream ;
import java.util.zip.ZipEntry ;
import java.util.zip.ZipOutputStream ;
import java.util.zip.ZipFile ;
import java.io.FileOutputStream ;
public class ZipFileDemo01{
public static void main(String args[]) throws Exception{ // 所有异常抛出
File file = new File("d:" + File.separator + "ljz.zip") ; // 找到压缩文件
ZipFile zipFile = new ZipFile(file) ; // 实例化ZipFile对象
System.out.println("压缩文件的名称:" + zipFile.getName()) ; // 得到压缩文件的名称
}
};
程序运行结果:
压缩文件的名称为:d:\ljz.zip
- 操作二:解压缩文件
import java.io.File ;
import java.io.FileInputStream ;
import java.io.InputStream ;
import java.io.OutputStream ;
import java.util.zip.ZipEntry ;
import java.util.zip.ZipOutputStream ;
import java.util.zip.ZipFile ;
import java.io.FileOutputStream ;
public class ZipFileDemo02{
public static void main(String args[]) throws Exception{ // 所有异常抛出
File file = new File("d:" + File.separator + "ljz.zip") ; // 找到压缩文件
File outputFile = new File("d:" + File.separator + "ljz_unzip.txt") ; // 定义解压缩的文件名称
ZipFile zipFile = new ZipFile(file) ; // 实例化ZipFile对象
ZipEntry entry = zipFile.getEntry("ljz.txt") ; // 得到一个压缩实体
OutputStream out = new FileOutputStream(outputFile) ; // 实例化输出流
InputStream input = zipFile.getInputStream(entry) ; // 得到一个压缩实体的输入流
int temp = 0 ;
while((temp=input.read())!=-1){
out.write(temp) ;
}
input.close() ; // 关闭输入流
out.close() ; // 关闭输出流
}
};
ZipInputStream类
ZipInputStream是InputStream的子类,通过此类可以方便的读取ZIP格式的压缩文件。
使用ZipInputStream可以像ZipFile一样取得ZIP压缩文件的每一个ZipEntry
范例
- 取得ljz.zip中的一个ZipEntry
import java.io.File ;
import java.io.FileInputStream ;
import java.io.InputStream ;
import java.util.zip.ZipEntry ;
import java.util.zip.ZipInputStream ;
import java.io.FileInputStream ;
public class ZipInputStreamDemo01{
public static void main(String args[]) throws Exception{ // 所有异常抛出
File zipFile = new File("d:" + File.separator + "ljz.zip") ; // 定义压缩文件名称
ZipInputStream input = null ; // 定义压缩输入流
input = new ZipInputStream(new FileInputStream(zipFile)) ; // 实例化ZIpInputStream
ZipEntry entry = input.getNextEntry() ; // 得到一个压缩实体
System.out.println("压缩实体名称:" + entry.getName()) ;
input.close() ;
}
};
程序运行结果:
压缩实体名称:ljz.txt
- 解压缩ljzdir.zip文件
import java.io.File ;
import java.io.OutputStream ;
import java.io.InputStream ;
import java.util.zip.ZipEntry ;
import java.util.zip.ZipFile ;
import java.util.zip.ZipInputStream ;
import java.io.FileInputStream ;
import java.io.FileOutputStream ;
public class ZipInputStreamDemo02{
public static void main(String args[]) throws Exception{ // 所有异常抛出
File file = new File("d:" + File.separator + "ljzdir.zip") ; // 定义压缩文件名称
File outFile = null ; // 输出文件的时候要有文件夹的操作
ZipFile zipFile = new ZipFile(file) ; // 实例化ZipFile对象
ZipInputStream zipInput = null ; // 定义压缩输入流
OutputStream out = null ; // 定义输出流,用于输出每一个实体内容
InputStream input = null ; // 定义输入流,读取每一个ZipEntry
ZipEntry entry = null ; // 每一个压缩实体
zipInput = new ZipInputStream(new FileInputStream(file)) ; // 实例化ZIpInputStream
while((entry = zipInput.getNextEntry())!=null){ // 得到一个压缩实体
System.out.println("解压缩" + entry.getName() + "文件。") ;
outFile = new File("d:" + File.separator + entry.getName()) ; // 定义输出的文件路径
if(!outFile.getParentFile().exists()){ // 如果输出文件夹不存在
outFile.getParentFile().mkdir() ; // 创建文件夹
}
if(!outFile.exists()){ // 判断输出文件是否存在
outFile.createNewFile() ; // 创建文件
}
input = zipFile.getInputStream(entry) ; // 得到每一个实体的输入流
out = new FileOutputStream(outFile) ; // 实例化文件输出流
int temp = 0 ;
while((temp=input.read())!=-1){
out.write(temp) ;
}
input.close() ; // 关闭输入流
out.close() ; // 关闭输出流
}
input.close() ;
}
};
程序运行结果:
解压缩ljz\ljz_1.txt文件
解压缩ljz\ljz_2.txt文件
解压缩ljz\ljz_3.txt文件
解压缩ljz\ljz_4.txt文件
解压缩ljz\ljz_5.txt文件以上程序首先使用ZipInputStream读取Zip格式的压缩文件,然后通过getNextEntry()方法依次读取出其中的每一个ZipEntry对象的名称,并通过ZipFile类取得每一个ZipEntry的输入流对象,在进行文件输出前,判断其输出文件夹文件是否存在,如果不存在则创建。
总结
至此,我已将IO流的主要的操作介绍完毕了,鉴于笔者经验有限,可能会有这样那样的不足,还请多多包涵!