JavaSE IO流

时间:2020-04-20
本文章向大家介绍JavaSE IO流,主要包括JavaSE IO流使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

一、File类的使用

  • File类的一个对象,代表一个文件或一个文件目录
  • 相对路径:相较于某个路径下,指明的路径
  • 绝对路径:包含盘符在内的文件或文件目录的路径
  • 路径分隔符
    • windows:\\
    • Unix:/
@Test
public void test1() {
   File file = new File("a.txt");
   System.out.println(file);
}

1.1 常用方法

@Test
public void test2() {
    File file = new File("cn/imut/hello.txt");
    //获取绝对路径
    System.out.println(file.getAbsoluteFile());
    //获取路径
    System.out.println(file.getPath());
    //获取名称
    System.out.println(file.getName());
    //获得上层文件目录路径,无则返回null
    System.out.println(file.getParent());
    //获取文件长度(字节数)
    System.out.println(file.length());
}
@Test
public void test3() {
    File file = new File("hello.txt");
    //判断是否是文件目录
    System.out.println(file.isDirectory());
    //判断是否是文件
    System.out.println(file.isFile());
    //判断是否存在
    System.out.println(file.exists());
    //判断是否可写
    System.out.println(file.canWrite());
}

二、IO流原理

  • I/O是Input/Output的缩写,I/O技术用于处理设备之间的数据传输
  • Java程序中,对于数据的输入/输出操作以“流(Stream)”的方式进行

输入input:将外部数据读取到内存中

输出output:将内存数据输出到磁盘、光盘中

三、流的分类

根据数据单位区分

  • 字节流:8 bit(InputStream,OutputStream)
  • 字符流:16bit(Reader,Writer)

根据流的流向区分

  • 输入流
  • 输出流

根据流的角色区分

  • 节点流
  • 处理流

3.1 IO流体系

分类 字节输入流 字节输出流 字符输入流 字符输出流
抽象基类 InputStream OutputStream Reader Writer
访问文件 FileInputStream FileOutputStream FileReader FileWriter
访问数组 ByteArrayInputStream ByteArrayOutputStream CharArrayReader CharArrayWriter
访问管道 PipedInputStream PipedOutputStream PipedReader PipedWriter
访问字符串 StringReader StringWriter
缓冲流 BufferedInputStream BufferedOutputStream BuffedReader BufferedWriter
转换流 InputStreamReader OutputStreamWriter
对象流 ObjectInputStream ObjectOutputStream
FilterInputStream FilterOutputStream FilterReader FilterWriter
打印流 PrintStream PrintWriter
退回输入流 PushbackInputStream PushbackReader
特殊流 DataInputStream DataOutputStream

四、文件流

文件读入

package cn.imut;

import java.io.File;
import java.io.FileReader;
import java.io.IOException;

public class IOTest {
    public static void main(String[] args) {
        FileReader fileReader = null;
        try {
            //1.File类实例化
            File file = new File("D:\\Test\\IO\\hello.txt");
            //2.FileReader流实例化
            fileReader = new FileReader(file);
            //3.读入操作
            char[] c = new char[5]; //表示每次读入5个
            int len;
            while ((len = fileReader.read(c)) != -1) {
                for (char value : c) {
                    System.out.print(value);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if(fileReader != null) {
                //4.资源关闭
                try {
                    fileReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

文件写出

package cn.imut;

import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class IOTest2 {
    public static void main(String[] args) {
        FileWriter fileWriter = null;
        try {
            //1.提供File类对象,指明写出到的文件
            File file = new File("D:\\Test\\IO\\hello.txt");
            //2.提供FileWriter对象,用于数据的写出
            fileWriter = new FileWriter(file);
            //3.写出操作
            fileWriter.write("hehe,I am you 's me");
            fileWriter.write("you a sb");
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //4.流资源关闭
            try {
                assert fileWriter != null;
                fileWriter.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

注意:输出操作,File可以不存在,若存在,流使用的构造器是FileWriter(file,false)则对原文件覆盖,若为FileWrith(file,true)不会覆盖原文件!

package cn.imut;

import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class IOTest3 {
    public static void main(String[] args) {
        FileReader fr = null;
        FileWriter fw = null;
        try {
            //1.创建File类的对象,指明读入和写出的文件
            File srcFile = new File("D:\\Test\\IO\\hello.txt");
            File destFile = new File("D:\\Test\\IO\\hello1.txt");
            //2.创建输入流和输出流的对象
            fr = new FileReader(srcFile);
            fw = new FileWriter(destFile);
            //3.数据的读入和写出操作
            char[] ch = new char[5];
            int len;
            while ((len = fr.read(ch)) != -1) {
                //每次写出 len个字符
                fw.write(ch,0,len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                assert fw != null;
                fw.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                fr.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }
}

FileInputStream

package cn.imut;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;

public class IOTest4 {
    public static void main(String[] args) {
        FileInputStream fileInputStream = null;
        try {
            //1.造文件
            File file = new File("D:\\Test\\IO\\hello2.txt");
            //2.造流
            fileInputStream = new FileInputStream(file);
            //3.读数据
            byte[] buffer = new byte[5];
            int len;    //记录每次读取的字节个数
            while ((len = fileInputStream.read(buffer)) != -1) {
                String str = new String(buffer,0,len);
                System.out.println(str);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //4.关闭资源
            try {
                assert fileInputStream != null;
                fileInputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

总结

  • 对于文本文件,使用字符流(FileReader/Writer)
  • 对于非文本文件,使用字节流(FileInputStream/OutputStream)

五、缓冲流

为了提高数据读写的速度,Java API提供了带缓冲功能的流类,在使用这些流类时,会创建一个内部缓冲区数组,缺省使用8192个字节(8Kb)的缓冲区

缓冲流要“套接”在相应的节点流之上,根据数据操作单位可以把缓冲流分为

  • BufferedInputStream 和 BufferedOutputStream
  • BufferedReader 和 BufferedWriter

**当读取数据时,数据按块读入缓冲区,其后的读操作则直接访问缓冲区 **

当使用BufferedInputStream读取字节文件时,BufferedInputStream会一次性从 文件中读取8192个(8Kb),存在缓冲区中,直到缓冲区装满了,才重新从文件中 读取下一个8192个字节数组

向流中写入字节时,不会直接写到文件,先写到缓冲区中直到缓冲区写满, BufferedOutputStream才会把缓冲区中的数据一次性写到文件里。使用方法 flush()可以强制将缓冲区的内容全部写入输出流

关闭流的顺序和打开流的顺序相反。只要关闭最外层流即可,关闭最外层流也 会相应关闭内层节点流

flush()方法的使用:手动将buffer中内容写入文件

图片复制

package cn.imut;

import java.io.*;

public class IOTest5 {
    public static void main(String[] args) {
        FileInputStream fis = null;
        FileOutputStream fos = null;
        try {
            File srcFile = new File("D:\\Test\\IO\\Test.jpg");
            File destFile = new File("D:\\Test\\IO\\Test1.jpg");

            fis = new FileInputStream(srcFile);
            fos = new FileOutputStream(destFile);

            BufferedInputStream bis = new BufferedInputStream(fis);
            BufferedOutputStream bos = new BufferedOutputStream(fos);

            byte[] buffer = new byte[10];
            int len;
            while ((len = bis.read(buffer)) != -1) {
                bos.write(buffer,0,len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                assert fis != null;
                fis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                assert fos != null;
                fos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

六、转换流

转换流提供了在字节流和字符流之间的转换

  • InputStreamReader:将InputStream转换为Reader
  • OutputStreamWriter:将Writer转换为OutputStrea

字节流中的数据都是字符时,转成字符流操作更高效

package cn.imut;

import java.io.*;

public class IOTest6 {
    public static void main(String[] args) {
        InputStreamReader isr = null;
        OutputStreamWriter osw = null;
        try {
            File file1 = new File("D:\\Test\\IO\\hello.txt");
            File file2 = new File("D:\\Test\\IO\\www.txt");

            FileInputStream fis = new FileInputStream(file1);
            FileOutputStream fos = new FileOutputStream(file2);

            isr = new InputStreamReader(fis,"utf-8");
            osw = new OutputStreamWriter(fos,"utf-8");

            char[] ch = new char[20];
            int len;
            while ((len = isr.read(ch)) != -1) {
                osw.write(ch,0,len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                assert isr != null;
                isr.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                assert osw != null;
                osw.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

6.1 常见编码表

  • ASCII:美国标准信息交换码,用一个字节的7位可以表示
  • ISO8859-1:拉丁码表,欧洲码表,用一个字节的8位表示
  • GB2312:中国的中文编码表,最多两个字节编码所有字符
  • GBK:中国的中文编码表升级,融合了更多的中文文字符号。最多两个字节编码
  • Unicode:国际标准码,融合了目前人类使用的所有字符。为每个字符分配唯一的字符码。所有的文字都用两个字节来表示
  • UTF-8:变长的编码方式,可用1-4个字节来表示一个字符

6.2 对象序列化

对象序列化机制允许把内存中的Java对象转换成平台无关的二进制流,从而允许把这种二进制流持久的保存在磁盘上,或通过网络将这种二进制流传输到另一个网络节点。当其他程序获取了这种二进制流,就可以恢复成原来的Java对象

序列化的好处在于可将任何实现了Serializable接口的对象转化为 字节数据 ,使其在保存和传输时可被还原

序列化是 RMI(Remote Method Invoke – 远程方法调用)过程的参数和返回值都必须实现的机制,而 RMI 是 JavaEE的基础。因此序列化机制是 JavaEE 平台的基础

如果需要让某个对象支持序列化机制,则必须让对象所属的类及其属性是可序列化的,为了让某个类是可序列化的,该类必须实现如下两个接口之一。 否则,会抛出NotSerializableException异常

  • Serializable
  • Externalizable

实现Serializable接口的类都有一个表示序列化版本标识符的静态变量

  • private static final long serialVersionUID
  • serialVersionUID用来表明类的不同版本间的兼容性。简言之,其目的是以序列化对象 进行版本控制,有关各版本反序列化时是否兼容
  • 如果类没有显示定义这个静态常量,它的值是Java运行时环境根据类的内部细节自 动生成的。若类的实例变量做了修改,serialVersionUID 可能发生变化,故建议显式声明!

简单来说,Java的序列化机制是通过在运行时判断类的serialVersionUID来验 证版本一致性的。在进行反序列化时,JVM会把传来的字节流中的 serialVersionUID与本地相应实体类的serialVersionUID进行比较,如果相同 就认为是一致的,可以进行反序列化,否则就会出现序列化版本不一致的异 常。(InvalidCastException)

七、标准输入、输出流

System.in和System.out分别代表了系统标准的输入和输出设备

默认输入设备是:键盘,输出设备是:显示器

**System.in的类型是InputStream,System.out的类型是PrintStream,其是OutputStream的子类 FilterOutputStream 的子类 **

原文地址:https://www.cnblogs.com/yfyyy/p/12735975.html