JavaSE进阶第十六天——文件类和IO流

23 篇文章 0 订阅
15 篇文章 0 订阅

文件类

文件:是一组相关的记录数据的集合。

Java中文件的表示:File类。可以表示为文件,也可以表示为目录。

Java中文件路径的分类:

  1. 相对路径:a\b\a.txt
  2. 绝对路径:D:\a\b\a.txt

文件类(File)的常用方法:

  1. 创建一个新文件:createNewFile(“路径”)
  2. 创建一个目录:mkdir(“路径”)
  3. 创建多级目录:mkdirs(“路径”)
  4. 判断文件/目录是否存在:exists()
  5. 删除文件:delete()
  6. 获取文件内容大小:length()
  7. 获取文件的相对路径:getPath()
  8. 获取文件的绝对路径:getAbsolutPath()
  9. 获取上一次修改时间:lastModified()

IO流

**流的概念 **:流是一个通道,里面是一连串的连续的字符,按照FIFO方式进行流动。(FIFO:first in first out 先进先出)

流的分类

  1. 按照数据类型分:
    字节流
    字符流
  2. 按照流向分:
    输入流
    输出流

在这里插入图片描述

在这里插入图片描述
注意:流使用后记得关闭。否则会造成资源占用/耗费。

字节流

字节流适用于任何文件。

FileInputStream/FileOutputStream

FileInputStream/FileOutputStream:文件输入/输出流。
FileInputStream:读取文件中的数据到内存中。
FileOutputStream:将内存中的数据写入文件。
读取文件方法:read(),返回的是读取到的字节
写入数据方法:write()
方法很多,请自行查文档,太多了写不下

具体使用方法

//将a.txt复制到b.txt
class FileStreamTest{
	public static void main(String[] args){
		InputStream fis = null;
		OutputStream ois = null;
		 try {
            //创建文件输入流对象,参数是文件地址,可以是相对也可以是绝对地址
            fis = new FileInputStream("D:\\a\\b\\a.txt");
            //创建文件输出流对象,参数是文件地址,可以是相对也可以是绝对地址
            ois = new FileOutputStream("D:\\a\\b\\b.txt");
            int len = 0;//用于接收read()读取的字节
            while((len = fis.read()) != -1){
                ois.write(len);//写入指定文件
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if (fis!=null){
                try {
                //关闭流
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (ois != null){
                try {
                //清空流
                    ois.flush();
                    //关闭流
                    ois.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
	}
}

DataInputStream/DataOutputStream

DataInputStream/DataOutputStream:数据输入/输出流。
数据专属的字节流。
注意:DataOutputStream写的文件,只能使用DataInputStream去读。并且读的时候需要提前知道写入的顺序。 读的顺序需要和写的顺序一致,这样才可以正常取出数据。

例如:

DataOutputStream dos = new DataOutputStream(new FileOutputStream("data"));
       //这是存的顺序
        dos.writeByte(100);
        dos.writeShort(1000);
        dos.writeInt(10000);
        dos.writeLong(100000);
        dos.writeFloat(200);
        dos.writeDouble(300);
        dos.writeBoolean(true);
        dos.writeChar('中');
DataInputStream dis = new DataInputStream(new FileInputStream("data"));
        //打乱顺序就无法正常取出数据
        //正常取出数据:
        System.out.println(dis.readByte());
        System.out.println(dis.readShort());
        System.out.println(dis.readInt());
        System.out.println(dis.readLong());
        System.out.println(dis.readFloat());
        System.out.println(dis.readDouble());
        System.out.println(dis.readBoolean());
        System.out.println(dis.readChar());

BufferedInputStream/BufferedOutputStream

BufferedInputStream/BufferedOutputStream:缓冲字节输入/输出流。
自带缓冲区的字节流。(暂时不讲,留着字符流讲,因为使用方法都是基本一样的)

ObjectInputStream/ObjectOutputStream

ObjectInputStream/ObjectOutputStream:对象输入/输出流。
ObjectInputStream:反序列化
ObjectOutputStream:序列化
序列化:对象——>字节
反序列化:字节——>对象
注意事项

  1. 序列化的对象必须实现Serializable接口
  2. 一个类中的属性如果也是一个类,则此属性代表的类也必须序列化。
  3. 当类中属性有transient关键字修饰时,此属性不参与流的传输。
  4. 当类中属性是static关键字修饰属性时,此属性在流中正常传输,值受最终所给的值来决定。
  5. 为了防止序列化版本不一致,最好手工加上serialVersionUID的编号。

案例:

//序列化
public class ObjectOutputStreamTest01 {
    public static void main(String[] args) throws Exception{
        //创建java对象
        Student students = new Student("张三",2222);
        //序列化
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("log"));
        oos.writeObject(students);
        oos.flush();
        oos.close();
    }
}
class Student implements Serializable {
    private static final long serialVersionUID = 6845409090868647L;
    private String name;
    private int age;
    @Override
    public String toString() {
        return "Student{" +
                "姓名='" + name + '\'' +
                ", 年龄=" + age +
                '}';
    }
    public Student() {
    }
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
}
/*
反序列化:
 */
public class ObjectInputStreamTest01 {
    public static void main(String[] args) throws Exception{
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("log"));
        Object s = ois.readObject();
        System.out.println(s);
        ois.close();
    }
}

字符流

字符流适用于文本类文件。用于文本文件的时候效率比字节流高。

InputStreamReader/OutputStreamWriter

InputStreamReader/OutputStreamWriter:字节流转换为字符流
使用方法基本和上面的字节流一致。
注意:这里讲一下什么是包装流什么是节点流。
例如:new OutputStreamWriter(new FileOutputStream(“d:/a/b/a.txt”,true),“utf-8”);这个代码中,外层的叫包装流,内层的叫节点流。
包装流:new OutputStreamWriter();
节点流:new FileOutputStream(“d:/a/b/a.txt”,true),“utf-8”
特点:关闭流的时候只需要关闭包装流即可。

案例:

public class Test04 {

    public static void main(String[] args) {

        //1.产生基本字符输出流
        OutputStreamWriter osw=null;
        InputStreamReader isr=null;

        try {

            //2.产生输出对象
            osw=new OutputStreamWriter(new FileOutputStream("d:/a/b/a.txt",true),"utf-8");
            isr=new InputStreamReader(new FileInputStream("d:/a/b/a.txt"));

            //3.写入数据
            osw.write("你好");

            //4.清空
            osw.flush();

            //给个提示
            System.out.println("写入成功!");

            //3.5定义变量
            char[] chars=new char[100];
            int len=0; //返回的实际长度

            //4.读取数据
            while((len=isr.read(chars))!=-1) {

                System.out.println(len);
                //5.输出 char[]-->String
                String str=new String(chars);

                System.out.println(str);

            }


        }catch (Exception e) {

            e.printStackTrace();
        }finally {

            if(osw!=null) {
                try {
                    osw.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            if(isr!=null) {
                try {
                    isr.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

FileReader/FileWriter

FileReader/FileWriter:文件字符输入/出流

案例:

public class Test05 {

    public static void main(String[] args) {

        //1.产生字符便捷输出类
        //产生字符便捷输入类
        Writer writer=null;
        Reader reader=null;

        //2.使用try...catch
        try {
            //产生fileWriter对象
            writer=new FileWriter("d:/a/b/a.txt",true);

            //产生fileReader对象
            reader=new FileReader("d:/a/b/a.txt");
            //写入数据到文件
            writer.write("中文");

            //给个提示
            System.out.println("写入成功!");

            //读取数据
            char[] data=new char[100];
            int len=0; //返回长度

            while((len=reader.read(data))!=-1) {

                String str=new String(data);

                System.out.println(str);
            }

        }catch (Exception e) {

            e.printStackTrace();
        }finally {

            if(writer!=null) {
                try {
                    writer.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

BufferedReader/BufferedWriter

BufferedReader/BufferedWriter:缓冲字符输入/出流。

案例:

public class BufferedReaderTest01 {
    public static void main(String[] args) throws Exception{
        FileReader reader = new FileReader("Test01");
        //这里的构造方法中要传入一个Reader
        //此时对于这个程序来说:FileReader就是一个节点流。BufferedReader就是一个包装流。
        BufferedReader br = new BufferedReader(reader);

        //读一行 readLine();
        //什么时候结束呢?
        //当读到末尾时,会返回一个null
        String str1 = null;
        while ((str1 = br.readLine()) != null)
        System.out.println(str1);
        //关闭流
        //对于包装流来说,只需要关闭最外层流就行,里面的节点流会随着关闭。(看底层源代码)
        br.close();
    }
}
public class BufferedWriterTest01 {
    public static void main(String[] args) throws Exception{
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("Test03",true)));
        bw.write("Hello Kitty");
        bw.write("\n");
        bw.write("Hello King");
        bw.flush();
        bw.close();
    }
}

这里实际上不推荐使用BufferedWriter,推荐使用的是PrintWriter(打印字符流)。
案例:

public class Test07 {
    public static void main(String[] args) throws FileNotFoundException, UnsupportedEncodingException {
        //1.产生字符输出流
        PrintWriter pw=new PrintWriter(new FileOutputStream("d:/a/b/a.txt",true),true);
        //2.写数据
        pw.println("这是打印字符流,我很喜欢使用,哈哈3!");
        //3.给个提示
        System.out.println("写入成功!");
        //4.清空
        pw.flush();
    }
}

PrintStream

PrintStream:打印字节流
作用:改变输出的显示位置
其实我们常用的:System.out 也是一个打印字节流。查看文档可知。
在这里插入图片描述

/**
 * 使用PrintStream流改变输出的显示位置,结果存在文件中
 */
public class Test08 {

    public static void main(String[] args) throws FileNotFoundException {
    		 //System.out返回的是PrintStream
        //我们可以尝试不写System.out,改为我们喜欢的方式来进行输出
        PrintStream ps = System.out;
        ps.println("Hello zhangsan");
        ps.println("Hello lisi");
        ps.println("Hello king");
        
        PrintStream ps=new PrintStream("d:/a/b/a.txt");
        //改变输出位置
        System.setOut(ps);
        //打印输出
        System.out.println("这是测试PrintStream流,我已经改变了它的显示位置,我是否可以当一黑客了!");
        System.out.println("写入完毕!");
        /*
        	关闭流
        	实际上标准输出流不需要手动close()关闭
        	想想,我们使用System.out关闭过吗?
        */
        ps.close();
    }
}

IO流+Properties的联合使用

以后经常改变得数据,可以单独写道一个文件中,使用程序动态提取。将来只需要修改这个文件得内容,java代码不需要改动,不需要重新编译, 服务器也不需要重启就可以拿到动态信息。
类似于以上机制的这种文件,被称为配置文件。并且当配置文件的格式是键值对的时候,我们把这种文件叫做属性文件。
例如:
key1=value
key2=value
key3=value
java规范中有要求:属性配置文件建议以properties结尾。但不是必须这样。
这种以.properties结尾的文件在java中被称为:属性配置文件
其中Properties对象是专门存放属性配置文件内容的一个类。

注意

  1. 在属性配置文件中井号#表示注释
  2. 在属性配置文件中相同的key值重复value会被覆盖
  3. 最好不要有空格

案列:

public class IoPropertiesTest01 {
    public static void main(String[] args) throws Exception{
        //创建一个输入流对象
        FileInputStream fis = new FileInputStream("IoPropertiesTest01");
        //创建Properties对象的同时会创建一个Map集合
        Properties p = new Properties();
        //调用Properties中的load方法,会将文件中的数据加载到Map集合中。
        p.load(fis);//文件中的数据顺着管道加载到Map集合中,其中等号(冒号也行,但不建议)左边赋值给key,右边赋值给value。
        //能不能通过key获取value呢?;
        System.out.println(p.getProperty("password"));
    }
}

结果:
在这里插入图片描述

今天就到这里。拜拜~如有错误请指出,不胜感激

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值