【JAVA】IO流

今天学习IO流的相关知识。 

  1. File
  2. 输入及输出的概念
  3. 输入流与输出流
  4. 输入输出节点字节流
  5. 节点流与处理流
  6. 输入输出节点字符流
  7. Print
  8. 对象输入输出流
  9. Serializable序列化接口

File 

File类 在程序中抽象的表示计算机中的文件或目录。 一个File类对象可以表示文件和路径, 可以对文件的属性进行操作,但不能直接对文件进行读写操作。

路径有两种:

绝对路径,完整的路径 D:\File.txt

相对路径,不是全路径,是两个文件的相对同一个父级的路径 File.txt

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

public class Demo1 {
    /*
    File类
    在程序中抽象的表示计算机中的文件或目录。
    一个File类对象可以表示文件和路径,
    可以对文件的属性进行操作,但不能直接对文件进行读写操作

    路径有两种:
    绝对路径,完整的路径   D:\File.txt
    相对路径,不是全路径,是两个文件的相对同一个父级的路径    File.txt
     */
    public static void main(String[] args) {
        File f1=new File("D:\\File.txt");//File类的构造方法

        String s="D:\\";
        new File(s,"File1.txt");
        new File(s,"File2.txt");
        new File(s,"File3.txt");

        File f2=new File("D:\\Files");
        if (!f2.exists()) {
            f2.mkdir();//创建一级目录(文件夹)
        }
        f2.delete();//删除目录时,目录要为空
        File f3=new File("D:\\File1\\File2\\File3");
        if (!f3.exists()) {
            f3.mkdirs();//创建多级目录
        }
        f3.delete();
        if (!f1.exists()){//判断文件是否存在
            try {
                f1.createNewFile();//新建一个文件
            } catch (IOException e) {
                e.printStackTrace();
                System.out.println("路径不正确");
            }
        }
        System.out.println(f1.canRead());//判断文件是否可读
        System.out.println(f1.canWrite());//判断文件是否可写
        System.out.println(f1.getAbsoluteFile());//获取文件的绝对地址
        System.out.println(f1.getParent());//返回路径名的父
        System.out.println(f1.length());//获取文件的长度(字节数,以字节为单位)
        System.out.println(new Date(f1.lastModified()));//获取文件的最后修改时间
        System.out.println(f1.delete());//删除文件
        System.out.println(f1.isFile());//判断是否为路径
        System.out.println(f1.isDirectory());//判断是否为目录
    }
}

对目录遍历,获得所有子目录和文件

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

public class Demo3 {
    /*
        对目录遍历,获得所有子目录和文件
     */
    public static void main(String[] args) {
        //对目录里的文件进行遍历,获得某个目录中的所有子目录或文件的文件名,以String返回
        File f1=new File("C:/JAVA 非凡");
        String[] strings=f1.list();
        for (String s:strings){
            System.out.println(s);
        }

        //对目录里的文件进行遍历,获得某个目录中的所有子目录或文件,以File对象返回
        File f2=new File("C:/JAVA 非凡");
        File [] files=f2.listFiles();
        for (File s:files) {
            System.out.println(s);
        }

        //设置条件来选择要操作的对象,返回File对象
        File f3 = new File("C:/JAVA 非凡");
        File[]  files1=f3.listFiles(new MyFileFilter());
        for (File s:files1){
            System.out.println(s);
        }
    }
}

import java.io.File;
import java.io.FilenameFilter;

public class MyFileFilter implements FilenameFilter {

    @Override
    public boolean accept(File dir, String name) {
        return name.endsWith("java");
    }
}

输入及输出的概念

输入输出,将电脑的硬盘上的数据往程序读为输入,把程序中的数据往程序外读为输出。

IO流中的流意思是读写文件的操作类。

IO输入流和输出流,读写文件的操作,根据操作单位不同可分为:

1.字节流以字节为单位,读取时,每次读一个字节

InputStream 字节流输出

OutputStream 字节流输入

2.字符流 以子符为单位,读取时,每次读一个字符,只适合读文本文件

Reader read 字符流输出

Writer writer 字符流输入

import java.io.*;

public class Demo2 {
    /*
        IO输入流和输出流
        读写文件的操作
        根据操作单位不同可分为:
        1.字节流
        以字节为单位,读取时,每次读一个字节
        InputStream 字节流输出
        OutputStream 字节流输入

        2.字符流
        以子符为单位,读取时,每次读一个字符
        只适合读文本文件
        Reader read 字符流输出
        Writer writer 字符流输入
         */
    public static void main(String[] args) throws IOException {
        File file=new File("D:/File.txt");
        try {
            file.createNewFile();
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("文件已存在");
        }
        FileInputStream in=new FileInputStream(file);
        FileOutputStream out=new FileOutputStream("D:/File2.txt");
        //字节流输出
        int n=0;
        while ((n=in.read())!=-1){
            System.out.println(n);
        }
        in.close();//关闭流的通道,释放对文件的占用
        //字节流输入
        int t=0;
        while ((t=in.read())!=-1){
            out.write(t);
        }
        out.close();//关闭流的通道,释放对文件的占用
    }
}

输入输出节点字节流

字节流的输入输出使用InputStream和OutputStream两种方法。

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

public class Demo4 {
    /*
    字节流
     */
    public static void main(String[] args) throws IOException {
        FileInputStream in=null;
        FileOutputStream out=null;

        try {
            in =new FileInputStream("D:\\File.txt");
            out =new FileOutputStream("D:\\File1.txt");
            int n=0;
            while ((n=in.read())!=-1){
                //in.read();//读取时以int字节形式读取,一次读取一个字节,当文件读完时返回-1
                out.write(n);//写入时,一次向目标写入一个字节
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            System.out.println(e.getMessage());//日志记录
        }finally {
            if (in!=null)
                in.close();//关闭流的通道,释放对文件的占用
            if (out!=null)
                out.close();//关闭流的通道,释放对文件的占用
        }

        byte[] bytes=new byte[10];


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

public class Demo5 {
    public static void main(String[] args) throws IOException {
        FileInputStream in=null;
        FileOutputStream out=null;

        try {
            in =new FileInputStream("D:\\File.txt");
            out =new FileOutputStream("D:\\File1.txt");
            //这每次读一个字节,时间长
//            int n=0;
//            while ((n=in.read())!=-1){
//                out.write(n);//写入时,一次向目标写入一个字节
//            }
            //这根据定义的byte数组长度,每次读byte.length个字节
            //当最后一次剩余字节不足以将byte数组放满,则剩多少放多少
            byte[] bytes=new byte[5];
            int size=0;
            while ((size=in.read(bytes))!=-1){
                System.out.println("这次byte中放入字节数为:"+size);
                //in.read();//读取时以int字节形式读取,一次读取一个字节,当文件读完时返回-1
                out.write(bytes,0,size);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            System.out.println(e.getMessage());//日志记录
        }finally {
            if (in!=null)
                in.close();//关闭流的通道,释放对文件的占用
            if (out!=null)
                out.close();//关闭流的通道,释放对文件的占用
        }




    }
}

节点流与处理流

根据封装的类型,流可分为字节流和处理流。

节点流 流对象是直接对数据进行操作。 例如:构造方法(文件)

处理流(包装流) 流对象中包装的是另一个流,提供一些额外的数据处理。 例如:ObjectInputStream(InputStream in);

节点流中的常用类:

字节输入流 FileInputStream

字节输出流 FileOutputStream

字符输入流 FileReader

字符输出流 FileWriter

import java.io.*;

public class Demo7 {
    /*
        节点流
        流对象是直接对数据进行操作。 例如:构造方法(文件)
        处理流(包装流)
        流对象中包装的是另一个流,提供一些额外的数据处理。 例如:ObjectInputStream(InputStream in);
       
         */
    public static void main(String[] args) throws IOException {
        FileInputStream in=new FileInputStream("C:\\Users\\Nexus\\Desktop\\2022-7-11_java第八章IO\\练习\\feige.exe");
        FileOutputStream out= new FileOutputStream("C:\\Users\\Nexus\\Desktop\\2022-7-11_java第八章IO\\练习\\feige.txt");
        BufferedInputStream bin = new BufferedInputStream(in);//缓存大小为DEFAULT_BUFFER_SIZE = 8192
        BufferedOutputStream bout =new BufferedOutputStream(out);

        int name=0;
        while ((name=bin.read())!=-1){//将数据读入底层的数组中(缓存区中),待读满缓存区中的8192个再输出
            bout.write(name);//并不是每次write都向磁盘去写数据,而是等缓存区数组满后再向磁盘输出
        }
        bin.close();
        bout.flush();//操作完成后,将缓存区刷新清空
        in.close();
        out.close();
    }
}

处理流中的常用类:

缓冲字节输出流 BufferedOutputStream

缓冲字节输入流 BufferedInputStream

缓冲字符输入流 BufferedReader

缓冲字符输出流 BufferedWriter

缓冲的输入流和输出流:

将数据读入底层的数组中(缓存区中,缓存大小为DEFAULT_BUFFER_SIZE = 8192),待读满缓存区中的8192个再输出;并不是每次write都向磁盘去写数据,而是等缓存区数组满后再向磁盘输出。

import java.io.*;

public class Demo6 {
        /*
        节点流
        流对象是直接对数据进行操作。 例如:构造方法(文件)
        处理流(包装流)
        流对象中包装的是另一个流,提供一些额外的数据处理。 例如:ObjectInputStream(InputStream in);

         */
    public static void main(String[] args) throws IOException {
        FileInputStream in=new FileInputStream("C:\\Users\\Nexus\\Desktop\\2022-7-11_java第八章IO\\练习\\feige.exe");
        FileOutputStream out= new FileOutputStream("C:\\Users\\Nexus\\Desktop\\2022-7-11_java第八章IO\\练习\\feige.txt");
        BufferedInputStream bin = new BufferedInputStream(in);//缓存大小为DEFAULT_BUFFER_SIZE = 8192
        //BufferedInputStream bin = new BufferedInputStream(in,1024);可改变缓存大小
        BufferedOutputStream bout =new BufferedOutputStream(out);

        byte[] bytes=new byte[1024*1024];//当自定义数组大于缓存区数组长度时,缓存区数组会失效
        int name=0;
        while ((name=bin.read(bytes))!=-1){//将1024个数据读入byte数组中,再读入底层的数组中(缓存区中),待读满缓存区中的8192个再输出
            System.out.println(bytes);
            bout.write(name);
        }
        bin.close();
        bout.flush();//操作完成后,将缓存区刷新清空
        in.close();
        out.close();
    }
}

输入输出节点字符流

字符流

字符输入流的基类:Reader

子类:FileReader extends InputStreamReader(转换流,将读到的字节按编码表(charsset)转换为字符)

字符输出流的基类:Writer extends OutputStream

子类:FileWriter extends InputStreamWriter(转换流,将读到的字符按编码表(charsset)转换为字节写出)

汉子的输入输出问题:

在uft-8编码表中,一个汉子等于三个字节,底层存储的单位是字节,通过转换流,将读到的字节按编码表(charsset)转换为字符。

import java.io.*;

public class Demo8 {
    /*
    字符流
    字符输入流的基类:Reader
    子类:FileReader extends InputStreamReader(转换流,将读到的字节按编码表(charsset)转换为字符)
    字符输出流的基类:Writer extends OutputStream
    子类:FileWriter extends InputStreamWriter(转换流,将读到的字符按编码表(charsset)转换为字节写出)
    汉子的输入输出问题:在uft-8编码表中,一个汉子等于三个字节,底层存储的单位是字节,通过转换流,将读到的字节按编码表(charsset)转换为字符。

    缓冲输入:BufferedReader
    缓冲输出:BufferedWriter
     */

    public static void main(String[] args) throws IOException {
        FileReader fileReader=new FileReader("C:\\Users\\Nexus\\Desktop\\2022-7-11_java第八章IO\\练习\\File1.txt");
        FileWriter fileWriter=new FileWriter("C:\\Users\\Nexus\\Desktop\\2022-7-11_java第八章IO\\练习\\File2.txt");

//        int name;
//        while ((name= fileReader.read())!=-1){
//            fileWriter.write(name);
//        }

        char[] chars=new char[5];
        int name;
        while ((name= fileReader.read(chars))!=-1){
            fileWriter.write(chars,0,name);
        }
        fileReader.close();
        fileWriter.close();
    }
}

字符流缓冲输入:BufferedReader

字符流缓冲输出:BufferedWriter

import java.io.*;

public class Demo9 {
       /*
        字符流
        缓冲输入:BufferedReader
        缓冲输出:BufferedWriter
        */
    public static void main(String[] args) throws IOException {

        FileReader fileReader=new FileReader("C:\\Users\\Nexus\\Desktop\\2022-7-11_java第八章IO\\练习\\File1.txt");
        FileWriter fileWriter=new FileWriter("C:\\Users\\Nexus\\Desktop\\2022-7-11_java第八章IO\\练习\\File2.txt");
        //FileWriter fileWriter=new FileWriter(fileName,true);写入数据时,可以保留之前的数据,追加内容
        BufferedReader bufferedReader=new BufferedReader(fileReader);
        BufferedWriter bufferedWriter=new BufferedWriter(fileWriter);

//        int name;
//        while ((name= fileReader.read())!=-1){
//            fileWriter.write(name);
//        }

//        char[] chars=new char[5];
//        int name;
//        while ((name= bufferedReader.read(chars))!=-1){
//            //bufferedWriter.write(chars);
//            bufferedWriter.write(chars,0,name);
//        }

        int name;
        String line;
        while ((line=bufferedReader.readLine())!=null){//readLine()一次可以读取一行数据
            bufferedWriter.write(line);
            bufferedWriter.newLine();//插入换行符
        }

        bufferedReader.close();
        bufferedWriter.close();
        fileReader.close();
        fileWriter.close();
    }
    }

Print流

 Print流(打印流):只做输出操作,单位的从程序向目标输出数据,没有输入操作。按打印的数据类型分可分为字节打印流和字符打印流。

PrintWriter:字符打印流print方法可以打印各种数据类型的数据。

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

public class Demo10 {
    /*
    Print流
    打印流:只做输出操作,单位的从程序向目标输出数据,没有输入操作。按打印的数据类型分可分为字节打印流和字符打印流。
    PrintWriter
    字符打印流print方法可以打印各种数据类型的数据
     */
    public static void main(String[] args) throws FileNotFoundException {
        PrintWriter printWriter=new PrintWriter("C:\\Users\\Nexus\\Desktop\\2022-7-12_java第八章IO\\练习\\test.html");

        printWriter.print("<h1>Hello world<h1>");
        printWriter.print("<h1>Hello world<h1>");
        printWriter.print("<h1>Hello world<h1>");
        printWriter.print("<h1>Hello world<h1>");
        printWriter.close();
    }
}

 对象输入输出流

 在编码过程中,对象被存储在内存中,程序终止运行时,内存数据会被刷新清空,有时需要保存对象中的数据,需要使用流对象,将对象数据输出到文件中,做到对象数据的持久化(长久保存)。

对象输入输出流,都属于处理流:

ObjectInputStream(反序列化)                                                                                  ObjectOutputStream(序列化)

这过程也称为对象序列化和反序列化。

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

public class Demo11 {
    /*
    在编码过程中,对象被存储在内存中,程序终止运行时,内存数据会被刷新清空
    有事需要保存对象中的数据,需要使用流对象,将对象数据输出到文件中,做到对象数据的持久化(长久保存)
    对象输入输出流,都属于处理流:
        ObjectInputStream(反序列化)
        ObjectOutputStream(序列化)
    这过程也称为对象序列化和反序列化.

     */
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        //对象序列化,对象序列化后有它自己特定的格式
        FileOutputStream fileOutputStream=new FileOutputStream("C:\\Users\\Nexus\\Desktop\\2022-7-12_java第八章IO\\练习\\temp\\test.txt");
        ObjectOutputStream objectOutputStream=new ObjectOutputStream(fileOutputStream);
        Date date=new Date();
        String s="ABCdef";
        objectOutputStream.writeObject(date);
        objectOutputStream.writeObject(s);

        objectOutputStream.flush();
        objectOutputStream.close();

        //对象反序列化,会新创建对象
        FileInputStream fileInputStream=new FileInputStream("C:\\Users\\Nexus\\Desktop\\2022-7-12_java第八章IO\\练习\\temp\\test.txt");
        ObjectInputStream objectInputStream=new ObjectInputStream(fileInputStream);
        Date date1=(Date) objectInputStream.readObject();
        String s1=(String)objectInputStream.readObject();
        System.out.println(date1);
        System.out.println(s1);
        objectInputStream.close();
    }
}

Serializable序列化接口

 Serializable 序列化接口:如果需要将某一对象进行序列化,那么此类必须实现Serializable接口 实现后,会生成一个版本号,如果不显示的定义版本号,会自定默认生成。

对象序列化,对象序列化后有它自己特定的格式;对象反序列化,会新创建对象。

自动生成版本号会有一个问题,每次当类改变了,版本号会重新生成 所以但一个类需要经常序列化和反序列化时,建议显式定义版本号。

序列化版本号,版本号的显式定义后,类信息发生改变后不会重新生成。

transient关键字:transient定义的属性,在序列化时不会保存到文件中。

import java.io.Serializable;

public class Animal implements Serializable {
    /*
    Serializable 序列化接口
    如果需要将某一对象进行序列化,那么此类必须实现Serializable接口
    实现后,会生成一个版本号,如果不显示的定义版本号,会自定默认生成,
    自动生成版本号会有一个问题,每次当类改变了,版本号会重新生成
    所以但一个类需要经常序列化和反序列化时,建议显式定义版本号
     */
    //序列化版本号,版本号的显式定义后,类信息发生改变后不会重新生成
    private static final long serialVersionUID = -5869686875672962881L;
    //transient定义的属性,在序列化时不会保存到文件中
    private transient int age;
    private String name;

    public Animal(int age, String name) {
        this.age = age;
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

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

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

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

public class AnimalTest {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        //对象序列化,对象序列化后有它自己特定的格式
        FileOutputStream fileOutputStream=new FileOutputStream("C:\\Users\\Nexus\\Desktop\\2022-7-12_java第八章IO\\练习\\temp\\test.txt");
        ObjectOutputStream objectOutputStream=new ObjectOutputStream(fileOutputStream);
        Animal animal1=new Animal(5,"旺财");
        objectOutputStream.writeObject(animal1);

        objectOutputStream.flush();
        objectOutputStream.close();

        //对象反序列化,会新创建对象
        FileInputStream fileInputStream=new FileInputStream("C:\\Users\\Nexus\\Desktop\\2022-7-12_java第八章IO\\练习\\temp\\test.txt");
        ObjectInputStream objectInputStream=new ObjectInputStream(fileInputStream);
        Animal animal2=(Animal) objectInputStream.readObject();
        System.out.println(animal2);
        objectInputStream.close();
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值