Java IO流

IO 流

1. 流

1.1 流的概念:

内存与存储设备之间传输数据的通道

1.2 流的分类

按方向分
  • 输入流: 将 < 存储设备 > 中的内容读入到 < 内存 > 中.
  • 输出流: 将 < 内存 > 中的内容写入到 < 存储设备 > 中.
按代为分
  • 字节流: 以字节为单位, 可以读写所有数据.
  • 字符流: 以字符为单位, 只能读写文本数据.
按功能分
  • 节点流: 具有实际传输数据的读写功能.
  • 过滤流: 在街电流的基础之上增强功能.

2. 字节流

2.1 字节流的父类(抽象类)

InputStream 字节输入流
  • public int read() {}
  • public int read(byte[] b) {}

读取输入流存储在 字节数组b中

  • public int read(byte[] b, int off , int len){}

偏移量off, 读取长度len

OutputStream 字节输出流
  • public void write (int n) {}
  • public void write (byte[] b) {}
  • public void write (byte[] b, int off, int len) {}

上面抽象类的两个子类:

2.2-1 FileInputStream

  • public int read (byte[] b)
    从流中读取多个字节, 将读到的内容存入b数组, 返回实际读到的字节数; 如果达到文件的尾部, 则返回-1

2.2-2 FileOutputStream

  • public void write (byte[] b)
    一次写多个字节, 将b数组中所有的字节, 写入输出流
package cn.ylq.filestream;

import java.io.FileInputStream;
import java.io.FileOutputStream;

public class FileIOStudy {
    public static void main(String[] args) throws Exception {
        FileInputStream fis = new FileInputStream("F:\\文档\\杂七杂八\\test.txt");
        byte[] dataList = new byte[1024];
        int count = fis.read(dataList);
        System.out.println(count);
        System.out.println(new String(dataList));
        fis.close();
        FileOutputStream fos = new FileOutputStream("F:\\文档\\杂七杂八\\test.txt",true);
        String line = "\n 因为有了因为,\n 所以有了所以,\n 既然已成既然,\n 何必再说何必.";

        fos.write(line.getBytes());
        fos.close();
    }
}

案例-复制一张图片

package cn.ylq.filestream;

import java.io.*;

public class Demo01 {
    public static void main(String[] args) throws IOException {
        FileInputStream in = new FileInputStream("F:\\文档\\杂七杂八\\test\\pic.jpg");
        FileOutputStream out = new FileOutputStream("F:\\文档\\杂七杂八\\test\\pic2.jpg",true);
        byte[] buf = new byte[1024*8];
        int counter = 0;
        while((counter=in.read(buf))!=-1){
            out.write(buf,0,counter);
        }
        in.close();
        out.close();
        System.out.println("复制完成");
    }
}

2.3 字节缓冲流

  • 缓冲流: BufferedInputStream / BufferedOutputStream
  • 提高IO销量, 减少访问磁盘的次数;
  • 数据存储在缓冲区中, flush 是将缓存区的内容写入文件中, 也可以直接 close .
package cn.ylq.filestream;

import java.io.*;

public class Demo02 {
    public static void main(String[] args) throws Exception {
        FileInputStream fis = new FileInputStream( "F:\\文档\\杂七杂八\\test.txt" );
        BufferedInputStream bis = new BufferedInputStream(fis,1024*8);
        int data = 0;
        while((data=bis.read())!=-1){
            System.out.print((char)data);
        }
        bis.close();
    }
}


package cn.ylq.filestream;

import java.io.*;

public class Demo03 {
    public static void main(String[] args) throws Exception {
        FileOutputStream fos = new FileOutputStream("F:\\文档\\杂七杂八\\试试中文行不行.txt");
        BufferedOutputStream bos=new BufferedOutputStream(fos);
        String line = "你好,乱码";
        byte[] cells = line.getBytes();
        bos.write(cells);
        bos.flush();
        bos.close();

    }
}

2.4 对象流

  • 对象流: ObjectOutputStream / ObjectInputStream
  • 增强了缓冲区功能
  • 增强了读写8种基本数据类型和字符串功能
  • 增强了读写对象的功能

readObject() 从流中读取一个对象
writeObject(Object obj) 向流中写入一个对象
序列化的对象必须实现Serializable接口,其对象属性也必须实现Serializable接口
类里声明赋值属性serialVersionUID 序列化版本ID,保证反序列化回来的也是同一个类
transient关键词可以让其后的属性方法不被序列化, 短暂的, 意味保存在内存中
静态属性也不能呗序列化

  • 读写的对象也可以是List实现批量操作

  • 使用流传输对象的过程称为序列化\反序列化

package cn.ylq.filestream;

import java.io.Serializable;

public class Ox implements Serializable {
    private int id;
    private String name;
//后面不用看

    public Ox() {
    }

    public Ox(int id, String name) {
        this.id = id;
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    @Override
    public String toString() {
        return "Ox{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }
}

package cn.ylq.filestream;

import java.io.*;

public class Demo04 {
    public static void main(String[] args) throws Exception {
        FileOutputStream fos = new FileOutputStream("F:\\文档\\杂七杂八\\Ox");
        ObjectOutputStream oos = new ObjectOutputStream(fos);
        Ox no1 = new Ox(1,"小花");
        Ox no2 = new Ox(2,"宫本武藏");
        oos.writeObject(no1);
        System.out.println(no1+"导入完成!");
        oos.writeObject(no2);
        System.out.println(no2+"导入完成!");
        oos.close();
    }
}

package cn.ylq.filestream;

import java.io.*;

public class Demo05 {
    public static void main(String[] args) throws Exception {
        FileInputStream fis = new FileInputStream("F:\\文档\\杂七杂八\\Ox");
        ObjectInputStream ois = new ObjectInputStream(fis);
        Object my;
        Object yours;
        my=ois.readObject();
        System.out.println(my);
        yours=ois.readObject();
        System.out.println(yours);
        ois.close();
    }
}

3. 字符流

3.1 字符流的的父类(抽象类)

Reader 字符输入流
  • public int read ( ){}
  • public int read (char[] c) {}
  • public int read (char[] b, int off, int len) {}
Writer 字符输出流
  • public void write (int n) {}
  • public void write (String str) {}
  • public void write (char[] c) {}

3.2 文件读写

FileReader
  • public int read (char[] c)
    从流中读取多个字符, 将读到的内容存入c数组, 返回实际读到的字符数; 如果达到文件的尾部, 则返回-1

Object - Reader - InputStreamReader - FileReader
read方法假定默认字符编码和缓冲区大小适合当的.如果要自己指定这些值,
可以现在FileInputStreamReader上构造一个InputStreamReader

public class Demo06 {
    public static void main(String[] args) throws Exception {
        FileReader fr = new FileReader("F:\\文档\\杂七杂八\\试试中文行不行.txt");
/*        int data = 0;
        while((data=fr.read())!=-1){
            System.out.print((char)data);
        }*/
        
        int count = 0;
        char[] buf =new char[1024];
        while((count=fr.read())!=-1) {
            String line = new String(buf);
            System.out.println(line);
        }
        
        fr.close();
    }
}
FileWriter
  • public void write (String str)
    一次写多个字符, 将字符串中所有的字符, 写入输出流
package cn.ylq.filestream;

import java.io.*;

public class demo07 {
    public static void main(String[] args) throws Exception {
        FileWriter fw = new FileWriter("试试中文行不行.txt");
        fw.write("/r/n人的梦想是不会终结的!");
        fw.flush();
        fw.close();
    }
}

3.3 字符缓冲流

  • 缓冲流: BufferedReader / BufferedWriter
  • 高效读写
  • 支持输入换行符
  • 可一次写(读)一行
  • BufferedReader 的 readLine() 方法, 读取一行字符串.
  • BufferedWriter 的 newLine() 方法, 输入一个换行符. 比起手动录入 \r\n 可以适配不同操作系统的换行
package cn.ylq.filestream;

import java.io.*;

public class Demo09 {
    public static void main(String[] args) throws Exception {
        FileReader fr = new FileReader ("F:\\文档\\杂七杂八\\test.txt");
        BufferedReader br = new BufferedReader(fr);
        String line = "这是个空文件呀!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!";
        while(line!=null) {
            line = br.readLine();
            System.out.println(line);
        }
        br.close();
    }
}

4. 打印流 PrintWriter

print 方法比起 write 可以跟的参数类型更多

package cn.ylq.filestream;

import java.io.*;

public class Demo11 {
    public static void main(String[] args) throws Exception {
        PrintWriter pw = new PrintWriter("F:\\文档\\杂七杂八\\暹罗猫.txt");
        pw.println(97);
        pw.println(3.1415927);
        pw.println(true);
        pw.println("嬲");
        pw.close();
    }
}

5. 转换流

  • 桥转换流: InnputStreamReader / OutputStreamWriter
  • 可将字节流转换为字符流
  • 可设置字符的编码方式
package cn.ylq.filestream;

import java.io.*;

public class Demo13 {

    public static void main(String[] args) throws Exception {
        FileOutputStream fos = new FileOutputStream("F:\\文档\\杂七杂八\\字节码文件哦");
        OutputStreamWriter osw = new OutputStreamWriter(fos,"utf-8");
        osw.write("长颈鹿的脖子那么长 哽咽的时候是不是很难受\r\n" +
                "章鱼有三颗心脏 心痛的时候是不是很疼\r\n" +
                "乌鸦可以学人说话 尴尬的时候会不会装咳嗽\r\n" +
                "骆驼有长长的睫毛 想哭的时候能不能说眼睛进了沙\r\n" +
                "蛇没有宽宽的肩膀 她累的时候给不了能够依靠的温暖\r\n" +
                "小强有两个大脑 孤单的时候会不会一起想着谁\r\n" +
                "我没有长长的脖子 却哽咽的说不出话\r\n" +
                "我没有三颗心脏 体会不到无法忍受的痛再多三倍\r\n" +
                "我假装咳嗽 假装被沙子迷了眼 你也没有看我一眼\r\n" +
                "是因为我太弱小 没有很可靠的肩膀么\r\n" +
                "无时无刻的清澈的想念 一定比两个大脑一起想你还多吧\r\n" +
                "蜉蝣只能活很短 可能一辈子都来不及和心里珍藏的那个人说一些想说的话\r\n" +
                "我又能活多久 时间会不会给我可以开口的勇气\r\n" +
                "把人生看做是自己独一无二的创作 便不会频频回首\r\n" +
                "你会不会忽然地出现 在旧时光的风景里 成为珍藏一生的美丽");
        osw.close();
    }
}
package cn.ylq.filestream;

import java.io.*;

public class Demo12 {
    public static void main(String[] args) throws Exception {
        FileInputStream fis = new FileInputStream ("F:\\文档\\杂七杂八\\字节码文件哦");
        InputStreamReader isr = new InputStreamReader(fis,"utf-8");
        int data = 0;
        while ((data = isr.read())!=-1){
            System.out.print((char) data);
        }
        isr.close();
    }
}

File类

  • 概念: 代表物理盘符中的一个文件或文件夹.
  • 方法:
  • createNewFile()
    创建一个新文件
  • mkdir()
    创建一个新目录
  • delete()
    删除文件或空目录
  • exists()
    判断File对象所代表的对象是否存在
  • getAbsolutePath()
    获取文件的绝对路径
  • getName()
    取得名字
  • getParent()
    获取文件目录所在的目录
  • isDirectory()
    是否是目录
  • isFile()
    是否是文件
  • length()
    获取文件的长度
  • listFiles()
    列出目录中的所有内容
  • rename()
    修改文件名为
package cn.ylq.filestream;

import java.io.File;

public class Demo14 {
    public static void main(String[] args) {
        separator();
    }

    public static void separator() {
        System.out.println("路径分隔符: [ " + File.pathSeparator + " ]");
        System.out.println("文件分隔符: [ " + File.separator + " ]");
    }

}

结果: (参考环境变量参数值理解)
路径分隔符: [ ; ] 路径1和路径2之间
文件分隔符: [ \ ] 路径1内各级目录之间

package cn.ylq.filestream;

import java.io.File;
import java.util.Date;

public class Demo14 {
    public static void main(String[] args) throws Exception {
        fileOperate();
    }


    public static void fileOperate() throws Exception {
        File f = new File("F:\\文档\\杂七杂八\\维京战机");
        //创建文件
        if(!f.exists()){
            boolean b1 = f.createNewFile();
            System.out.println("文件创建:"+b1);
        }
        //获取文件的绝对路径
        System.out.println("文件的绝对路径:"+f.getAbsolutePath());
        //获取文件的路径 (和创建时候写的一样)
        System.out.println("文件的路径:"+f.getPath());
        //获取文件名称
        System.out.println("文件的名称:"+f.getName());
        //获取父目录
        System.out.println("文件父目录:"+f.getParent());
        //获取文件的长度
        System.out.println("文件长度:"+f.length());
        System.out.println("文件最后的修改时间:"+new Date(f.lastModified()));
        //判断文件时候可写    注意可读和可执行在linux才可以用
        System.out.println("文件是否可写:"+f.canWrite());
        //判断是否是文件
        System.out.println("是否是文件:"+f.isFile());
        //判断是否隐藏
        System.out.println("是否隐藏:"+f.isHidden());

        //删除文件
        boolean b2 = f.delete();
        System.out.println("文件删除:"+b2);
        //另一种JVM删除, 记得删掉上面的删除代码
        f.deleteOnExit();
        Thread.sleep(5000);

    }
}
package cn.ylq.filestream;

import java.io.File;

public class Demo15 {
    public static void main(String[] args) throws InterruptedException {
        dicOperation();
    }

    public static void dicOperation() throws InterruptedException {
        File dir = new File("F:/我试试正斜杠\\我再试试反斜杠");
        //比起mkdir方法, mkdirs方法可以创建多级目录
        if (!dir.exists()) {
            dir.mkdirs();
        }
        //只会删除最后一目录, 只有空目录可以删除
        dir.delete();
        //用JVM删除
        dir.deleteOnExit();
        Thread.sleep(5000);
        //获取绝对路径 路径 名称 父目录 最后一次修改时间 啥的和 文件的一样
        //判断是否是文件夹 判断是否隐藏也一样
        //遍历文件夹  注意用list方法返回的是字符串数组,用listFiles返回的是File数组
        File dir2 = new File ("F:\\文档\\杂七杂八");
        String[] files = dir2.list();
        for(String file:files){
            System.out.println(file);
        }
    }
}

FileFileter接口

  • public interface FileFilter
  • boolean accept (File pathname)

-当调用File类中的ListFiles()方法时, 支持传入FileFilter接口接口实现类, 对获取文件进行过滤, 只有满足条件的文件才可出现在listFiles()的返回值中

package cn.ylq.filestream;

import java.io.File;
import java.io.FileFilter;

public class Demo16 {
    public static void main(String[] args) {
        File dir = new File ("F:\\文档\\杂七杂八");
        FileFilter filter = new FileFilter() {
            @Override
            public boolean accept(File pathname) {
                if (pathname.getName().endsWith(".txt")){
                    return true;
                }
                else {
                    return false;
                }
            }
        };
        File[] files = dir.listFiles(filter);
        for (File file:files){
            System.out.println(file);
        }
    }
}

递归调用遍历文件夹

package cn.ylq.filestream;

import java.io.File;

//递归调用遍历文件夹
public class Demo17 {
    public static void main(String[] args) {
        File f = new File("F:\\文档\\杂七杂八");
        printDir(f);
    }

    public static void printDir(File thisDir) {
        File[] files = thisDir.listFiles();
        if(files!=null&&files.length>0){
            for(File file:files){
                if(file.isFile()){
                    System.out.println(file.getAbsolutePath());
                }
                else{
                    printDir(file);
                }
            }
        }
    }
}

递归删除略

Propertises

  • Properties: 属性集合
  • 特点
  1. 存储属性名和属性值
  2. 属性名和属性值都是字符串类型
  3. 没有泛型
  4. 和流有关
posted @ 2021-03-05 16:34  菜鸟巫师illich  阅读(46)  评论(0编辑  收藏  举报