JAVA-IO流篇

一、什么是IO流

IO流(InputOutput )即文件的输入输出流,负责对文件的读和写。
IO流在 java.io.*包下

io 流章节主要是使用流对文件的读写和通过File类操作目录和文件。

二、IO流的分类

所有流都实现了 java.io.Closeablecolse()方法皆为可关闭的。
所有流都实现了 java.io.Flushablefiush()方法皆为可刷新的

记忆小窍门:以Stream 结尾的均为字节流,以 Reader 或 Writer 结尾的均为字符流。

按照家族分类:

以下皆为抽象类,

概述
java.io .InputStream字节输入流
java.io.OutputStream字节输出流
java.io.Reader字符输入流
java.io .Writer字符输出流

按照功能分类

!!! 只列出常用的16个流

文件专属流

概述
java.io.FileInputStream字节输入流
java.io.FileOutStream字节输出流
java.io.FileReader字符输入流
java.io.FileWriter字符输出流

转换流

将字节流转为字符流

概述
java.io.InputStreamReader输入流转换
java.io.OutStreamWriter输出流转换

缓冲流专属

概述
java.io.BufferedInputStream带缓冲的字节输入流
java.io.BufferedOutStream带缓冲的字节输出流
java.io.BufferedReader带缓冲的字符输入流
java.io.BufferedWriter带缓冲的字符输出流

数据专属流

概述
java.io.DateInputStream可以读取带数据类型的文件
java.io.DateOutputStream可以写入数据类型的流

标准输出流

概述
java.io.PrintWriter
java.io.PrintStream系统打印流

对象专属流

概述
java.io.ObjectInputStream反序列化
java.io.ObjectOutputStream序列化

待补充

三、IO流的使用

其实每种流的使用方式都大同小异,使用对象调用方法,以下展示文件专属流的使用方法,和其他流之间的小异之处,具体请参照API文档。

文件专属流示例:

FileInputStream 和 FileOutputStream 是文件字节输入输出流,主要读写字节
FileReader 和 FileWriter 是文件字符输入输出流,主要读写字符(只能读取普通文本不能读取图片等)

FileInputStream

读取指定个数的字符

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

public class MyFileInputStream {

    public static void main(String[] args) throws IOException {


        FileInputStream fileInputStream = null;
        try {
            /*
               FileInputStream 构造方法有三个重载:String name | File file | FileDescriptor fdObj。
            */
            fileInputStream = new FileInputStream("C:\\Users\\Desktop\\新建文本文档.txt");

            byte[] bytes = new byte[10];
            int count =0;

            while ((count = fileInputStream.read(bytes)) != -1){
                    /*
                     int i = fileInputStream.read()每次只读一个字节,返回值为读到的字节的阿克斯码
                     int i = fileInputStream.read(bytes)每次读取byte长度的字节数,读取到的字节将存入byte数组中,
                     返回值为读到的字节的个数,当最后一次读取到的所剩字节若少于byte数组的长度时,则将读到的字节按照顺序
                     覆盖数组中前若干个字节,在读取不到时则返回-1,当返回-1时使用new String(byte,起始位置,长度)将
                     字节转换为字符串即可完成读取。
                    */
                String s = new String(bytes,0,count);//读到的字节
                System.out.println(s);
            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }finally {
            /* 关闭流 */
            if (fileInputStream != null){
                fileInputStream.close();
            }

        }

    }

}

一次读取全部字符


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

public class MyFileInputStream {

    public static void main(String[] args) throws IOException {


        FileInputStream fileInputStream = null;
        try {
            /*
               FileInputStream 构造方法有三个重载:String name | File file | FileDescriptor fdObj。
            */
            fileInputStream = new FileInputStream("C:\\Users\\Desktop\\新建文本文档.txt");

            /*返回从此输入流中可以读取(或跳过)的剩余字节数的估计值,*/
            int number =fileInputStream.available();
            /*一次读取全部*/
            byte[] bytes = new byte[number];
            /*读取 全部 大小的字节,返回字符个数 */
            int byt = fileInputStream.read(bytes);

            System.out.println(new String(bytes));

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }finally {
            /* 关闭流 */
            if (fileInputStream != null){
                fileInputStream.close();
            }
        }
    }
}

跳过一些字符不读取

  /*跳过一些字节不读取*/
   fileInputStream.skip(10);

FileOutputStream


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

public class MyFileOutputStream {

    public static void main(String[] args) throws IOException {

        FileOutputStream outputStream = null;

        try {

            /*创建文件输出流 三个重载 File file | File file, boolean append | FileDescriptor fdObj| String name |
            String name, boolean append
            以下构造为从文件的开始位置开始写入,在流写入关闭后再次使用流进行写入时。会清空原文件内容!!!!使用第五个构造方法
            new FileOutputStream("文件名",true) 为从文件内容的末尾开始写入
             */
            outputStream = new FileOutputStream("C:\\Users\\XinPeng.SHI\\Desktop\\IO测试.txt");

            byte[] bytes = {94,95,96,97,98,99,100};
            /*全部写出*/
            outputStream.write(bytes);
            /*部分写出*/
            /*outputStream.write(bytes,0,4);*/
            /*一次写一个*/
            /*outputStream.write(int byt)*/
			/*刷新*/
			outputStream.flush();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }finally {
            if (outputStream != null){
                try {
                    
                    outputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

FileReader

package IO;


import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

public class MyFileReader {

    public static void main(String[] args) throws IOException {

        FileReader reader = null;

        try {
            reader = new FileReader("C:\\Users\\Desktop\\新建文本文档.txt");
            /*创建一个char数组,表示每次读取的个数*/
            char[] chars = new char[10];
            /*读取到的个数*/
            /*int number =  reader.read(chars);*/
            /*判断值*/
            int count = 0;
            while ((count = reader.read(chars)) != -1){
                System.out.println(new String(chars,0,count));
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }finally {
            if (reader != null){
                try {
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

FileWriter

package IO;


import java.io.FileWriter;
import java.io.IOException;

public class MyFileWriter {

    public static void main(String[] args) {

        FileWriter  writer = null;
        /*FileWriter 有五种方法重载,重载参数和 FileOutputStream相同 */
        try {
            writer = new FileWriter("C:\\Users\\XinPeng.SHI\\Desktop\\FileWriter测试.txt");
            /* FileWriter也可以直接写入String字符串 或 char 数组*/
            char[] chars = {'一','二','三','四','五','六' };
            /*全部写入*/
            writer.write(chars);
            /*部分写入*/
           /* writer.write(chars,0,5);*/
            /*刷新*/
            writer.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if (writer!=null){
                try {
                    writer.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

带缓冲的流

Buffered即带缓冲的流,这四个流不需要数组,自带缓冲。只展示了BufferedReader。
使用了装饰者模式。

BufferedReader

import java.io.*;

public class MyBufferedReader {

    public static void main(String[] args)  {
        try {
            /**/
            BufferedWriter bufferedWriter = new BufferedWriter( 
                    new OutputStreamWriter(
                    new FileOutputStream("C:\\Users\\XinPeng.SHI\\Desktop\\新建文本.txt")
                    )
            );
            char[] chars = {'一','二','三','四','五','六' };
             /*开始写*/
            bufferedWriter.write(chars,0,4);
            /*换行*/
            bufferedWriter.newLine();
            /*内容末尾追加*/
            bufferedWriter.append()
            bufferedWriter.write(chars,0,4);
            /* 关闭流 */
            bufferedWriter.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }


}

数据专属流

DataOutputStream 和 DataInputStream是数据字节输入输出流
数据专属流可以将数据以及数据类型共同写入文件中。
在读取DataOutputStream写的文件时。读取文件的顺序必须按照写入时的顺序进行读取,

DataOutputStream


import java.io.*;

public class MyOutputStream {

    public static void main(String[] args) {
        long l = 10000;
        DataOutputStream dataOutputStream = null;

        try {
            dataOutputStream = new DataOutputStream(new FileOutputStream("C:\\Users\\XinPeng.SHI\\Desktop\\新建文本.txt"));
            /*在写入时根据数据类型选择*/
            /*dataOutputStream.writeInt();
            dataOutputStream.writeChar();*/
            try {
                dataOutputStream.writeLong(l);
            } catch (IOException e) {
                e.printStackTrace();
            }
            //......

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

标准流

标准的字节流默认输出到控制台。标准输出流不需要关闭,我们可以改变输出的位置从而达到日志输出的功能。


import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintStream;

public class MyPrintStream {

    public static void main(String[] args) {

        try {
            PrintStream printStream = new PrintStream(new FileOutputStream("C:\\Users\\Desktop\\文本.txt",true));
            /*修改输出位置*/
            System.setOut(printStream);
            /*输出内容*/
            System.out.println("123123131");

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }
}

四、File类

File类不是一种流不能进行文件的读写,在系统中的任何一个都是一个File,File可以理解为所有文件的抽象表示,是文件和目录路径名的抽象表示。使用File类可以对文件和文件目录进行操作
以下展示File常用的方法

        
package IO;


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

public class MyFile {
    public static void main(String[] args) throws IOException {
        /*四种重载*/
        File file  = new File("C:\\Users\\Desktop\\新建文本.txt");
        /*判断文件或目录是否在存在*/
        boolean b = file.isFile();
        /*如果不存在则创建这个文件*/
        if (!b){
            file.createNewFile();
        }
        /*如果不存在则创建这个 目录*/
        if (!b){
            file.mkdir();
            /*以多重目录的方式新建时只需将newFile()中写入多重目录的路径即可*/
            /*file.mkdirs();*/
        }
        /*获取该文件的父路径(两种返回值不相同)*/
        file.getParent();
        file.getParentFile();
        /*获取绝对路径*/
        file.getAbsolutePath();
        /*获取文件的名字*/
        file.getName();
        /*判断是否为目录*/
        file.isDirectory();
        /*判断是否为文件*/
        file.isFile();
        /*判断是否为隐藏文件*/
        file.isHidden();
        /*获取文件的最后修改时间 返回毫秒 1970.01.01.00.00*/
        long l = file.lastModified();
        /*将毫秒转换为日期*/
        Date date = new Date(l);
        /*穿件日期格式*/
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");
        /*返回日期时间*/
        format.format(date);
        /*获取文件大小(字节)*/
        file.length();
        /*获取目录下的子文件*/
        file.listFiles();
    }
}

五、对象专属流(序列化与反序列化)

  • 序列化是指将java对象转换为字节存储在文件中,方便传输或存储。
    反序列化是将序列化后得到文件转换为java对象。
  • 需要序列化的类必须实现 Serializable 标志性接口。
  • 在序列化多个对象时请将对象放入集合中, 一次性序列化整个集合即可,反序列化时也是如此

序列化

package IO;


import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;

public class MyObjectOutputStream {


    public static void main(String[] args) {

        String s = new String();
        ObjectOutputStream outputStream = null;

        try {

            outputStream = new ObjectOutputStream(new FileOutputStream("String类"));

            /*序列化*/
            outputStream.writeObject(s);

            /*刷新*/
            outputStream.flush();

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

    }
}


反序列化


import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;

public class MyObjectInputStream {

    public static void main(String[] args) {

        try {

            ObjectInputStream  inputStream = new ObjectInputStream(new FileInputStream("user"));
            /*反序列化*/
            String s =  (String)inputStream.readObject();

            System.out.println(s.getClass());//class java.lang.String


        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

序列化版本号

在一个类序列化时JVM会为此类默认生成一个序列化版本号内置其中。
在java序列化中在区分类时,若类名不同则类定然不同,在类名且包名都相同时,依靠序列化本号区分。若一个类在后续修改了代码,此时再次编译后将会产生不同的序列化版本号,这会使原先已经序列化过的类在反序列化时出错,因此,我们应在创建一个需要序列化的类时应手动以常量的形式指定序列化版本号,且最好唯一不重复。

/*常量名为固定不可自定义*/
private static final long serialVersionUID = 8888888888888L;

transient关键字

在类中为属性使用transient关键字修饰可以使属性不参加序列化。

   
import java.io.Serializable;
    
public class User implements Serializable {
    	
     private transient int aeg;
    
 }

六、使用IO流读取Properties文件

  • 在java中 Properties 文件为推荐的属性配置文件,在 Properties中 以Key Value键值对的方式存在,在此文件中如果有相同的 Key 时则会覆盖 Value。

import java.io.FileReader;
import java.io.IOException;
import java.util.Properties;

public class ReadProperties {

    public static void main(String[] args) throws IOException {
        /*创建流*/
        FileReader fileReader = new FileReader("D:\\源码\\untitled\\src\\a.properties");
        /*创建 properties 对象*/
        Properties properties = new Properties();
        /*加载文件*/
        properties.load(fileReader);
        /*获取属性*/
        String name = properties.getProperty("name");
        String password = properties.getProperty("password");
        
        System.out.println(name);//admin
        System.out.println(password);//123456
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值