Java第14章作业:I/0输入输出

本章主要内容

  • 流的分类
  • 字节流与字符流
  • 流的装配与串行化
  • 文件操作

第一题:Java中流的分类有哪些?

Java中流的分类有3种,分别可以按照读取类型、流动方向与流的源头来分类。

按读取类型分类,可以分为字节流与字符流

  1. 字节流:字节流以字节(byte)作为处理单位,一次仅读入或输出一个字节;在Java中,字节流是由InputStreamOutputStream两个抽象类所衍生的一系列子类所组成的;
  2. 字符流:与字节流不同,字符流以字符作为处理单位;在Java中,字符流是由ReaderWriter两个抽象类所衍生的一系列子类所组成的。

注意:字节流与字符流不能混用,即字节流的对象引用不能指向字符流的对象,反正亦然。

按照流动方向分类,可以分为输入流与输出流:

  1. 输入流:即用来读取数据的流,可以将数据从外部设备读入内存中;
  2. 输出流:即将数据输出到指定的地方去,可以输出到终端、文件,也可以通过网络通信发送给对方。

按照流的源头分类

  1. 节点流:即从特定的数据源头读取数据,这些数据源可以是文件、终端、网络设备等;
  2. 过滤流:过滤流不从特定的数据源读取数据,而是通过连接节点流来对数据进行更加复杂强大的操作,比如BufferedInputStreamBufferedOutputStream两个过滤流就提供了缓存的功能,使得读取更加地高效;

第二题:字节流InputStream和OutputStream的子类分别有哪些?请举例说明其使用场景。与其对应的字符流分别有哪些?

下图是Java中I/O的整体轮廓,对于InputStream类的子类作了介绍,OutputStream的子类名称与InputStream子类名称类似,仅需要将InputStream改为OutputStream即可。
在这里插入图片描述
常用字节流与字符流与它们的对应关系如下:
在这里插入图片描述

第三题:字节流与字符流的转化是怎样的?Java对此提供了哪些支持?

字节流与字符流的转化概括

Java对于两种流的转化提供了两个类来支持,但转化的方向是固定的,仅可以按照以下两种转化方向进行:

  1. 输入字节流转为字符流:使用InputStreamReader类,该类的名字也很好理解,就是将输入流(InputStream)转为字符流(Reader);
    其构造函数为:InputStreamReader(InputStream in),可以理解为从一个InputStream字节流读入后转为字符流。
  2. 输出字符流转为字节流:一个是OutputStreamWriter类,该类的名字倒不太好理解,但记住就行了;另一种方法是使用PrintWriter类将字符流转为字节流,这个类可以输出不同类型(整型、浮点型、String类等)的数据,而OutputStreamWriter类仅可以输出字符类型的数据。
    两个类的构造函数为:OutputStreamWriter(OutputStream out)PrintWriter(OutputStream out) ,可以理解为将字符流通过OutputStreamWriterPrintWriter转为字节流,然后向out进行输出;

字节流与字符流的转化–代码示例

以下面两题为例,在其中运用字节流与字符流的转化。
在这里插入图片描述

loadFile函数:

    public static String loadFile(String filename){
        StringBuffer contents = new StringBuffer();
        String tmp;

        try{
            BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(filename))); /** 将字节流转成了字符流 */
            while((tmp=reader.readLine()) != null){
                contents.append(tmp+"\n");
            }    
            reader.close();
        } catch (IOException e){
            System.out.println("Error!");
            e.printStackTrace();
        }

        return contents.toString();
    }

saveFile函数:


    public static boolean saveFile(String filename, String contents){
        try{
            BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(filename))); /** 输出字符流转为字节流 */
            writer.write(contents, 0, contents.length());
            writer.close();

        } catch (Exception e){
            System.out.println("Error");
            e.printStackTrace();
            return false;
        }
        return true;
    }

主函数中对这两个函数的调用代码如下:

    public static void main(String[] args){
        String contents = loadFile("./test.txt");
        System.out.print(contents);
        saveFile("./test2.txt", contents);
    }

第四题:Java中的过滤流(流的装配)有什么作用?请举例说明常用的过滤流。

过滤流的作用
普通的流读取或写入时没有缓冲功能,只能读取或写入字节或字符,而过滤流的作用就是为普通的流添加一些复杂的功能,如缓冲功能、操作(读取)各种数据类型等功能。

常用的过滤流

字节流中常用的过滤流:

  1. BufferedInputStreamBufferedOutputStream:提供缓冲功能,代码示例如下:

        public static void main(String[] args){
            try{
                BufferedInputStream reader = new BufferedInputStream(new FileInputStream("./test.txt"));
                BufferedOutputStream writer = new BufferedOutputStream(new FileOutputStream("./test2.txt"));
                int n=512, s=0;
                byte[] buffer = new byte[n];
                while((s=reader.read(buffer, 0, n)) != -1){
                    writer.write(buffer, 0, s);
                    System.out.println("writting contents...");
                }
    
                reader.close();
                writer.close();
    
            } catch (Exception e){
                System.out.println("Error");
                e.printStackTrace();
            }
        }
    
  2. DataInputStreamDataOutputStream:提供对多种数据类型的读写功能,代码示例如下:

            try{
                DataOutputStream writer = new DataOutputStream(new BufferedOutputStream(new FileOutputStream("./test_DataStream.txt")));
                
                writer.writeInt(234); // 写入整型
                writer.writeDouble(3.244); // 写入双精度浮点数
                writer.writeUTF("hahaha"); // 写入字符串
                writer.close();
    
                DataInputStream reader = new DataInputStream(new BufferedInputStream(new FileInputStream("./test_DataStream.txt")));
    
                System.out.println(reader.readInt()); 
                System.out.println(reader.readDouble()); 
                System.out.println(reader.readUTF()); 
    
                reader.close();
            
            } catch (Exception e){
                System.out.println("Error");
                e.printStackTrace();
            }
    

字符流中常用的过滤流:

  1. BufferedReaderBufferedWriter

            try{
                String file = "./test_reader.txt";
                BufferedWriter writer = new BufferedWriter(new FileWriter(file));
                String contents = "Hello, I like programming.";
                writer.write(contents, 0, contents.length());
                writer.close();
    
                BufferedReader reader = new BufferedReader(new FileReader(file));
                System.out.println(reader.readLine());
                reader.close();
    
            } catch (Exception e){
                System.out.println("Error");
                e.printStackTrace();
            }
    
  2. PrintWriter:支持多种数据类型的输出,缺点是没有对应的读取流来读入不同数据类型,代码示例如下:

            PrintWriter out = new PrintWriter(System.out, true);
            out.println("Hello");  
            out.println(4); //输出整型
            out.println(3.45); // 输出浮点数
            
    

第五题:什么是对象的序列化和反序列化?Java对此提供了哪些支持?

概念

  1. 对象的序列化:又叫串行化(Serialization),序列化指的是将对象转化为字节序列,当将对象转为字节后便可以将对象存储在文件中或在网络上进行传输;
  2. 对象的反序列化:将某个对象的字节序列恢复成原来对象的过程称为反序列化;

Java对序列化与反序列化提供的支持

Java的io包中提供了两个类来对对象进行序列化与反序列化,这两个类是ObjectOutputStream(序列化)与ObjectInputStream(反序列化)。

注意:只有实现了java.io.Serializable接口的类才可以被序列化,因此在使用ObjectOutputStream对对象进行序列化时,要对对象所属的类实现java.io.Serializable接口。

下面是这两个类的示例代码:

        try{
            String file = "./object.obj";

            /** 序列化 */
            ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(file));
            oos.writeUTF("This class is a `String`");
            String s = "hahahaha";
            oos.writeObject(s);
            oos.close();

            /** 反序列化 */
            ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file));
            System.out.println(ois.readUTF()); // 读取字符串

            s = (String)ois.readObject(); // 读取对象,并将对象转为其所属的类
            System.out.println(s);
            ois.close();

        } catch (Exception e){
            System.out.println("Error");
            e.printStackTrace();
        }

第六题:Java的File类表示什么?有什么作用?

File类介绍与作用:

Java的File类是对文件和路径名的抽象表示,可以通过File类来对文件和路径进行许多操作,这些操作包括删除、创建、重命名文件和目录等,还可以判断文件或目录是否存在,获取文件大小等信息,真的是非常地方便。

File类常用方法

1、构造方法

方法名使用说明
File(String pathname)将指定的路径名字符串转成一个抽象的路径名来创建一个新的File实例
File(String parent, String child)通过两个分别表示父路径和子路径的字符串来创建File实例
File(File parent, String child)从父目录的抽象路径和子路径名创建File实例

2、常用方法

方法名使用说明
boolean canRead()测试应用程序是否能从指定的文件中进行读取
boolean canWrite()测试应用程序是否能写当前文件
boolean delete()删除当前对象指定的文件或目录
boolean exists()测试当前的File是否存在
boolean isAbsolute()判断当前路径是否是绝对路径
boolean isDirectory()判断当前File是否是路径
boolean isFile()判断当前File是否是普通文件
boolean mkdir()根据当前File来创建目录
boolean mkdirs()可以创建多层目录(这些目录不存在)
boolean renameTo(File dest)将当前File改名为指定的File
long lastModified()返回当前 File 对象表示的文件最后修改的时间,返回的是一串数字,表示的是从1970年1月1日以来到现在所经历的毫秒数,可以通过Date类来对这个数字进行包装,获取可读性更强的时间表示
long length()返回当前 File 对象表示的文件大小,以字节为单位;若File是路径则返回0
String getAbsolutePath()获取绝对路径
String getName()获取当前文件名或路径名(最低一级的路径)
String getParent()获取上一层路径
String[] list()返回当前 File 对象指定的路径文件列表
String[] list(FilenameFilter)返回当前 File 对象指定的目录中满足指定过滤器的文件列表

第七题:Java对文件的读写分别提供了哪些支持?

Java对文件的读操作提供了FileInputStreamFileReader两个类进行支持,
对文件的写操作提供了FileOutputStreamFileWriter两个类进行支持,下面列举一下这四个类常用的构造函数。

1、字节流 FileInputStream

方法名使用说明
FileInputStream(File file)使用File类的实例来构造输入字节流
FileInputStream(String name)使用字符串表示的文件名来构造输入字节流

2、字节流 FileOutputStream

方法名使用说明
FileOutputStream(File file)使用File类的实例来构造输出字节流
FileOutputStream(File file, boolean append)使用File类的实例来构造输入出节流,append参数表示是否对文件追加内容
FileOutputStream(String name)使用字符串表示的文件名来构造输出字节流
FileOutputStream(String name, boolean append)使用字符串表示的文件名来构造输出字节流,append参数表示是否对文件追加内容

3、字符流FileReader

方法名使用说明
FileReader(File file)使用File类的实例来构造输入字符流
FileReader(String fileName)使用字符串表示的文件名来构造输入字符流

4、字符流FileWriter

方法名使用说明
FileWriter(File file)使用File类的实例来构造输出字符流
FileWriter(File file, boolean append)使用File类的实例来构造输出字符流,append参数表示是否对文件追加内容
FileWriter(String fileName)使用字符串表示的文件名来构造输出字符流
FileWriter(String fileName, boolean append)使用字符串表示的文件名来构造输出字符流,append参数表示是否对文件追加内容
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值