黑马程序员--Java_IO流(二)

——- android培训java培训、期待与您交流! ———-

字符流

字符流其实就是通过转换流把字节流转换成字节流+编码表。
编码表有很多,不过我们最常见的有两种:

  • ACSII表:7位表示一个数据,最高位为符号位。
  • UTF-8:最多用三个字节来表示一个字符。能用一个就用一个,现在不行就用三个。

我们在写程序的时候,可以使用指定的编码表,如果不指定,则使用系统默认的编码表。

转换流

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;

/*
 * OutputStreamWriter:字符输出流
 *                 public OutputStreamWriter(OutputStream out):根据默认编码表把字节流的数据转换为字符流
 * public OutputStreamWriter(OutputStream out,Charset cs):根据指定编码表把字节流的数据转换为字符流
 * 
 * InputStreamReader:字符输入流
 *                 public InputStreamReader(InputStream in):根据默认编码表把字节流的数据转换为字符流
 *                 public InputStreamReader(InputStream in,Charset cs):根据指定编码表把字节流的数据转换为字符流
 * 
 */
public class ZiFu {
        public static void main(String[] args) throws IOException {
                InputStreamReader isr = new InputStreamReader(new FileInputStream(
                                "a.txt"));
                OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(
                                "b.txt"));

                int i = 0;
                while ((i = isr.read()) != -1) {
                        osw.write(i);
                }
                osw.flush();

                osw.close();
                isr.close();
        }
}

flush()和close()的区别:

  • A:close()关闭流对象,但是先刷新一次缓冲区。关闭之后,流对象不可以继续再使用了。
  • B:flush()仅仅刷新缓冲区,刷新之后,流对象还可以继续使用。

由于转换流的代码比较长,Java就提供了其子类供我们使用。

OutputStreamWriter = FileOutputStream + 编码表(GBK)
FileWriter = FileOutputStream + 编码表(GBK)

InputStreamReader = FileInputStream + 编码表(GBK)
FileReader = FileInputStream + 编码表(GBK)

转换流复制文件

import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

 /*
 * 需求:把当前项目目录下的a.txt内容复制到当前项目目录下的b.txt中
 * 
 * 数据源:
 *      a.txt -- 读取数据 -- 字符转换流 -- InputStreamReader -- FileReader
 * 目的地:
 *      b.txt -- 写出数据 -- 字符转换流 -- OutputStreamWriter -- FileWriter
 */
public class CopyFileDemo2 {
    public static void main(String[] args) throws IOException {
        // 封装数据源
        FileReader fr = new FileReader("a.txt");
        // 封装目的地
        FileWriter fw = new FileWriter("b.txt");

        // 一次一个字符数组
        char[] chs = new char[1024];
        int len = 0;
        while ((len = fr.read(chs)) != -1) {
            fw.write(chs, 0, len);
            fw.flush();
        }

        // 释放资源
        fw.close();
        fr.close();
    }
}

高效字符流

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class ZiFuDemo2 {
        public static void main(String[] args) throws IOException {
                BufferedReader br = new BufferedReader(new FileReader("a.txt"));
                BufferedWriter bw = new BufferedWriter(new FileWriter("b.txt"));

                BufferedReader br2 = new BufferedReader(new FileReader("a.txt"));
                BufferedWriter bw2 = new BufferedWriter(new FileWriter("c.txt"));

                int i = 0;
                while ((i = br.read()) != -1) {
                        bw.write(i);
                }

                char[] chs = new char[1024];
                int len = 0;
                while ((len = br2.read(chs)) != -1) {
                        bw2.write(chs);
                }

                br.close();
                bw.close();
                br2.close();
                bw2.close();
        }
}

高效字符流的特殊用法

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

/*
 * 字符缓冲流的特殊方法:
 * BufferedWriter:
 *      public void newLine():根据系统来决定换行符
 * BufferedReader:
 *      public String readLine():一次读取一行数据
 *      包含该行内容的字符串,不包含任何行终止符,如果已到达流末尾,则返回 null
 */
public class BufferedDemo {
    public static void main(String[] args) throws IOException {
        // write();
        read();
    }

    private static void read() throws IOException {
        // 创建字符缓冲输入流对象
        BufferedReader br = new BufferedReader(new FileReader("bw2.txt"));

        // 最终版代码
        String line = null;
        while ((line = br.readLine()) != null) {
            System.out.println(line);
        }

        //释放资源
        br.close();
    }

    private static void write() throws IOException {
        // 创建字符缓冲输出流对象
        BufferedWriter bw = new BufferedWriter(new FileWriter("bw2.txt"));
        for (int x = 0; x < 10; x++) {
            bw.write("hello" + x);
            // bw.write("\r\n");
            bw.newLine();
            bw.flush();
        }
        bw.close();
    }

}

其他类型的流

数据输入输出流

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

/*
 * 可以读写基本数据类型的数据
 * 数据输入流:DataInputStream
 *          DataInputStream(InputStream in)
 * 数据输出流:DataOutputStream
 *          DataOutputStream(OutputStream out) 
 */
public class DataStreamDemo {
    public static void main(String[] args) throws IOException {
        // 写
        // write();

        // 读
        read();
    }

    private static void read() throws IOException {
        // DataInputStream(InputStream in)
        // 创建数据输入流对象
        DataInputStream dis = new DataInputStream(
                new FileInputStream("dos.txt"));

        // 读数据
        byte b = dis.readByte();
        short s = dis.readShort();
        int i = dis.readInt();
        long l = dis.readLong();
        float f = dis.readFloat();
        double d = dis.readDouble();
        char c = dis.readChar();
        boolean bb = dis.readBoolean();

        // 释放资源
        dis.close();

        System.out.println(b);
        System.out.println(s);
        System.out.println(i);
        System.out.println(l);
        System.out.println(f);
        System.out.println(d);
        System.out.println(c);
        System.out.println(bb);
    }

    private static void write() throws IOException {
        // DataOutputStream(OutputStream out)
        // 创建数据输出流对象
        DataOutputStream dos = new DataOutputStream(new FileOutputStream(
                "dos.txt"));

        // 写数据了
        dos.writeByte(10);
        dos.writeShort(100);
        dos.writeInt(1000);
        dos.writeLong(10000);
        dos.writeFloat(12.34F);
        dos.writeDouble(12.56);
        dos.writeChar('a');
        dos.writeBoolean(true);

        // 释放资源
        dos.close();
    }
}

内存操作流

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;

/*
 * 内存操作流:用于处理临时存储信息的,程序结束,数据就从内存中消失。
 * 字节数组:
 *      ByteArrayInputStream
 *      ByteArrayOutputStream
 * 字符数组:
 *      CharArrayReader
 *      CharArrayWriter
 * 字符串:
 *      StringReader
 *      StringWriter
 */
public class ByteArrayStreamDemo {
    public static void main(String[] args) throws IOException {
        // 写数据
        ByteArrayOutputStream baos = new ByteArrayOutputStream();

        // 写数据
        for (int x = 0; x < 10; x++) {
            baos.write(("hello" + x).getBytes());
        }

        byte[] bys = baos.toByteArray();

        // 读数据
        ByteArrayInputStream bais = new ByteArrayInputStream(bys);

        int by = 0;
        while ((by = bais.read()) != -1) {
            System.out.print((char) by);
        }
    }
}

合并流

import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.SequenceInputStream;

/*
 * 以前的操作:
 * a.txt -- b.txt
 * c.txt -- d.txt
 * 
 * 现在想要:
 * a.txt+b.txt -- c.txt
 */
public class SequenceInputStreamDemo {
    public static void main(String[] args) throws IOException {
        // SequenceInputStream(InputStream s1, InputStream s2)
        // 需求:把ByteArrayStreamDemo.java和DataStreamDemo.java的内容复制到Copy.java中
        InputStream s1 = new FileInputStream("ByteArrayStreamDemo.java");
        InputStream s2 = new FileInputStream("DataStreamDemo.java");
        SequenceInputStream sis = new SequenceInputStream(s1, s2);
        BufferedOutputStream bos = new BufferedOutputStream(
                new FileOutputStream("Copy.java"));

        byte[] bys = new byte[1024];
        int len = 0;
        while ((len = sis.read(bys)) != -1) {
            bos.write(bys, 0, len);
        }

        bos.close();
        sis.close();
    }
}

序列化流和反序列化流

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

/*
 * 序列化流:把对象按照流一样的方式存入文本文件或者在网络中传输。对象 -- 流数据(ObjectOutputStream)
 * 反序列化流:把文本文件中的流对象数据或者网络中的流对象数据还原成对象。流数据 -- 对象(ObjectInputStream)
 */
public class ObjectStreamDemo {
    public static void main(String[] args) throws IOException,
            ClassNotFoundException {
        // 由于我们要对对象进行序列化,所以我们先自定义一个类
        // 序列化数据其实就是把对象写到文本文件
        // write();

        read();
    }

    private static void read() throws IOException, ClassNotFoundException {
        // 创建反序列化对象
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(
                "oos.txt"));

        // 还原对象
        Object obj = ois.readObject();

        // 释放资源
        ois.close();

        // 输出对象
        System.out.println(obj);
    }

    private static void write() throws IOException {
        // 创建序列化流对象
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(
                "oos.txt"));

        // 创建对象
        Person p = new Person("蔡依林", 27);

        // public final void writeObject(Object obj)
        oos.writeObject(p);

        // 释放资源
        oos.close();
    }
}

Properties

Properties的基本演示

import java.util.Properties;
import java.util.Set;

/*
 * Properties:属性集合类。是一个可以和IO流相结合使用的集合类。
 * Properties 可保存在流中或从流中加载。属性列表中每个键及其对应值都是一个字符串。 
 * 
 * 是Hashtable的子类,说明是一个Map集合。
 */
public class PropertiesDemo {
    public static void main(String[] args) {
        // 作为Map集合的使用
        Properties prop = new Properties();

        // 添加元素
        prop.put("it002", "hello");
        prop.put("it001", "world");
        prop.put("it003", "java");

        // 遍历集合
        Set<Object> set = prop.keySet();
        for (Object key : set) {
            Object value = prop.get(key);
            System.out.println(key + "---" + value);
        }
    }
}

Properties的特殊功能

import java.util.Properties;
import java.util.Set;

/*
 * 特殊功能:
 * public Object setProperty(String key,String value):添加元素
 * public String getProperty(String key):获取元素
 * public Set<String> stringPropertyNames():获取所有的键的集合
 */
public class PropertiesDemo2 {
    public static void main(String[] args) {
        // 创建集合对象
        Properties prop = new Properties();

        // 添加元素
        prop.setProperty("张三", "30");
        prop.setProperty("李四", "40");
        prop.setProperty("王五", "50");

        Set<String> set = prop.stringPropertyNames();
        for (String key : set) {
            String value = prop.getProperty(key);
            System.out.println(key + "---" + value);
        }
    }
}

Properties的load和store方法

import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Reader;
import java.io.Writer;
import java.util.Properties;

/*
 * 这里的集合必须是Properties集合:
 * public void load(Reader reader):把文件中的数据读取到集合中
 * public void store(Writer writer,String comments):把集合中的数据存储到文件
 */
public class PropertiesDemo3 {
    public static void main(String[] args) throws IOException {
        // myLoad();

        myStore();
    }

    private static void myStore() throws IOException {
        // 创建集合对象
        Properties prop = new Properties();

        prop.setProperty("李延旭", "21");
        prop.setProperty("康小广", "23");
        prop.setProperty("任兴亚", "25");

        Writer w = new FileWriter("name.txt");
        prop.store(w, "helloworld");
        w.close();
    }

    private static void myLoad() throws IOException {
        Properties prop = new Properties();

        // 注意:这个文件的数据必须是键值对形式
        Reader r = new FileReader("prop.txt");
        prop.load(r);
        r.close();

        System.out.println("prop:" + prop);
    }
}

总结

IO流是Java中比较常用的知识,记得分清字节流和字符流的区别,对于指定的文件,需要使用适合的流,不过字节流可以操作任何文件,如果你不知道用什么,那就使用字节流,有时效率可能会低,但肯定不会错。

——- android培训java培训、期待与您交流! ———-

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值