java --- IO流

目录

1.File类

1.1  File的构造方法

1.2  File的常用方法

1.3   文件夹的常用方法

附加: 遍历文件夹目录

方法一

方法二(这个更加简便)

2. 输入与输出概念

3. 字节流与字符流

3. 1  IO流的常用方法

3.2 文件的复制

第一种

第二种

3.3 字节流和字符流两种读写速度的比较

4. 节点流和处理流

4.1 文件夹的合并和分割(1MB大小)

5. 输入输出字符流

6. Print流(打印流)

7. 对象输入输出流

7.1 对象输出

7.2 对象输入

7.3 自定义对象进行序列化


1.File类

文件和目录路径名的抽象表示

一个File类的对象,表示计算机硬盘上的一个文件和目录

1.1  File的构造方法

  • File f = new File("E:/test.txt");
  • File f1 = new File("E:","学习哦");
  • File pf = new File("E:");
  • File cf = new File(pf,"学习哦");

1.2  File的常用方法

import java.io.IOException;

public class FileDemo1 {
    public static void main(String[] args) {
//        一个File类的对象
        File f = new File("E:/test.txt");
//        File类的常用方法:
        System.out.println(f.canRead());//读 true
        System.out.println(f.canWrite());//写 true
        System.out.println(f.getPath());//绝对路径 E:\test.txt
        System.out.println(f.getName());//文件名 test.txt
        System.out.println(f.getParent());//父级 E:\
        System.out.println(f.length());//长度(以字节为单位) 79
        System.out.println(f.isFile());//文件是否存在 true
        System.out.println(f.isDirectory());//是否为目录 false
        System.out.println(f.isAbsolute());//是否为绝对路径 true
        System.out.println(f.isHidden());//是否为隐藏 false
        System.out.println(f.exists());//是否存在 true
        System.out.println(f.lastModified());//最后一次修改时间 1639734309196
        try {
            System.out.println(f.createNewFile());//创建新的文件 false
        } catch (IOException e) {
            e.printStackTrace();
        }
        //删除文件
        f.delete();
     
    }
}

1.3   文件夹的常用方法

  •         f.mkdir();//创建文件夹(单级)
  •         f.mkdirs();//创建多级文件夹
  •         f.delete();//删除多级文件夹时,一次只能删除一级目录且目录为空

附加: 遍历文件夹目录

方法一

import java.io.File;
public class FilePractice {

   public static void Directory(File f){
        String[] fs = f.list();
        for (String fileName : fs) {
            System.out.print(fileName + ",");
        }
    }
    public static void show(File f){
        File[] fs = f.listFiles();
        for (File fileName : fs) {
            if(fileName.isDirectory()){
                Directory(fileName);
                System.out.println();
            }else{
                System.out.println(fileName);
            }
        }
    }

    public static void main(String[] args) {
        File f = new File("E:\\学习哦");
         show(f);

    }

}

方法二(这个更加简便)

import java.io.File;
public class FilePractice {
   public static void getAllFile(File f) {
       System.out.println(f);
       File[] fi = f.listFiles();
       for (File fs : fi) {
           if (fs.isDirectory()) {
               getAllFile(fs);
           } else {
               System.out.println(fs);
           }
       }
   }
    public static void main(String[] args) {
        File f = new File("E:\\学习哦");
        getAllFile(f);

    }

}

2. 输入与输出概念

I ——> input  输入  把电脑硬盘上的文件(数据)读入到程序中(进行读操作)

O ——> output 输出 把程序中的数据写到目标地址中(进行写操作)

例图:

3. 字节流与字符流

字节流:每次读取数据时是以字节为单位读写

字节输入流:InputStream的子类 (例:FileInputStream

字节输出流:OutputStream的子类(例:FileOutputStream

字符流:每次以字符为单位进行读写操作

字符入流 Reader的子类(例:FileReader

字符出流 Writer的子类(例:FileWrite

3. 1  IO流的常用方法

InputStream的基本方法

创建字节输入流对象,接入到指定的文件上,如果找不到文件,抛出异常throws FileNotFoundException

FileInputStream in = new FileInputStream("D:/test.txt") ;

读取一个字节并以整数的形式返回(0~255), 如果返回-1已到输入流 的末尾。

int read() throws IOException

读取一系列字节并存储到一个数组buffer, 返回实际读取的字节数,如果读取前已到输入流的末尾返回-1

int read(byte[] buffer) throws IOException

关闭流释放内存资源

void close() throws IOException

OutputStream的基本方法

 创建一个字节输出流对象,同时创建一个空文件,如果路径不对,抛出异常throws FileNotFoundException

 FileOutputStream out = new FileOutputStream("E:/test.txt");

向输出流中写入一个字节数据,该字节数据为参数b的低8位

void write(int b) throws IOException

将一个字节类型的数组中的从指定位置(off)开始的 len个字节写入到输出流

void write(byte[] b, int off, int len) throws IOException

关闭流释放内存资源   void close() throws IOExceptio

3.2 文件的复制


import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class Demo {
    public static void main(String[] args) {
//        把D盘中的“test.txt”文件内容(abcdefg)复制到 E盘中的“test.txt”文件
        FileInputStream in = null;
        FileOutputStream out = null;
        try {
            //创建字节输入流对象,接入到指定的文件上,如果找不到文件,抛出异常
//            FileInputStream in = new FileInputStream("D:/test.txt");
            in = in = new FileInputStream("D:/test.txt");
//            创建一个字节输出流对象,同时创建一个空文件,如果路径不对,会报异常
//            FileOutputStream out = new FileOutputStream("E:/test.txt");
            out = new FileOutputStream("E:/test.txt");
            int a = 0;
//          in.read() 返回为int类型,如果文件读完后返回 -1
            while ((a = in.read() )!= -1){
                out.write(a);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            System.out.println("系统找不到指定文件夹");
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("读或写出现异常");
        }finally {
//            在此处不能直接在异常中调用文件输入/输出字节流,
//             所以我们在开始创建文件输入/输出字节流
//           关闭文件输入/输出字节流
            try {
                if(in != null) {
                    in.close();
                }
                if(out != null){
                    out.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

第一种

以字节为单位对字符进行输入输出,有多少字节就进行多少次输入输出

int a = 0;

while ((a = in.read() )!= -1){

     out.write(a);

}

第二种

使用容器来对字符进行输入输出
byte[] bytes = new byte[10];

int size = 0;    //表示实际长度

while((size = in.read(bytes)) != -1){

         System.out.println(size); //数组每次最大可以装 bytes.length 个

        out.write(bytes, 0, size);   //一般从 0 开始从数组的指定位置开始,写出实际装入的个数

}


import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class Demo2 {
    public static void main(String[] args) throws IOException {
            FileInputStream in = new FileInputStream("D:/test.txt");
            FileOutputStream out = new FileOutputStream("E:/test.txt");
           //  in.read() 返回为int类型,如果文件读完后返回 -1
            // 第一种 以字节为单位对字符进行输入输出,有多少字节就进行多少次输入输出
            /*int a = 0;
            while ((a = in.read() )!= -1){
                out.write(a);
            }*/
            //第二种
//             int c = in.read(b);//返回的也是int值,表示实际向数组中装入字节的个数
            //使用容器来对字符进行输入输出
            byte[] bytes = new byte[10];
            int size = 0;//表示实际长度
            while((size = in.read(bytes)) != -1){
                System.out.println(size);//数组每次最大可以装 bytes.length 个
                //一般从 0 开始从数组的指定位置开始,写出实际装入的个数
                out.write(bytes, 0, size);
            }
            in.close();
            out.close();
    }
}

3.3 字节流和字符流两种读写速度的比较

public class FilePractice1 {
    public static void main(String[] args) throws IOException {
        FileInputStream in1 = null;
        FileOutputStream out1 = null;
        in1 = new FileInputStream("E:/feige.exe");
        out1 = new FileOutputStream("E:/学习哦/feige.exe");
        long s1 = System.currentTimeMillis();
        int a = 0;
        while((a = in1.read()) != -1){
            out1.write(a);
        }
        long e1 = System.currentTimeMillis();
        System.out.println("第一种读写:" + (e1 - s1)); //第一种读写:21486
            if(in1 != null)
                in1.close();
            if(out1 != null)
                out1.close();

        FileInputStream in2 = null;
        FileOutputStream out2 = null;
        in2 = new FileInputStream("E:/feige.exe");
        out2 = new FileOutputStream("E:/学习哦/feige.exe");
        long s2 = System.currentTimeMillis();
        byte[] bytes = new byte[100];
        int size = 0;
        while((size = in2.read(bytes)) != -1){
            out2.write(bytes,0,size);
        }
        long e2 = System.currentTimeMillis();
        System.out.println("第二种读写:" + (e2 - s2)); //第二种读写:305
        if(in2 != null)
            in2.close();
        if(out2 != null)
            out2.close();

    }
}

4. 节点流和处理流

节点流 

流对象中直接包含的就是数据,并对数据进行操作(如文件、字符串、字符串数组等)

例:FileInputStream in = new FileInputStream("D:/test.txt");

       FileOutputStream out = new FileOutputStream("E:/test.txt");

处理流

处理流中包含的是其他的流的对象(节点) 可以缓冲区功能

 bout.flush();//刷新缓冲区

import java.io.*;
public class Demo3 {
    public static void main(String[] args) throws IOException {
        //节点流:直接包含数据,对数据进行操作
        FileInputStream in = new FileInputStream("D:/test.txt");
        FileOutputStream out = new FileOutputStream("E:/test.txt");
        //创建处理流(包装流)
        /*
        底层有一个缓冲数组,每次读到的数据线存入到缓冲数组中,等缓冲数组满后再实际操作,
        一旦自己定义的数组长度大于缓冲区数组大小,缓冲区是数据就失效了
         */
        BufferedInputStream bin = new BufferedInputStream(in);
        BufferedOutputStream bout = new BufferedOutputStream(out);
        byte[] bytes = new byte[1024];
        int size = 0;
        while((size = bin.read(bytes)) != -1){
            bout.write(bytes, 0, size);
        }
        bin.close();
        bout.flush();//刷新缓冲区
        bout.close();
    }
}

4.1 文件夹的合并和分割(1MB大小)

分割

public static void Splits(File f) throws IOException {
        int m = 1024*1024;
        long num = 0;
        if((f.length()% m ) == 0 ){
             num = f.length() / m;
        }else{
            num = (f.length() / m) + 1;
        }
        System.out.println(num);
        int count = 0;
        FileInputStream  in = new FileInputStream(f);
        for (int i = 0; i < f.length(); i++) {
            FileOutputStream out = new FileOutputStream("E:/temp/temp"+ i );
            byte[] bytes = new byte[1024];
            int size = 0;
            while((size = in.read(bytes)) != -1){
                out.write(bytes, 0, size);
                count += size;
            }
            if(count == num){
                out.close();
                count = 0;
                break;
            }
        }
        in.close();
    }

合并

 public static void Join(File temp) throws IOException {
        FileOutputStream out = new FileOutputStream("E:/feige.exe");
        File fl = new File(String.valueOf(temp));
        File[] fs = fl.listFiles();
        for (int i = 0; i < fs.length; i++) {
            FileInputStream in = new FileInputStream("E:/temp/temp"+ i );
            byte[] bytes = new byte[1024];
            int size = 0;
            while((size = in.read(bytes)) != -1){
                out.write(bytes, 0, size);

            }
            in.close();
        }
        out.close();
        for (File f: fs
             ) {
            f.delete();
        }
        fl.delete();
    }

主线程

public static void main(String[] args) throws IOException {
        File f = new File("E:/feige.exe");
        Splits(f);
        Join(f);
    }

5. 输入输出字符流

每次读取单位为字符,字符流只能读取文本文件(.txt,.java,.html)

计算机上的文件存储都是字节,字符流每次之所以能读到一个字符,通过转换流,将读到的字节结合指定的字符编码转为字符

例:

Reader ---> InputStreamReader(转换流) ---> FileReader

Writer ---> InputStreamWriter(转换流) ---> FileWriter

方法一:每次可以读有个字符,进行输入输出字符

 read() 每次直接可以读到一个字符的编码,一个中文由三个字节组成。

import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class Demo1 {
    public static void main(String[] args) throws IOException {

        FileReader reader = new FileReader("D:/test.txt");
        FileWriter writer = new FileWriter("E:/test.txt");
       int c = reader.read();
      // read() 每次直接可以读到一个字符的编码,一个中文由三个字节组成
   
        while((c = reader.read())!= -1){
            writer.write(c);
        }
      
        reader.close();
        writer.close();
    }
}

方法二:使用容器进行输入输出字符流(使用Char数组

import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class Demo {
    public static void main(String[] args) throws IOException {

        FileReader reader = new FileReader("D:/test.txt");
        FileWriter writer = new FileWriter("E:/test.txt");
        char[] chars = new char[100];
        int size = 0;
        while((size = reader.read(chars))!= -1){
            writer.write(chars,0,size);
        }
        reader.close();
        writer.close();
    }
}

方法三:使用缓冲字符输入输出流 

import java.io.*;

public class Demo2 {
    public static void main(String[] args) throws IOException {
        FileReader reader = new FileReader("D:/test.txt");
        FileWriter writer = new FileWriter("E:/test.txt",true);
        BufferedReader breader = new BufferedReader(reader);
        BufferedWriter bwrite = new BufferedWriter(writer);
        String s = null;
//      readLine() 每次读一行数据,读完返回 null
        while((s=breader.readLine())!= null){
            bwrite.write(s);
            bwrite.newLine();//换行
         }
        breader.close();
        bwrite.close();
    }
}

6. Print流(打印流)

定义:只做输出,不做输入。(单向的从程序中向外输出)

底层都是使用write();


import java.io.FileNotFoundException;
import java.io.PrintWriter;

public class PrintDemo {
    public static void main(String[] args) throws FileNotFoundException {
        PrintWriter pw = new PrintWriter("D:/test.txt");
        pw.print("abc"); //输出字符串
        pw.println("cad"); //换行输出
        pw.write("def"); //打印字符串
    }
}

7. 对象输入输出流

定义:对象的输入输出流,将对象信息写入文件中,做到持久保存(序列化)

对象:程序运行时,创建的对象

7.1 对象输出

对象序列化:将程序运行时,创建的对象输出到指定的文件中,持久保存

public class Demo3 {
    public static void main(String[] args) throws IOException {
        Date date = new Date();
        String s = "abcd";
        FileOutputStream fout = new FileOutputStream("E:/test.txt");
        ObjectOutputStream out = new ObjectOutputStream(fout);
        out.writeObject(date);
        out.writeObject(s); //对象序列化
        out.close();
    }
}

7.2 对象输入

import java.io.*;
import java.util.Date;

public class Demo3 {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
   
        FileInputStream in = new FileInputStream("E:/test.txt");
        ObjectInputStream oin = new ObjectInputStream(in);
        Date date = (Date) oin.readObject();
        String s = (String)oin.readObject();
        System.out.println(date);//Sat Dec 18 18:58:43 CST 2021
        System.out.println(s);//abcd
        oin.close();
    }
}

7.3 自定义对象进行序列化

实现 Serializable 为类生成一个编号(唯一的)

private static final long serialVersionUID = 1712358556364516246L;  

如果不显示的声明此编号,运行时会默认生成一个,如果类一旦发生变化,编号也会改变

自定义:User类 

import java.io.Serializable;

public class User implements Serializable {
    /*
    实现 Serializable
    为类生成一个编号(唯一的)
    private static final long serialVersionUID = 1712358556364516246L;
    如果不显示的声明此编号,运行时会默认生成一个,如果类一旦发生变化,编号也会改变
     */
    private static final long serialVersionUID = 1712358556364516246L;
    private int id;
    private String name;

    public int getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public User(int id, String name) {

        this.id = id;
        this.name = name;
    }

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

对象输出

import java.io.*;

public class ObjectOutputDeno {

    public static void main(String[] args) throws IOException, ClassNotFoundException {
       User user = new User(1001, "小段");
        FileOutputStream fout = new FileOutputStream("E:/test.txt");
        ObjectOutputStream out = new ObjectOutputStream(fout);
        out.writeObject(user);
        out.close();
    }
}

对象输入

import java.io.*;

public class ObjectOutputDeno {

    public static void main(String[] args) throws IOException, ClassNotFoundException {
        FileInputStream in = new FileInputStream("E:/test.txt");
        ObjectInputStream oin = new ObjectInputStream(in);
        User user = (User) oin.readObject();
        System.out.println(user);
        oin.close();
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值