java IO流

什么是IO流?

I :input

O :output

通过io就可以完成硬盘文件的读写。

IO 流的分类?

  • 一种方式是按照流的方向进行分类。

    以内存作为参照物,

    ​ 往内存中去,叫做输入(input),或者叫做读(Read)。

    ​ 从内存中出来,叫做输出(Output),或者叫做写(Write)。

  • 另一种方式是按照读取数据的方式不同进行分类。

    ​ (1)按照字节读取数据

    ​ 一次性读取一个字节 byte ,等同于一次性读取8个二进制。这种流是万能的,什么类型的文件都能读 取,包括:文本文件、图片、声音文件、视屏。

    举例; 文件 filel.txt,采取字节流的方式读取。

    ​ a我爱bc中d国

    ​ 第一次读:一个字节,到‘ a’

    ​ 第二次读:一个字节,正好读到 ‘我’ 字符的一半

    ​ 第三次读:一个字节,正好读到 ‘我’ 字符的另一半

    ​ (2)按照字符读取数据

    ​ 一次读取一个字符,这种流是为了读取普通文本文件而存在的,不能读取图片、视频、音乐等文件。只能读取纯文本文件,连word都不行。

​ 举例; 文件 filel.txt,采取字节流的方式读取。

​ a我爱bc中d国

​ 第一次读:’ a’ 字符

​ 第二次读:'我’字符。

综上所述,流的分类;

​ 输入流、输出流

​ 字节流、字符流

java中的流都已经写好了,java所有的流都在 java.io.* ;下

java IO 流四大家族

java.io.InputStream ; 字节输入流

java.io.OutputStream ; 字节输出流

java.io.Reader ; 字符输入流

java.io.Writer ; 字符输出流

都是抽象类 。

所有的都实现了java.io.Closeable接口,都有close()方法,都是可关闭的,流相当于内存和硬盘之间的管道用完后要及时关闭,否则会占用很多资源。

所有的输出流都实现了java.io.Flushable接口,都是可刷新的,都有flush()方法表示将通道当中剩余未输出的数据强行输出完(清空管道),输出流在最终输出之后一定要记得刷新一下清空管道。(如果没有flush()可能会导致丢失数据)

注意:在 java 中只要类名stream结尾的都是字节流;以 Reader/Writer 结尾的都是字符流。

java.io.* 中需要掌握的流

  • 文件专属

    java.io.FileInputStream(掌握)

    java.io.FileOutputStream(掌握)

    java.io.FileReader

    java.io.FileWriter

  • 转换流(将字节流转换为字符流)

​ java.io.InputStreamReader

​ java.io.OutputStreamWriter

  • 数据流专属

    java.io.DataInputStream

    java.io.DataOutputStream

  • 标准输出流

    java.io.PrintStream

    java.io.PrintWriter(掌握)

  • 对象专属流

    java.io.ObjectInputStream(掌握)

    java.io.ObjectOutputStream(掌握)

字节流读取文件

(一个一个的读)

代码演示:

/*
java.io.FileInputStream
文件字节输入流,万能的。任何类型的文件都可以用这个读。
 */
public static void main(String[] args) {
        FileInputStream q1 = null;
        try {
             q1 = new FileInputStream("test.txt");  //存储内容是; a
             int readDate = q1.read();
             System.out.println(readDate);//97 ,输出为ascii值

        } catch (FileNotFoundException e) {  
          //  FileNotFoundException 是 IOException 的子类。所以只写catch IOException 也可以。
            e.printStackTrace();
        }
        catch (IOException e) {
            e.printStackTrace();
        } finally {
            //关闭流。前提是 流不为空。当流是null,没有必要关闭,也是避免空指针异常。
            if (q1 != null) {
                try {
                    q1.close();
                } catch (IOException e) {
                    e.printStackTrace();}}}}}
  • 使用数组读

    public static void main(String[] args) {
            FileInputStream fls = null;
            try {
                //idea 默认都当前路径在哪里? (默认读文件的文件位置)
                fls = new FileInputStream("test.txt");   //文件内容;abcdef
                //采用byte读取字节,一次读取多个字节,最多读取 "数组.length" 个字符
                byte [] bytes = new byte[4]; //准别一个 4 长度的a数组,一次最多读取4字符
    
                int readTxt = fls.read(bytes);   //这个方法返回的是 读取的字节数量。
                System.out.println(readTxt);  //第一次读到了四个字节,输出4
                //System.out.println(new String(bytes));  //abcd   。别忘了引用包,java.lang.String;
                System.out.println(new String(bytes,0,readTxt));  //(idea此时不能自动引包).
                //表示从数组bytes的第0个下标开始,读取长度为readTxt的字节数组
                readTxt = fls.read(bytes);   //第二次只能读取两个字节,输出2, 后两个字节覆盖前两个数组。
                System.out.println(readTxt);
                //System.out.println(new String(bytes));  //efcd
    
                System.out.println(new String(bytes,0,readTxt));
                //readTxt = fls.read();   //第三次一个字节都没有读到,返回-1。 因为后面没有数据了。
             } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (fls != null){
                    try {
                        fls.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    } }}}}
    

此时可以按照设定好的byte数组长度进行读取文件, 一次读取四个字节。

  • 如何读取文件中所有的字符?

     public static void main(String[] args) {
            FileInputStream fls = null;
            try {
                fls = new FileInputStream("/Users/caoxingxing/Desktop/test.txt");
                /*byte [] bytes = new byte[4];
                while (true){
                    int readCount = fls.read(bytes);
                    if (readCount == -1){
                        break;
                    }
                    System.out.print(new String(bytes,0,readCount));    //如果连续输出字符,去ln。
                }*/
                byte [] bytes = new byte[4];
                int readCount = 0;
                while ((readCount = fls.read(bytes)) != -1){  //改进后的while循环。
                    System.out.print(new String(bytes,0,readCount));  //一次读取4个字节,读取长度为readCount的数组
                }
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (fls != null){
                    try {
                        fls.close();
                    } catch (IOException e) {
                        e.printStackTrace();
    }}} }}
    
  • available ();方法

    int read = fis.read();
    System.out.println("剩余" + fis.available() + "字节");  //剩余多少字节
    
    byte [] bytes = new byte[fis.available()];  //数组长度为字符床总长度
    int read = fis.read(bytes);
    System.out.println(new String(bytes));    //不适用太大的文件,因为byte 有一定限制。
    

获取数组长度的字节。=获取全部字节并输出。

  • skip(); 跳过读取。

    //skip跳过几个字节不读取。
        public static void main(String[] args) {
            FileInputStream fls = null;
            try {
                fls = new FileInputStream("test.txt");  //文件内容:abcd
                fls.skip(2);
                System.out.println(fls.read());  //输出:cd
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }finally {
                if (fls != null){
                    try {
                        fls.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }}}}}
    
  • 使用FileOutputStream写入文件

//文件字节输出流,负责写
    //从内存到硬盘

    public static void main(String[] args) {
        FileOutputStream fos = null;
        try {
            //以追加的方式在文件末尾写入,不会晴空源文件内容。文件末尾加true
            fos = new FileOutputStream("myfile",true); //文件不存在时会自动重建,
            //  后加“true”,每次写入后,不格式化文件。
            //不加的话,每次写入文件后会清空文件 重新写入。
            //例如;不加true,每一次程序运行,文件都是显示:123。
            //加true后,程序运行两次,文件:123123
           
            //开始写
            //byte [] bytes = {97,98,99,100};
            //fos.write(bytes);  //abcd
            //fos.write(bytes,0,2);  //在写出ab,输出:abcdab

            //写完之后记得刷新一下,不然看不到新写的信息、
            fos.flush();

            String s = "123";
            byte [] bytes2 = s.getBytes();
            fos.write(bytes2);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fos != null){
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        //打印添加 "s" 后的文件
        FileInputStream fls = null;
        try {
            fls = new FileInputStream("myfile");
            byte [] bytess = new byte[fls.available()];
            int read = fls.read(bytess);
            System.out.println(new String(bytess));  
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fls != null){
                try {
                    fls.close();
                } catch (IOException e) {
                    e.printStackTrace();
                } } } }}
  • 使用FileOutputStream 和 FileInputStream 拷贝文件
public static void main(String[] args) {
        FileInputStream fls = null;
        FileOutputStream fos = null;

        //使用字节流可以拷贝 文本、视频、音频等。(目前只会拷贝单个文件,文件夹还不行)
        try {
            fls = new FileInputStream("我自己的io作业01");
            fos = new FileOutputStream("/Users/caoxingxing/Desktop/test.txt",true);  
            //若不加true,每一次拷贝文件都会覆盖原文件内容。
          
            byte [] bytes = new byte[4];  //一次四个字节
            int readCount = 0;
            while ((readCount = fls.read(bytes)) != -1){
                fos.write(bytes,0,readCount);
            }
            //写入文件记得刷新。
            fos.flush();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
          //连个close要分开处理异常(try、catch)。  不然可能会影响另一个流的关闭。
            if (fos != null){
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
            if (fls != null){
                try {
                    fls.close();    
                } catch (IOException e) {
                    e.printStackTrace();
                } }} }

FileReader

public static void main(String[] args) {
        FileReader reader = null;
        try {
            reader = new FileReader("我自己的io作业01");
            /*char [] chars = new char[4];
            int readCount = 0;
            while ((readCount = reader.read(chars)) != -1){
                System.out.println(new String(chars,0,readCount));
            }*/

            //按字符的方式读取
            char [] chars = new char[4]; //一次读取四个字节,也可以增加。例如:1024*512。
            reader.read(chars);
            for (char c : chars){  //遍历 chars,保存到c中。
                System.out.println(c);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (reader != null){
                try {
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
} }} }}

FileWriter文件字符输出流

//文件字符输出流,负责写的
//只能输出普通文本。world文件不是普通文本。
public class FileWriterrr01 {
    public static void main(String[] args) {
        FileWriter fw = null;
        try {
            fw = new FileWriter("我自己的io作业01",true);   //append :追加。
            char [] chars = {'豆','雷','楼','姆','˜'};
            fw.write(chars); //文件增加chars的内容。
            fw.write(chars,2,3); //写入数组下标为2-3的数据。
            fw.write("🐒好猴");   //可写入String 类型。!!!!!!!所以FileWriter非常好用。
          //一个emoji两个字符位。
            fw.write("\n");  //写入的文件换行
            fw.write("helloWorld");
            fw.flush(); //写入文件一定记得刷新。
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if (fw != null){
                try {
                    fw.close();
                } catch (IOException e) {
                    e.printStackTrace();
  }} } }}

使用FileWriter和FileReader复制文件

    public static void main(String[] args) {
        FileWriter out = null;
        FileReader in = null;
        try {
            in = new FileReader("/Users/caoxingxing/Desktop/demo/idea的所有java/src/IOo/copy02.java");
            out = new FileWriter("我自己的io作业01",true);  //加true,写入文件后格式化文件。

            char [] chars = new char[1024 * 512]; // 1mb
            int readCount = 0;
            while ((readCount = in.read(chars)) != -1){
                out.write(chars,0,readCount);
               System.out.print(new String(chars,0,readCount));  //打印更改后的文件
            }
            out.flush();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (in != null){
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (out != null) {     //此处两个try、catch。
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }}} }}
  • 只可以对普通文本读写,例如,txt、java等。

BufferedReader字符输入流

/*
BufferedReader是带有缓冲区的字符输入流。
使用这个流不需要自定义char数组,或者不用定义byte数组,自带缓冲。
 */
public class BufferReader01 {
    public static void main(String[] args) throws Exception{
        FileReader reader = new FileReader("我自己的io作业01");
        //当一个流的构造方法中需要一个流的时候,这个被传进来的流叫做,节点流
        //外部负责包装这个流,叫做,包装流,也有另一个名子,叫处理流
        //对于这个程序,FileReader是一个节点流,BufferedReader是一个包装流/处理流。
        BufferedReader br = new BufferedReader(reader);

        /*  //读一行
        String firstLine = br.readLine();   
        System.out.println(firstLine);
        
        //读取文件第二行。
        String secondLine = br.readLine();
        System.out.println(secondLine);*/

        String s = null;
        while ((s = br.readLine()) != null){
            System.out.println(s);    //读取全部文件。
        }
        //关闭流
        //对于包装流来数,只需要关闭最外层流即可,里面的节点流会自动关闭。
        br.close();
    }
}

转换流(将字节转换为字符)

InputStreamReader

/*
字节流转换为字符流。
 */
public static void main(String[] args) throws Exception{  //此处将异常统一处理,不需要try、catch。
    //完整写法
    //创建字节流
    FileInputStream q1 = new FileInputStream("我自己的io作业01");

    //字符流转换,InputStreamReader将字节流转换为字符流。
    InputStreamReader q2 = new InputStreamReader(q1);  //q1是节点流,q2是包装流。
    //这个构造方法只能传一个字符流,不能传字节流
    BufferedReader q3 = new BufferedReader(q2);  //q2是节点流,q3是包装流。

    //简便写法
    //BufferedReader q = new BufferedReader(new InputStreamReader(new FileInputStream("我自己的io作业01")));
    String s = null;
    while ((s = q3.readLine()) != null) {
        System.out.println(s);
    }}}

“读” 的转换流

OutputStreamWriter

/*
BufferedWriter:带有缓冲的字符输出流
OutputStreamWriter:转换流
 */
public class BufferWriter01 {
    public static void main(String[] args) throws Exception{
        //BufferedWriter q1 = new BufferedWriter(new FileWriter("myfile"));   //字符流
        //
        BufferedWriter q1 = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("myfile")));
        q1.write("fffff");
        q1.write("啵啵鸡2");

        q1.flush();
        q1.close();
    }}

”写“ 的转换流。

数据流DataInputStream & DataOutputStream

  • DataOutputStream文件
/*
java.io.DataOutputStream:数据专属的流
这个流可以将数据连同数据的类型一起写入文件
这个文件不是普通文本文档
 */
public class DataOutputStreamTest01 {
    public static void main(String[] args) throws Exception{
        //创建数据专属的字节输出流
        DataOutputStream dos = new DataOutputStream(new FileOutputStream("myfile2"));

        byte a = 100;
        short b = 200;
        int c = 300;
        long d = 400L;
        float e = 3.0F;
        double f = 3.14;
        boolean sex = false;
        char g = 'a';

        dos.writeByte(a);  //数据及数据类型一并写进去。
        dos.writeShort(b);
        dos.writeInt(c);
        dos.writeLong(d);
        dos.writeFloat(e);
        dos.writeDouble(f);
        dos.writeBoolean(sex);
        dos.writeChar(g);
      
        dos.flush();
        dos.close();

    }
}
  • DataInputStream文件

    /*
    java.io.DataOutputStream:数据专属的流
    这个流可以将数据连同数据的类型一起写入文件
    这个文件不是普通文本文档.(可以理解为打不开、看不了)
     */
    public class DataOutputStreamTest01 {
        public static void main(String[] args) throws Exception{
            //创建数据专属的字节输出流
            DataOutputStream dos = new DataOutputStream(new FileOutputStream("myfile2"));
            byte a = 100;
            short b = 200;
            int c = 300;
            long d = 400L;
            float e = 3.0F;
            double f = 3.14;
            boolean sex = false;
            char g = 'a';
    
            dos.writeByte(a);  //数据及数据类型一并写进去。
            dos.writeShort(b);
            dos.writeInt(c);
            dos.writeLong(d);
            dos.writeFloat(e);
            dos.writeDouble(f);
            dos.writeBoolean(sex);
            dos.writeChar(g);
    
            dos.flush();
            dos.close();
      }}
    //输出:
    100
    200
    1300
    400
    3.0
    3.14
    false
    a
    

PrintStream标准输出流

public class PrintStreamTest01 {
    public static void main(String[] args) throws Exception{
        //输出到控制台。标准输出流不需要手动 close()关闭。
        //联合起来写
        System.out.println("hahahah");
        //分开写
        PrintStream ps = System.out;
        ps.println("ha");
        ps.println("ha");

        //改变输出方向
        //输出流不再控制台输出,输出到文件"myfile"
        PrintStream psw = new PrintStream(new FileOutputStream(" myfile3"));
        //修改文件输出方向,到 文件" myfile"。
        System.setOut(psw);
        System.out.println("dddd");
    }
}
  • 记录日志的方法
public class Logger {
    public static void log(String msg) {

        try {
            //指向一个日志文件
            PrintStream ps = new PrintStream(new FileOutputStream("/Users/caoxingxing/Desktop/demo/idea的所有java/myfile4",true));
            //改变输出方向
            System.setOut(ps);
            //日期当前时间
            Date nowTime = new Date();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");
            String strTime = sdf.format(nowTime);
            System.out.println(strTime + " :" + msg);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }

    }

    public static void main(String[] args) {
        Logger.log("dddd");
        Logger.log("avav");
        Logger.log("dddd");
        Logger.log("avav");
        Logger.log("dddd");
        Logger.log("avav");
        Logger.log("dddd");
        Logger.log("avav");
    }
}

File类

File是文件和目录路径名的抽象表示形式。包含许多方法。

    public static void main(String[] args) throws Exception{
        File file = new File("/Users/caoxingxing/Desktop/test.txt");
        //.getName() .获取文件名
        System.out.println(file.getName());

        //.isDirectory()  .判断是否是一个目录
        System.out.println(file.isDirectory());

        //.isFile()  .判断是否是一个文件
        System.out.println(file.isFile());

        //.lastModified()  .获取最后一次修改时间
        long time = file.lastModified(); //这个毫秒是从1970年到现在到总毫秒数
        //将毫秒数转换成日期
        Date time2 = new Date(time);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-mm-dd HH:mm:ss SSS");
        String time3 = sdf.format(time2);
        System.out.println("最后一次更改时间:" + time3);

        //获取文件大小
        System.out.println(file.length());  //字节
    }
}
//输出:
test.txt
false
true
最后一次更改时间:2020-27-07 22:27:31 249
45

.exists() 判断文件是否存在

public static void main(String[] args) {
    File file = new File("/Users/caoxingxing/Desktop/test.txt");
    System.out.println(file.exists());
}
//若当前文件存在,则返回true。若不存在返回false。

.getParent() 获取文件父类路径

public static void main(String[] args) throws Exception{
    File file = new File("/Users/caoxingxing/Desktop/test.txt");
    System.out.println(file.getParent());  //输出文件父路径:/Users/caoxingxing/Desktop
}

.getAbsolutePath() 获取绝对路径(完整路径)

public static void main(String[] args) throws Exception{
File file1 = file.getAbsoluteFile();
System.out.println(file1.getAbsolutePath());  //获取绝对路径,/Users/caoxingxing/Desktop/test04
}

.mkdirs()

创建此抽象路径名指定的目录。

//如果不存在,则已文件夹的形式创建
if (!file.exists()){
    file.mkdirs();   
}

.mkdir()

创建此抽象路径名指定的目录,包括所有必需但不存在的父目录。

//如果不存在,则已文件夹的形式创建
if (!file.exists()){
    file.mkdir();   
}

区别取决于

 File file = new File("/Users/caoxingxing/Desktop/test.txt");

若路径下没有此文件,则创建“test.txt”文件夹,若包含多重目录,例如test.txt后又有文件名,则需要用.mkdirs。

既然不清楚要创建的是单个文件目录还是多重目录,直接用.mkdirs较合适。

.createNewFile();

//如果不存在,则已文件的形式创建
if (!file.exists()){
        file.createNewFile();
 }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值