Java IO核心操作(四)

本文详细介绍Java中的IO流操作,包括BufferedReader与Scanner类的使用、数据操作流(DataOutputStream与DataInputStream)的应用、合并流(SequenceInputStream)的功能及压缩流(ZipOutputStream与ZipFile类)的实践。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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流的主要的操作介绍完毕了,鉴于笔者经验有限,可能会有这样那样的不足,还请多多包涵!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Bryce李小白

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值