• Java-IO流之输入输出流基础示例


    一、理论:

    1、什么是输入输出?

    输入输出的对象是数据,数据的存储区域是磁盘或者光盘等设备,我们知道还有一个存储数据的空间----内存,其中磁盘的速度比较慢,内存的速度比较快,把数据读入内存的动作称作输入,把数据从内存存入磁盘的动作称作输出。

    2、流的分类按照流向:按照流向分为输入流和输出流

    按照数据内容:字节流(能处理字节的流对象)、字符流(能处理字符的流对象)。

    字符流的实质:字节流读取文字字节数据后,不直接操作而是先查指定的编码表,获取对应的文字,对文字进行操作,简单说,字符流=字节流+编码表。

    备注:字符流出现的原因:面向字节的流不便于处理Unicode形式的存储信息,Unicode中的每个字符都使用了两个字节来标识,所以字节流处理不方便,所以出现了字符流,字符流的读入和写出操作是基于量子界的Unicode码元的。

    关于Unicode推荐我的另一篇博文:ASCII到Unicode到UTF-8http://www.cnblogs.com/heisehenbai/p/7704827.html

    3、常用基类;

    字节流常用基类:

    • InputStream     
    • OutputStream

    字符流常用基类:

    • Reader           
    • Writer

    什么时候使用字符流:当需要操作字符的时候。

    二、示例:

    1、FileWriter的使用:

    • 创建相应的流----需要指定操作的路径,要操作什么文件new FileWriter(String fileName)(使用这个方法创建流,若是所指定的目录下没有该文件,则会创建,若是已存在,则会覆盖);
    • 对文件进行写入操作(调用write方法);
    • 调用flush方法,把写入缓冲区的内容冲刷到文件中(调用write(String content)方法写入的时候其实是把内容写入到了缓冲区中,磁盘中的文件事实上并不存在该内容)。
    • 关闭流(调用colose方法----事实上调用colose方法会自动对缓冲区进行冲刷,把缓冲区的内容写入文本)
    • 调用flush方法和调用colose方法的区别:调用flush方法之后还可以继续写入,而colose之后无法继续写入,反而会抛出IO异常。
            FileWriter fileWriter = null;
            try {
                fileWriter = new FileWriter("test.txt");
                fileWriter.write("eke test");
                fileWriter.flush();
            } catch (IOException e) {
                System.err.println(e.getMessage());
                throw new RuntimeException("写入文件失败!");
    
            } finally {
                if (fileWriter != null) {
                    try {
                        fileWriter.close();
                    } catch (Exception e) {
                        System.err.println(e.getMessage());
                        throw new RuntimeException("关闭文件流失败");
                    }
    
                }
            }
    

      运行结果将在项目的运行目录下创建文本文件test.txt,并且在文件中写入文本:eke test.

    代码解析:先创建一个FileWriter,这个类主要用来创建字符流,对文件进行操作。在IO操作当中我们经常会遇上IOException异常,因此我们需要捕获异常。另外,创建一个流进行对文件操作调用了操作系统的资源,在使用完毕之后需要对有限的操作系统资源进行释放,否则会导致系统资源被耗尽。所以在finally中需要调用close方法,同时,clos方法也是可能产生异常的,因此要进行捕获,而判断fileWriter不能为null的原因是fileWriter在创建的时候就有可能失败(可能出现找不到相应的路径,例如指定不存在的磁盘)。

    注意:上面第一步有提到过,我们使用new FileWriter(String fileName)创建流会覆盖原本存在的文件,所以如果是要对已存在的文件进行续写操作,就需要使用重载的构造函数new FileWriter(String fileName,boolean append)来创建写入流。

    2、FileWriter的使用:

    • 创建相应的流----需要指定操作的路径,要操作什么文件newWriter(String fileName)(使用这个方法创建流,若是所指定的目录下没有该文件,则会创建,若是已存在,则会覆盖);
    • 对文件进行读取操作(调用read方法,这个方法是返回一个int值,该值表示的是Unicode的码元----0~65535之间的整数);
        注意:因为返回的是码元,所以如果要打印出来成字符,需要强制转换成char类型的再输出,而在使用FileWriter的write方法的时候可以直接使用返回的码元进行写入。
    • 调用flush方法,把写入缓冲区的内容冲刷到文件中(调用write(String content)方法写入的时候其实是把内容写入到了缓冲区中,磁盘中的文件事实上并不存在该内容)。
    • 关闭流(调用colose方法----事实上调用colose方法会自动对缓冲区进行冲刷,把缓冲区的内容写入文本)
    • 调用flush方法和调用colose方法的区别:调用flush方法之后还可以继续写入,而colose之后无法继续写入,反而会抛出IO异常。
            FileReader fileReader = null;
            try {
                fileReader = new FileReader("test.txt");
    
                int charUnit=0;
                while((charUnit=fileReader.read())!=-1){
                    System.out.print((char)charUnit);
                }
    
            } catch (IOException e) {
                System.err.println(e.getMessage());
                throw new RuntimeException("写入文件失败!");
    
            } finally {
                if (fileReader != null) {
                    try {
                        fileReader.close();
                    } catch (Exception e) {
                        System.err.println(e.getMessage());
                        throw new RuntimeException("关闭文件流失败");
                    }
    
                }
            }
    

      以下是输出成果:

    Disconnected from the target VM, address: '127.0.0.1:36988', transport: 'socket'
    eke test
    Process finished with exit code 0
    

      

    3、改进:

    使用char数组来一次性读取多个字符:

                char[] contentArray = new char[1024];
    
                int charUnit = 0;
                while ((charUnit = fileReader.read(contentArray)) != -1) {
                    System.out.println(new String(contentArray,0,charUnit));
                }
    

      如上代码中的read方法使用了参数char[] contentArray;该方法返回的是读取的个数,并且把读取到的字符插入到contentArray数组中。

    4、FileWriter与FileReader的联合使用----复制

    FileReader fileReader = null;
            FileWriter fileWriter = null;
            
            try {
                fileReader = new FileReader("借我----木心.txt");
                fileWriter = new FileWriter("test.txt");
    
                char[] contentArray = new char[1024];
    
                int charUnit = 0;
                while ((charUnit = fileReader.read(contentArray)) != -1) {
                    System.out.println(new String(contentArray, 0, charUnit));
                    fileWriter.write(contentArray, 0, charUnit);
                }
            } catch (IOException e) {
                System.err.println(e.getMessage());
                throw new RuntimeException("写入文件失败!");
    
            } finally {
                if (fileReader != null) {
                    try {
                        fileReader.close();
                    } catch (Exception e) {
                        System.err.println(e.getMessage());
                        throw new RuntimeException("关闭文件流失败");
                    }
                }
    
                if (fileWriter != null) {
                    try {
                        fileWriter.close();
                    } catch (Exception e) {
                        System.err.println(e.getMessage());
                        throw new RuntimeException("关闭文件流失败");
                    }
                }
            }
    
            FileReader reader = null;
    
            try {
                reader = new FileReader("test.txt");
                char[] contentArray = new char[1024];
    
                int charUnit = 0;
                while ((charUnit = reader.read(contentArray)) != -1) {
                    System.out.println(new String(contentArray, 0, charUnit));
                }
    
            } catch (IOException e) {
                throw new RuntimeException("读取流出现异常");
    
            } finally {
                if (reader != null) {
                    try {
                        reader.close();
                    } catch (IOException e) {
                        throw new RuntimeException("关闭流出现异常");
                    }
                }
            }
    

      结果将打印出我很喜欢的一首诗:

    Connected to the target VM, address: '127.0.0.1:40996', transport: 'socket'
    借我
         ----木心
    
    借我一个暮年,
    借我碎片,
    借我瞻前与顾后,
    借我执拗如少年。
    借我后天长成的先天,
    借我变如不曾改变。
    借我素淡的世故和明白的愚,
    借我可预知的脸。
    借我悲怆的磊落,
    借我温软的鲁莽和玩笑的庄严。
    借我最初与最终的不敢,
    借我不言而喻的不见。
    借我一场秋啊,可你说这已是冬天。
    
    Disconnected from the target VM, address: '127.0.0.1:40996', transport: 'socket'
    

      

  • 相关阅读:
    ajax 请求登录超时跳转登录页的示例代码
    [WPF]实现密码框的密码绑定
    Linq系列(5)——表达式树之案例应用
    idea设置内存大小
    idea右下角显示使用内存情况
    idea打开Run Dashboard
    java的byte[]与String相互转换
    java有包名的调用没有包名的类,用反射
    【转】查看电脑显卡型号及显卡性能
    idea关闭sonarLint自动扫描
  • 原文地址:https://www.cnblogs.com/heisehenbai/p/7895736.html
Copyright © 2020-2023  润新知