JavaIO流之四大抽象类

JavaIO流之四大抽象类

文章目录

  • JavaIO流之四大抽象类
    • 1.IO流的分类
    • 2.乱码的产生与解决
      • 2.1编码
      • 2.2解码
      • 2.3常见的字符编码
    • 3.字节流
      • 3.1输入流 FileInputStream
      • 3.2输出流 FileOutputStream
    • 4.字符流
      • 4.1输入流 FileReader
      • 4.2输出流 FileWriter
    • 5.转换流
      • 5.1InputStreamReader
      • 5.2OutputStreamWriter
    • 6.字符流和字节流的区别
    • 7.IO流异常处理
    • 8.IO流应用

1.IO流的分类

按照数据流向分:输入流、输出流。

按照数据类型分:字节流、字符流。

2.乱码的产生与解决

  • 编码和解码的规则不一致。
  • 平台不支持。

2.1编码

String --> byte[]
  • String类提供了编码的方法
byte[] getBytes() 使用平台的默认字符集将此 String 编码为 byte 序列 
byte[] getBytes(Charset charset) 使用指定的字符编码来编码字符串
byte[] getBytes(String charsetName) 使用指定的字符编码来编码字符串

2.2解码

byte[] --> String
  • String类提供了解码的构造方法
String(byte[] bytes) 通过使用平台的默认字符集解码指定的 byte 数组
String(byte[] bytes, Charset charset) 使用指定的字符集来解码指定的byte数组
String(byte[] bytes, String charsetName) 使用指定的字符集来解码指定的byte数组

2.3常见的字符编码

  • ASCII编码

用来表示英文,它使用1个字节表示,其中第一位规定为0,其他7位存储数据,一共可以表示128个字符。

  • 拓展ASCII编码

用于表示更多的欧洲文字,用8个位存储数据,一共可以表示256个字符。

  • GBK/GB2312/GB18030

简称国标,表示汉字。GB2312表示简体中文,GBK/GB18030表示繁体中文,其实就是几个不同的版本而已。

  • Unicode

包含世界上所有的字符,是一个字符集。

  • UTF-8

是Unicode字符的实现方式之一,它使用1-4个字符表示一个符号,根据不同的符号而变化字节长度

  • ISO8859-1

是单字节编码,向下兼容ASCII,不支持中文

3.字节流

3.1输入流 FileInputStream

  • 构造方法
FileInputStream(File file) 通过打开一个到实际文件的连接来创建一个 FileInputStream,该文件通过文件系统中的 File 对象 file 指定。
FileInputStream(String name) 通过打开一个到实际文件的连接来创建一个 FileInputStream,该文件通过文件系统中的路径名 name 指定。
  • 功能方法
int read() 从此输入流中读取一个数据字节。 
int read(byte[] b)从此输入流中将最多 b.length 个字节的数据读入一个 byte 数组中。 
int read(byte[] b, int off, int len) 从此输入流中将最多 len 个字节的数据读入一个 byte 数组中。 
void close() 关闭此文件输入流并释放与此流有关的所有系统资源。 

3.2输出流 FileOutputStream

  • 构造方法
  • 父路径存在的情况下,如果文件不存在,会自动创建文件。当append为true的时候,表示向源文件追加内容。
FileOutputStream(File file) 创建一个向指定 File 对象表示的文件中写入数据的文件输出流。 
FileOutputStream(File file, boolean append) 创建一个向指定 File 对象表示的文件中写入数据的文件输出流。 
FileOutputStream(String name) 创建一个向具有指定名称的文件中写入数据的输出文件流。 
FileOutputStream(String name, boolean append) 创建一个向具有指定 name 的文件中写入数据的输出文件流。 
  • 功能方法
void write(int b) 将指定字节写入此文件输出流。
void write(byte[] b) 将 b.length 个字节从指定 byte 数组写入此文件输出流中。 
void write(byte[] b, int off, int len) 将指定 byte 数组中从off 开始的len个字节写入此文件输出流。
void close() 关闭此文件输出流并释放与此流有关的所有系统资源。

4.字符流

4.1输入流 FileReader

  • 构造方法
FileReader(File file) 在给定从中读取数据的 File 的情况下创建一个新 FileReader。 
FileReader(String fileName) 在给定从中读取数据的文件名的情况下创建一个新 FileReader。 
  • 功能方法
int read() 读取单个字符。
int read(char[] cbuf) 将字符读入数组。
int read(char[] cbuf, int off, int len) 将字符读入数组的某一部分。
//使用方法同FileInputStream(while循环,判断文档末尾是否为-1)

4.2输出流 FileWriter

  • 构造方法
FileWriter(File file) 根据给定的 File 对象构造一个 FileWriter 对象。 
FileWriter(File file, boolean append)  根据给定的 File 对象构造一个 FileWriter 对象。 
FileWriter(FileDescriptor fd) 构造与某个文件描述符相关联的 FileWriter 对象。 
FileWriter(String fileName) 根据给定的文件名构造一个 FileWriter 对象。 
FileWriter(String fileName, boolean append) append如果为true,不覆盖原文件,直接向原文件中追加内容。
  • 功能方法
 void close() 关闭此流,但要先刷新它(关闭流的时候也会自动刷新)。 
 void flush() 刷新该流的缓冲。 
 String getEncoding() 返回此流使用的字符编码的名称。 
 void write(char[] cbuf, int off, int len) 写入字符数组的某一部分。 
 void write(int c) 写入单个字符。 
 void write(String str, int off, int len) 写入字符串的某一部分。 

5.转换流

5.1InputStreamReader

  • 构造方法
InputStreamReader(InputStream in) 创建一个使用默认字符集的 InputStreamReader。 
InputStreamReader(InputStream in, Charset cs)  创建使用给定字符集的 InputStreamReader。 
InputStreamReader(InputStream in, CharsetDecoder dec) 创建使用给定字符集解码器的 InputStreamReader。 
InputStreamReader(InputStream in, String charsetName) 创建使用指定字符集的 InputStreamReader。 
  • 功能方法
 void close() 关闭该流并释放与之关联的所有资源。 
 String getEncoding() 返回此流使用的字符编码的名称。 
 int read() 读取单个字符。 
 int read(char[] cbuf, int offset, int length) 将字符读入数组中的某一部分。 
 boolean ready() 判断此流是否已经准备好用于读取。 

5.2OutputStreamWriter

  • 构造方法
OutputStreamWriter(OutputStream out) 创建使用默认字符编码的 OutputStreamWriter。 
OutputStreamWriter(OutputStream out, Charset cs) 创建使用给定字符集的 OutputStreamWriter。 
OutputStreamWriter(OutputStream out, CharsetEncoder enc) 创建使用给定字符集编码器的 OutputStreamWriter。 
OutputStreamWriter(OutputStream out, String charsetName) 创建使用指定字符集的 OutputStreamWriter。 
  • 功能方法
 void close() 关闭此流,但要先刷新它。 
 void flush() 刷新该流的缓冲。 
 String getEncoding() 返回此流使用的字符编码的名称。 
 void write(char[] cbuf, int off, int len) 写入字符数组的某一部分。 
 void write(int c) 写入单个字符。 
 void write(String str, int off, int len) 写入字符串的某一部分。 

6.字符流和字节流的区别

  • 操作单位不同:一个是字节,一个是字符。
  • 操作中文(文档)的时候使用字符流更方便,字节流更广泛:文本、视频、音频、图片都可以。
  • 字符流中有直接可以写字符串的方法。
  • 字节流如果不关闭流也会写入文件,字符流必须经过刷新或者关闭,才会写入文件。
  • 字符流关闭的时候会先刷新,关闭后不能使用,刷新之后可以继续操作。
  • 当字符流写入数据较多时,可以使用刷新的方法提交数据。

7.IO流异常处理

  • 处理方式一:注意关闭流之前要判断非空。
	FileInputStream fis = null;
        FileOutputStream fos = null;
        try{
            fis = new FileInputStream("E:/test/a.avi");
            fos = new FileOutputStream("E:/test/b.avi");
            //建立一个数组,用于保存读取的数据
            byte[] bys = new byte[10];
            //构建一个int类型的局部变量,用于保存每次读的数据的长度
            int len = 0;
            //while循环,读取数据
            while ((len = fis.read(bys))!=-1){
                //写数据
                fos.write(bys, 0, len);
            }
        }catch (IOException e){
            e.printStackTrace();
        }finally {
            try {
                //关闭流之前要判断非空
                if(fos!=null){
                    fos.close();
                }
                if(fis!=null){
                    fis.close();
                }
            }catch (IOException e){
                e.printStackTrace();
            }

        }
  • 第二种方式:可以自动关闭流,不需要手动关闭。

自动关闭流资源必须是实现AutoCloseable接口的类。

	try(
		FileInputStream fis = new FileInputStream("E:/test/a.avi");
		FileOutputStream fos = new FileOutputStream("E:/test/b.avi");
		){
			byte[] bys = new byte[10];
			int len = 0;
			while ((fis.read(bys))!=-1){
				fos.write(bys, 0, len);
		}
	}catch(IOException e){
		e.printStackTrace();
	}

8.IO流应用

  • 拷贝文件夹
 	/**
     * 实现文件夹的拷贝
     * @param srcPath 要拷贝的目录
     * @param destPath 要拷贝到的目标目录
     * @throws IOException
     */
    public static void copyFolder(String srcPath,String destPath) throws IOException {
        FileInputStream fis = null;
        FileOutputStream fos = null;
        //创建File对象,方便调方法
        File file = new File(srcPath);
        //如果File对象所表示的抽象目录或者文件存在
        if(file.exists()){
            if(file.isFile()){//如果是文件,就拷贝
                fis = new FileInputStream(file);
                fos = new FileOutputStream(destPath+file.getAbsolutePath().substring(srcPath.length()));
                byte[] bys = new byte[512];
                int len = 0;
                while ((len = fis.read(bys))!=-1){
                    fos.write(bys, 0, len);
                }
            }else{//如果是目录
                //创建目录
                new File(destPath).mkdirs();
                //获取当前文件夹下左右的对象
                File[] files = file.listFiles();
                for (File f : files) {
                    copyFolder(f.toString(), destPath+f.getAbsolutePath().substring(srcPath.length()));
                }
            }
        }
    }
  • 拷贝筛选相同后缀的文件到一个目录下
	/**
     * 拷贝一个文件件中的满足指定后缀名的文件到另外一个文件夹中的效果
     * @param srcpath 所拷贝指定文件的根目录
     * @param destPath 拷贝到的新目录
     * @param name 指定的文件后缀
     */
    public static void copySelectFile(String srcpath,String destPath,String name) throws IOException {
        File file = new File(srcpath);
        new File(destPath).mkdirs();
        FileInputStream fis = null;
        FileOutputStream fos = null;
        //如果File对象所表示的抽象目录或者文件存在
        if(file.exists()){
            //如果此抽象路径是文件并且以指定后缀名结尾,就进行拷贝
            if(file.isFile() && file.getAbsolutePath().endsWith(name)){
                fis = new FileInputStream(file);
                fos = new FileOutputStream(destPath+"/"+file.getName());
                byte[] bys = new byte[512];
                int len = 0;
                while ((fis.read(bys))!=-1){
                    fos.write(bys, 0, len);
                }
            }//(此处不可以用else,因为当文件后缀不是指定的名称时,就会执行到这里,那么listFiles返回的就为空,会造成空指针异常)
            //如果是目录
            if(file.isDirectory()){
                //获取当前路径下所有File对象
                File[] files = file.listFiles();
                for (File f : files) {
                    copySelectFile(f.getAbsolutePath(), destPath,name);
                }
            }
        }
    }

你可能感兴趣的:(JavaIO流之四大抽象类)