2019-03-02

作者: DreamPath | 来源:发表于2019-03-03 09:13 被阅读5次

    IO之字符流基础整理

    字符流:
    当使用字节流读取文本文件时,遇到中文字符时,可能不会显示完整的字符,由于一个中文字符可能占用多个字节存储。所以Java提供一些字符流类,以字符为单位读写数据,专门用于处理文本文件。

    字符输入流 Reader

    java.io.Reader抽象类是表示用于读取字符流的所有类的超类,可以读取字符信息到内存中。

    • public void close() :关闭此流并释放与此流相关联的任何系统资源。
    • public int read() : 从输入流读取一个字符。
    • public int read(char[] cbuf) : 从输入流中读取一些字符,并将它们存储到字符数组 cbuf中。
    FileReader子类

    java.io.FileReader类是读取字符文件的便利类。构造时使用系统默认的字符编码和默认字节缓冲区。

      1. 字符编码:字节与字符的对应规则。Windows系统的中文编码默认是GBK编码表。
      1. 字节缓冲区:一个字节数组,用来临时存储字节数据。

    读取字符串

      1. 读取字符: read 方法,每次可以读取一个字符的数据,提升为int类型,读取到文件末尾,返回 -1 ,循环读取。
    package Reader_Demo;
    
    import java.io.File;
    import java.io.FileReader;
    import java.io.IOException;
    import java.io.Reader;
    
    /**
     * FileReader(File file) : 创建一个新的 FileReader ,给定要读取的File对象。
     * FileReader(String fileName) : 创建一个新的 FileReader ,给定要读取的文件的名称
     */
    public class ReaderDemo1 {
        public static void main(String[] args) throws IOException {
    
            File file=new File("D:\\Java代码\\Java基础加强\\c.txt");
                //使用File对象创建流对象
            Reader reader1=new FileReader(file);
    
            //直接使用文件名称创建流对象
            Reader reader=new FileReader("D:\\Java代码\\Java基础加强\\c.txt");
            int len;
            //循环读取
            while((len=reader.read())!=-1){
                System.out.print((char)len);
    
            }
            reader.close();
            reader1.close();
    
        }
    }
    
    • 使用字符数组读取: read(char[] cbuf) ,每次读取b的长度个字符到数组中,返回读取到的有效字符个数, 读取到末尾时,返回 -1
    package Reader_Demo;
    
    import java.io.FileReader;
    import java.io.IOException;
    import java.io.Reader;
    
    public class ReaderDemo2 {
        public static void main(String[] args) throws IOException {
            FileReader reader=new FileReader("c.txt");
    
            //使用字符数组读取
            char [] ss=new char[2];
            // 定义变量,保存有效字符个数
            int len;
            // 定义字符数组,作为装字符数据的容器
            while((len=reader.read(ss))!=-1){
                    //将ss的int编码转化为字符串输出
                System.out.println(new String(ss));
            }
    
            char [] sss=new char[2];
            int lenss;
            while((lenss=reader.read(sss))!=-1){
                   //优化程序
                System.out.println(new String(sss,0,len));
            }
             reader.close();
        }
    }
    
    字符输出流 Writer
    • java.io.Writer 抽象类是表示用于写出字符流的所有类的超类,将指定的字符信息写出到目的地。它定义了字节输出流的基本共性功能方法。

    FileWriter类
    java.io.FileWriter 类是写出字符到文件的便利类。构造时使用系统默认的字符编码和默认字节缓冲区。

    package writer_demo;
    
    import java.io.File;
    import java.io.FileWriter;
    import java.io.IOException;
    
    /**
     * @author lx
     * @date 2019/3/3 - 6:54
     * FileWriter(File file) : 创建一个新的 FileWriter,给定要读取的File对象。
     * FileWriter(String fileName) : 创建一个新的 FileWriter,给定要读取的文件的名称。
     * 写出字符:
     *          write(int b) 方法,每次可以写出一个字符数据。
     * 注意:
     *      关闭资源时,与FileOutputStream不同。         
     *      如果不关闭,数据只是保存到缓冲区,并未保存到文件
     */
    public class FileWriterDemo1 {
        public static void main(String[] args) throws IOException {
            /*//使用File对象来创建流对象
            File dir=new File("D:\\Java代码\\Java基础加强\\c.txt");
    
            FileWriter fileWriter=new FileWriter(dir);*/
    
            //直接使用文件路径名创建流对象
            FileWriter files=new FileWriter("D:\\Java代码\\Java基础加强\\c.txt");
    //                写出字符
            files.write(97);//写出第一个字符
            files.write('a');//写出第二个字符
            files.write('c');//写出第三个字符
            files.write(30000);//写出第四个字符,中文编码中的一个汉字
    
            files.close();
                //输出结果:默认覆盖原文件数据。false
                    // aac田
        }
    }
    
    关闭和刷新
    • 因为内置缓冲区的原因,如果不关闭输出流,无法写出字符到文件中。
    • 但是关闭的流对象,是无法继续写出数据的。如果我们既想写出数据,又想继续使用流,就需要 flush 方法了。
    • 如果不使用flush方法,输入的字节将会只存在于缓冲区里,数据关闭将会丢失。
    package writer_demo;
    
    import java.io.File;
    import java.io.FileWriter;
    import java.io.IOException;
    
    /**
     * flush :刷新缓冲区,流对象可以继续使用。
     * close :先刷新缓冲区,然后通知系统释放资源。流对象不可以再被使用了。
     */
    public class WriterDemo2 {
        public static void main(String[] args) throws IOException {
            File dir=new File("D:\\Java代码\\Java基础加强\\c.txt");
    
            FileWriter fileWriter=new FileWriter(dir);
    
    //        写出字符
                fileWriter.write("刷");
                fileWriter.flush();
                fileWriter.write("新");//继续写出第二个字符,写出成功
                fileWriter.flush();
    
                fileWriter.write("关");
                fileWriter.close();
    
               // fileWriter.write("闭");//直接抛出异常 Stream closed  流被关闭了
             //   fileWriter.close();
        }
    }
    
    写出其他字符串
    package writer_demo;
    
    import java.io.FileWriter;
    import java.io.IOException;
    
    /**
     * @author lx
     * @date 2019/3/3 - 7:39
     * 1. 写出字符数组 : write(char[] cbuf) 和 write(char[] cbuf, int off, int len) ,
     *    每次可以写出字符数组中的数据,用法类似FileOutputStream
     *  写出字符串
     * 2. write(String str) 和 write(String str, int off, int len) ,
     * 每次可以写出字符串中的 数据,更为方便。
     */
    public class FileWriterDemo3 {
        public static void main(String[] args) throws IOException {
            FileWriter files=new FileWriter("D:\\Java代码\\Java基础加强\\c.txt");
    
            char [] chars="程序员的世界".toCharArray();
            //直接写出字符数组
            files.write(chars);
    
            //换行
                files.write("\r\n");
                //写出指定初始索引和长度的字符串
            files.write(chars,2,2);
    
            //换行
            files.write("\r\n");
    
            String msg="你好呀,Java";
            //写出字符串
            files.write(msg);
            //换行
            files.write("\r\n");
            //写出指定索引长度字符串
                files.write(msg,1,3);
    
            files.close();
        }
    }
    

    字符流,只能操作文本文件,不能操作图片,视频等非文本文件。

    io异常处理
    package io_exception;
    
    import java.io.FileWriter;
    import java.io.IOException;
    
    /**
     *异常建议使用 try...catch...finally
     */
    public class IOExceptionDemo {
    
        public static void main(String[] args) {
    
    //  jdk以前的处理方式:
    
                //声明流对象,便于关流
            FileWriter fw=null;
    
            try {
                //创建流对象   追加数据 true
                fw=new FileWriter("D:\\Java代码\\Java基础加强\\出师表.txt",true);
                //写出数据
                fw.write("lalala");
    
            } catch (IOException e) {
                e.printStackTrace();
            }finally {
                if (fw != null) {
                    try {
                        fw.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        //jdk7的处理方式
    
            // 要在try(异常处理多个语句时需用分号隔开){}
                try(FileWriter fileWriter=new FileWriter
                        ("D:\\Java代码\\Java基础加强\\出师表.txt",true)){
                        fileWriter.write("黑马程序员");
                }catch (IOException e){
                    e.printStackTrace();
                }
        }
    }
    

    使用jdk9的处理方式来实现文本文件的复制

    package copy_jdk9_StringFile;
    
    import java.io.FileNotFoundException;
    import java.io.FileReader;
    import java.io.FileWriter;
    import java.io.IOException;
    
    /**
     * @author lx
     * @date 2019/3/3 - 8:25
     *使用jdk9异常引入来实现文本文件的复制操作
     * JDK9中 try-with-resource 的改进,对于引入对象的方式,支持的更加简洁。
     * 被引入的对象,同样可以自动关闭, 无需手动close
     */
    public class CopyFileDemo {
        public static void main(String[] args){
            //创建文件的数据源
            try (FileReader fr = new FileReader("D:\\Java代码\\Java基础加强\\出师表.txt")) {){
    
           //创建文件的目的存储地
           FileWriter fw = new FileWriter("D:\\Java代码\\Java基础加强\\复制出师表.txt");
    
           try (fr; fw) {
               int len;
               while ((len = fr.read()) != -1) {
                   fw.write(len);
               }
           } catch (IOException e) {
               e.printStackTrace();
           }
            }
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
            }
    

    属性集

    • java.util.Properties 继承于 Hashtable ,来表示一个持久的属性集。它使用键值结构存储数据,每个键及其对应值 都是一个字符串。
    • 该类也被许多Java类使用,比如获取系统属性时, System.getProperties 方法就是返回一个 Properties 对象
    Properties类
    package properties_demo;
    
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.util.Properties;
    import java.util.Set;
    
    /**
     * 构造方法:
     *          public Properties() :创建一个空的属性列表。
     * 基本方法:
     *         public Object setProperty(String key, String value) : 保存一对属性。
     *         public String getProperty(String key) :使用此属性列表中指定的键搜索属性值。
     *         public Set<String> stringPropertyNames() :所有键的名称的集合
     * 与流相关方法:
     *          public void load(InputStream inStream) : 从字节输入流中读取键值对
     */
    public class PropertiesDemo {
        public static void main(String[] args) throws IOException {
            //创建属性集对象
            Properties properties = new Properties();
            //添加键值对元素
            properties.setProperty("filename","a.txt");
            properties.setProperty("length","2546894");
            properties.setProperty("location","D:\\a.txt");
    
            //打印属性集对象
            System.out.println(properties);
    
            //通过键的键获取属性值
            System.out.println(properties.getProperty("filename"));
            System.out.println(properties.getProperty("length"));
            System.out.println(properties.getProperty("location"));
    
            // 遍历属性集,获取所有键的集合
            Set<String> set=properties.stringPropertyNames();
    //            打印键值对
            for (String ss:set) {
                System.out.println(ss+"--"+properties.getProperty(ss));
            }
    
            //加载文本中信息到属性集
                properties.load(new FileInputStream("复制出师表.txt"));
    
            Set<String> set1=properties.stringPropertyNames();
                    //打印集合并输出
            for (String sss:set1) {
                System.out.println(sss+"---"+properties.getProperty(sss));
            }
                //文本中的数据,必须是键值对形式,可以使用空格、等号、冒号等符号分隔。
        }
    
    }
    

    相关文章

      网友评论

        本文标题:2019-03-02

        本文链接:https://www.haomeiwen.com/subject/msnyuqtx.html