Java笔记15---一些有用的IO流总结

1.数据输入输出流
数据输入流: DataInputStream
数据输出流: DataOutputStream
特点: 可以写基本数据类型,可以读取基本数据类型

public class Demo1 {
    public static void main(String[] args) throws IOException {
        //数据输入输出流 DataOutputStream DataInputStream
        //特点:能写基本数据类型,能读取基本数据类型

        dataWrite();
        dataRead();
        //读的顺序要和写的顺序一样,否则易乱码
    }

    private static void dataRead() throws IOException {
        DataInputStream in=new DataInputStream(new FileInputStream("a.txt"));
        System.out.println(in.read());
        System.out.println(in.readInt());
        System.out.println( in.readLong());
        System.out.println(in.readShort());

    }
    private static void dataWrite() throws IOException {
        DataOutputStream out=new DataOutputStream(new FileOutputStream("a.txt"));
        out.write(2);//写入指定字节的低八位out.writeBoolean(true);//boolean类型
        out.writeInt(12);//int类型
        out.writeLong(12345);//long类型
        out.writeShort(3);//short类型
        out.writeByte(34);//将一个 byte 值以 1-byte 值形式写出到基础输出流中
        out.writeBytes("明天你会感激今天努力的你");
        out.writeDouble(3.1415926);
        out.writeFloat(9);
        out.writeUTF("爱生活爱 Java");
        out.flush();
        out.close();
    }
}

2.内存操作流
内存操作流的概述
a:操作字节数组
ByteArrayOutputStream
ByteArrayInputStream
此流关闭无效,所以无需关闭
b:操作字符数组
CharArrayWrite
CharArrayReader
c:操作字符串
StringWriter
StringReader

public class Demo2 {
    public static void main(String[] args) throws IOException {
        //内存操作流的概述
        //		a:操作字节数组
        //			ByteArrayOutputStream
        //			ByteArrayInputStream
        //			此流关闭无效,所以无需关闭//取出数据的方法 :toByteArray(),toString()
        ByteArrayOutputStream out=new ByteArrayOutputStream();
        byte[] bytes={123,122,22,120};
        out.write(bytes,0,3);
        out.write(10);
        //从缓冲区中取出数据
        byte[] bytes1=out.toByteArray();
        for(byte b:bytes1){
            System.out.println(b);
        }
        ByteArrayOutputStream out1=new ByteArrayOutputStream();
        out1.write("努力的你终将会有回报".getBytes());
        out1.write("\r\n".getBytes());
        out1.write("越努力越幸运".getBytes());
        byte[] bytes2=out1.toByteArray();
        System.out.println(out1.toString());

        System.out.println("------------------------");
        ByteArrayInputStream in=new ByteArrayInputStream(bytes1);
        int len=0;
        while((len=in.read())!=-1){
            System.out.println(len);
        }
        ByteArrayInputStream in1=new ByteArrayInputStream(bytes2);
        byte[] bytes3=new byte[1024];
        in1.read(bytes3);
        String str=new String(bytes3);
        System.out.println(str);
    }
}
public class Demo2 {
    public static void main(String[] args) throws IOException {
        //内存操作流的概述
        //		a:操作字节数组
        //			ByteArrayOutputStream
        //			ByteArrayInputStream
        //			此流关闭无效,所以无需关闭//取出数据的方法 :toByteArray(),toString()
        ByteArrayOutputStream out=new ByteArrayOutputStream();
        byte[] bytes={123,122,22,120};
        out.write(bytes,0,3);
        out.write(10);
        //从缓冲区中取出数据
        byte[] bytes1=out.toByteArray();
        for(byte b:bytes1){
            System.out.println(b);
        }
        ByteArrayOutputStream out1=new ByteArrayOutputStream();
        out1.write("努力的你终将会有回报".getBytes());
        out1.write("\r\n".getBytes());
        out1.write("越努力越幸运".getBytes());
        byte[] bytes2=out1.toByteArray();
        System.out.println(out1.toString());

        System.out.println("------------------------");
        ByteArrayInputStream in=new ByteArrayInputStream(bytes1);
        int len=0;
        while((len=in.read())!=-1){
            System.out.println(len);
        }
        ByteArrayInputStream in1=new ByteArrayInputStream(bytes2);
        byte[] bytes3=new byte[1024];
        in1.read(bytes3);
        String str=new String(bytes3);
        System.out.println(str);
    }
}

3.打印流:
printStream 字节打印流 printWriter 字符打印流
printStream: 为其他输出流添加了功能,使它们能够方便地打印各种数据值表示形式.。它还提供其他两项功能:PrintStream 永远不会抛出 IOException;而是,异常情况仅设置可通过 checkError 方法测试的内部标志;另外,为了自动刷新,可以创建一个 PrintStream。
printWriter 字符打印流
向文本输出流打印对象的格式化表示形式。与 PrintStream 类不同,如果启用了自动刷新,则只有在调用 println、printf 或 format 的其中一个方法时才可能完成此操作。

public class Demo4 {
    public static void main(String[] args) throws IOException {
        //PrintStream 字节打印流,能够打印出各种类型数据
        File file=new File("a.txt");
        PrintStream ps=new PrintStream(file);
        ps.println("123456");
        ps.println(true);
        ps.println(1);
        ps.println(3.14);
        //注意此字节打印流关联的不是屏幕,所以打印不到屏幕上
        System.out.println("---------------");
        //out 标准的输出流,关联的设备是屏幕,可以直接打印出来看到
        PrintStream out=System.out;
        out.println(true);
        out.println(123);
    }
}
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;

public class Demo5 {
    public static void main(String[] args)throws IOException {
        //PrintWriter字符打印流
        //没有自动刷新功能
        PrintWriter pw=new PrintWriter("a.txt");
        pw.println("爱生活,爱java");
        pw.write("123456");
        pw.println('m');
        pw.flush();
        pw.close();
        System.out.println("------------");
        //定义有自动刷新的功能
        PrintWriter pw1=new PrintWriter(new FileOutputStream("a.txt"),true);
        pw1.println("窗前明月光");
        pw1.println("疑是地上霜");
        pw1.println("热爱学习,热爱劳动");
    }
}
public class Demo6 {
    public static void main(String[] args)throws IOException {
          //打印流复制文本文件
        //打印流只能写,不能读取,我们采用BufferedReader读取
//        PrintWriter pw=new PrintWriter(new FileOutputStream("b.txt"),true);
//        pw.println("窗前明月光");
//        pw.println("疑是地上霜");
//        pw.println("举头望明月");
//        pw.println("低头思故乡");
//        pw.println("热爱学习,热爱劳动");
        BufferedReader reader=new BufferedReader(new FileReader("b.txt"));
        PrintWriter pw=new PrintWriter("copy.txt");
        String line=null;
        while((line=reader.readLine())!=null){
            pw.println(line);
            pw.flush();
        }
        pw.close();
        reader.close();
    }
}

4.标准的输入输出流
在System类中存在着两个静态的成员变量:
Public static final InputStream in:标准的输入流,对应的设备是键盘;
Public static final PrintStream out:标准的输出流,对应的设备是显示器。
注意:System.in的类型是InputStream。
System.out的类型是PrintStream。
案例:两种方式实现键盘录入
1.Scanner
2. BufferedReader
分析:由于标准的输入流对应的设备是键盘,且类型是Inputstream,故可以采用BufferedReader的readLine()方法。
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

public class Demo7 {
    public static void main(String[] args) throws IOException {
        //键盘的两种录入方式
        //1.Scanner
        //2.BufferedReader
        BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
        while(true){
            System.out.println("请键盘录入数据:");
            String s=br.readLine();
            if("end".equals(s)){
                break;
            }
            System.out.println(s);
        }
         br.close();
    }
}

5.随机访问流
RandomAccessFile概述 最大特点 能读能写
RandomAccessFile类不属于流,是Object类的子类。但它融合了InputStream和OutputStream的功能。此类支持对随机访问文件的读取和写入,随机访问文件的行为类似存储在文件系统中的一个大型byte数组,存在指向该数组的指针。该文件指针可以通过getFilePointer方法读取,并通过seek方法设置。
构造方法:
RandomAccessFile(File file, String mode)
创建从中读取和向其中写入(可选)的随机访问文件流,该文件由 File 参数指定。
RandomAccessFile(String name, String mode)
创建从中读取和向其中写入(可选)的随机访问文件流,该文件具有指定名称。
案例:
案例2:断点复制

public class Demo8 {
    public static void main(String[] args) throws IOException {
        //随机访问流 RandomAccessFile 可读可写
        //写数据
        WriteData();
        //读数据
         readData();
    }
    private static void readData() throws IOException {
        RandomAccessFile ra = new RandomAccessFile("c.txt", "rw");
        int  b= ra.read();
        long pointer=ra.getFilePointer();
        System.out.println("指针位置"+pointer);
        System.out.println(b);
        byte[] bytes=new byte[3];
        ra.read(bytes);
        pointer=ra.getFilePointer();
        System.out.println("指针位置"+pointer);
        for(byte be:bytes){
            System.out.println(be);
        }
        boolean bo=ra.readBoolean();
        pointer=ra.getFilePointer();
        System.out.println("指针位置"+pointer);
        System.out.println(bo);
        String s=ra.readUTF();
        pointer=ra.getFilePointer();
        System.out.println("指针位置"+pointer);
        System.out.println(s);
        //定位指针位置
        ra.seek(4);
        System.out.println(ra.readBoolean());
    }
    private static void WriteData() throws IOException {
        RandomAccessFile ra = new RandomAccessFile("c.txt", "rw");
        ra.write(95);
        byte[] bytes = {1,2,3,44,55};
        ra.write(bytes, 1, 3);
        ra.writeBoolean(true);
        ra.writeUTF("爱java");//一个汉字占五个字节
        ra.close();
    }
public class Demo9 {
    public static void main(String[] args) throws IOException {
        //断点复制文件,即文件复制一部分之后暂停了,下次可以从此处接着复制
        //采用的是RandomAccessFile中的seek指针
        RandomAccessFile r=new RandomAccessFile("论文.pdf","rw");
        RandomAccessFile w=new RandomAccessFile("论文2.pdf","rw");
        File file = new File("论文2.pdf");
        if(file.exists()){
            long len=file.length();
            r.seek(len);
            w.seek(len);
        }else{
            r.seek(0);
            w.seek(0);
        }
        copyFile(r,w);
    }
   private static void copyFile(RandomAccessFile r, RandomAccessFile w)throws IOException {
        String line=null;
        while((line=r.readLine())!=null){
            w.writeBytes(line);
            long pointer=w.getFilePointer();
            System.out.println(pointer);
        }
        r.close();
        w.close();
    }
}

6.序列化流与反序列化流
序列化:把对象通过流的方式存储到文件中,即把数据写到硬盘上。
反序列化:就是把文件存储的对象以流的方式还原成对象,即把数据读取到内存中。
序列化流:ObjectOutputStream
反序列化流:ObjectInputStream
注意:一个对象可以被序列化的前提是这个对象对应的类必须实现Serializable接口。
Serializable接口是一个标记接口,此接口中没有任何方法。

public class Demo10 {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        //序列化流ObjectOuptStream与反序列化流ObjectInputStream
        //序列化:就是把数据写入硬盘中
        //writeObj();

        //反序列化:就是把数据读到内存中
        readObj();
    }

    private static void readObj() throws IOException, ClassNotFoundException {
        ObjectInputStream ois=new ObjectInputStream(new FileInputStream("student.txt"));
        Object obj1=ois.readObject();
        Student stu1=(Student)obj1;
        System.out.println(stu1.name);
        System.out.println(stu1.age);
        obj1=ois.readObject();
        stu1=(Student)obj1;
        System.out.println(stu1.name);
        System.out.println(stu1.age);
        obj1=ois.readObject();
         stu1=(Student)obj1;
        System.out.println(stu1.name);
        System.out.println(stu1.age);
        obj1=ois.readObject();
         stu1=(Student)obj1;
        System.out.println(stu1.name);
        System.out.println(stu1.age);
        obj1=ois.readObject();
        stu1=(Student)obj1;
        System.out.println(stu1.name);
        System.out.println(stu1.age);
         obj1=ois.readObject();
         stu1=(Student)obj1;
        System.out.println(stu1.name);
        System.out.println(stu1.age);
        ois.close();

    }

    private static void writeObj() throws IOException {
        ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("student.txt"));
        Student s1=new Student("天天",12);
        Student s2=new Student("天天1",11);
        Student s3=new Student("天天2",12);
        Student s4=new Student("天天3",14);
        Student s5=new Student("天天4",16);
        Student s6=new Student("天天5",19);
        oos.writeObject(s1);
        oos.writeObject(s2);
        oos.writeObject(s3);
        oos.writeObject(s4);
        oos.writeObject(s5);
        oos.writeObject(s6);
        oos.close();
    }
}
public class Student implements Serializable {
    static final long serialVersionUID = 42L;//给Serializable添加的标记
     String name;
    transient  int age;//用transient标记不被序列化的成员变量。
    public Student(String name,int age){
        this.name=name;
        this.age=age;
    }
    public String getName(){
        return name;
    }
    public int getAge(){
        return age;
    }
}

7.Properties
(1)Properties 类表示了一个持久的属性集。Properties 可保存在流中或从流中加载。属性列表中每个键及其对应值都是一个字符串。
Properties父类是Hashtable,属于双列集合,这个集合中的键和值都是字符串 Properties不能指定泛型。
案例演示: Properties作为Map集合的使用

public class Demo11 {
    public static void main(String[] args) {
    //Properties作为Map集合使用
        Properties pro=new Properties();
        pro.put(1,"小明");
        pro.put(2,"天天");
        pro.put(3,"亮亮");
        pro.put(4,"顶顶");
        pro.put(5,"小小");
        pro.put(6,"明明");
        //遍历找值
        //方法1,键找值
        Set<Object> key=pro.keySet();
        for(Object k:key){
            Object value=pro.get(k);
            System.out.println(k+"----"+value);
        }
        System.out.println("---------------------");
        //方法2:键值对找值
        Set<Map.Entry<Object,Object>> entryset=pro.entrySet();
        for(Map.Entry<Object,Object> en:entryset){
             Object k=en.getKey();
             Object v=en.getValue();
            System.out.println(k+"-----"+v);
        }
    }
}

(2)Properties的特殊功能
public Object setProperty(String key,String value)添加元素,注意:第一次添加元素的时候返回的是null,下一次添加元素的时候返回的是上一次键对应的值。
public String getProperty(String key)根据键获取值
public Set stringPropertyNames()获取所有的键对应的Set集合
Properties集合的特有的遍历方式: 根据键找值
Set names = prop.stringPropertyNames() ;
for(String name : names){
// 获取值
String value = prop.getProperty(name) ;
// 输出
System.out.println(name + “----” + value);
}

public class Demo12 {
    public static void main(String[] args) {
        //Properties的特殊功能的使用
       // public Object setProperty(String key,String value)添加元素
        //注意:第一次添加元素的时候返回的是null,下一次添加元素的时候返回的是上一次键对应的值。
       // public String getProperty(String key)根据键获取值
        // public Set<String> stringPropertyNames()获取所有的键对应的Set集合
        Properties pro=new Properties();
       Object str= pro.setProperty("开开","心心");
        System.out.println(str);//null
        Object str1=pro.setProperty("开开","旺旺");
        System.out.println(str1);//心心
        pro.setProperty("小","大");
        pro.setProperty("左","右");
        System.out.println(pro.getProperty("小"));
        System.out.println("-------------------");
        Set<String> keyset=pro.stringPropertyNames();
        for(String key:keyset){
            Object v=pro.get(key);
            System.out.println(v);
        }
    }
}

(3)Properties的load()和store()功能
Properties和IO流进行配合使用:
public void load(Reader reader): 读取键值对数据把数据存储到Properties中
public void store(Writer writer, String comments)把Properties集合中的键值对数据写入到文件中, comments注释.

public class Demo13 {
    public static void main(String[] args) throws IOException {
       // Properties的load()和store()功能
//        public void load(Reader reader): 读取键值对数据把数据存储到Properties中
//        public void store(Writer writer, String comments)把Properties集合中的键值对数据写入

        Properties pro=new Properties();
        FileWriter fw=new FileWriter("user.txt");
        pro.setProperty("小","大");
        pro.setProperty("左","右");
        pro.setProperty("高","矮");
        pro.setProperty("lisi","wangwu");
        pro.store(fw,"反义词");
        InputStreamReader in=new InputStreamReader(new FileInputStream("user.txt"));
        Properties pro1=new Properties();
        pro1.load(in);
        Set<String> keyset=pro1.stringPropertyNames();
        for(String k:keyset){
            Object v=pro1.get(k);
            System.out.println(k+"---"+v);
        }

  }
}

(4) 判断文件中是否有指定的键如果有就修改值.
案例演示
需求:我有一个文本文件,我知道数据是键值对形式的,但是不知道内容是什么。
请写一个程序判断是否有“lisi”这样的键存在,如果有就改变其值为”100”
分析:
a: 把文本文件中的数据加载到Properties集合中。
b: 判断这个集合中是否有"lisi"这个键如果有直接修改其值为100。
c: 把集合中的数据再次存储到文本文件中。

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Properties;
import java.util.Set;
public class Demo14 {
    public static void main(String[] args)throws IOException {
        //我有一个文本文件,我知道数据是键值对形式的,但是不知道内容是什么。
        //		      请写一个程序判断是否有“lisi”这样的键存在,如果有就改变其值为”100”
        InputStreamReader in=new InputStreamReader(new FileInputStream("user.txt"));
        Properties pro=new Properties();
        pro.load(in);
        Set<String> keyset=pro.stringPropertyNames();
        for(String k:keyset){
            if(k.equals("lisi")){
                System.out.println("键lisi存在");
                pro.setProperty("lisi","100");
            }
        }
        for(String k1:keyset){
            Object v=pro.get(k1);
            System.out.println(k1+"---"+v);
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值