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