JAVA IO流

JAVA IO流

IO介绍

I/O 即输入(读)/输出(写)的意思,是Input与Output的简写,IO是任何编程语言都支持的,I/O 是机器获取和交换信息的主要渠道。在当今时代,I/O 问题尤其突出,很容易成为一个性能瓶颈。正因如此,所以 Java 在 I/O 上也一直在做持续的优化,如从 1.4 开始引入了 NIO,提升了 I/O 的性能。

File类(文件及文件夹管理)

在Java中File类是对文件系统中文件以及文件夹进行封装的对象,可以通过对象的思想来操作文件和文件夹。
File类保存文件或目录的各种元数据信息,包括文件名、文件长度、最后修改时间、是否可读、获取当前文件的路径名,判断指定文件是否存在、获得当前目录中的文件列表,创建、删除文件和目录等方法。

使用File类管理文件

TestFile.java

import org.junit.Test;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;

public class TestFile {

    /**
     * 抛出异常,当前这个方法抛出异常给上级,谁调用该方法,谁处理该异常
     * 处理异常使用try{}catch(Exception e){}
     */

    /**
     * 创建文件
     * @throws IOException
     */
    @Test
    public void getFile() throws IOException {
        //1.创建文件对象
//        File file = new File("D:\\IO\\File");
        //File中的separator静态常量,是一个自适应的斜线
        File file = new File("D:" + File.separator + "IO" + File.separator + "File");
        int i = 0;
        i++;
        //2.判断该目录文件是否存在
        if (!file.exists()) {
            //不存在则创建目录
            file.mkdirs();//创建整个目录,没有则创建,有就不变
//            file.createNewFile();  //创建文件一定在已有目录下创建文件
        }
        //在上级目录下创建一个新的文件
        File newFile = new File(file, "test.txt");
        boolean flag = newFile.createNewFile();
        if (flag) {
            System.out.println("文件已创建成功");
        } else {
            System.out.println("文件创建失败");
        }
    }

    /**
     * 删除文件
     */
    @Test
    public void deleteFile() {
        //创建文件对象,获取到文件夹
        File file = new File("D:" + File.separator + "IO" + File.separator + "File", "test.txt");
        System.out.println(file.getName());//文件或目录的名称
        System.out.println(file.getPath());//获取到相对路径
        System.out.println(file.getAbsolutePath());//获取到绝对路径
        if (file.delete()) {
            System.out.println("文件删除成功");
        } else {
            System.out.println("文件不存在,删除文件失败");
        }
    }


    /**
     * 查找所有的文件
     */
    @Test
    public void findFile() {
        //获取到所有的盘符
        File[] roots = File.listRoots();
        System.out.println(Arrays.toString(roots));
        //找到D盘目录
        File d = roots[1];
        //获取d盘下所有的文件和数量
        long num = showFile(d);
        System.out.println("D盘中所有文件的数量为:" + num);
    }


    /**
     * 查找文件方法
     * @param file
     * @return
     */
    private long showFile(File file) {
        long num = 0;
        //获取到当前目录下的子目录或文件
        File[] files = file.listFiles();
        //判断该数组是否为null
        if (files!=null){
            //循环所有目录
            for (File file2 : files) {
                 //判断file2是否为目录
                if (file2.isDirectory()){
                    //自己调用自己,查询当前文件夹的下一级文件
                    num += showFile(file2);
                }else {
                    num++; //如果是文件,就不需要遍历
                    System.out.println(file2.getParent()+ File.separator+file2.getName());
                }
            }
        }
        return num;
    }
}

IO流介绍

1.先进先出,最先写入输出流的数据最先被输入流读取到。

2.顺序存取,可以一个接一个地往流中写入一串字节,读出时也将按写入顺序读取一串字节,不能随机访问中间的数据。(RandomAccessFile可以从文件的任意位置进行存取(输入输出)操作)

3.只读或只写,每个流只能是输入流或输出流的一种,不能同时具备两个功能,输入流只能进行读操作,对输出流只能进行写操作。在一个数据传输通道中,如果既要写入数据,又要读取数据,则要分别提供两个流。

一.IO流常用到的五类一接口

在整个Java.io包中最重要的就是5个类和一个接口。5个类指的是File、OutputStream、InputStream、Writer、Reader;一个接口指的是Serializable.掌握了这些IO的核心操作那么对于Java中的IO体系也就有了一个初步的认识了。

二.主要的类如下:

1.File(文件特征与管理):File类是对文件系统中文件以及文件夹进行封装的对象,可以通过对象的思想来操作文件和文件夹。 File类保存文件或目录的各种元数据信息,包括文件名、文件长度、最后修改时间、是否可读、获取当前文件的路径名,判断指定文件是否存在、获得当前目录中的文件列表,创建、删除文件和目录等方法。

2.InputStream(二进制格式操作):抽象类,基于字节的输入操作,是所有输入流的父类。定义了所有输入流都具有的共同特征。

3.OutputStream(二进制格式操作):抽象类。基于字节的输出操作。是所有输出流的父类。定义了所有输出流都具有的共同特征。

4.Reader(文件格式操作):抽象类,基于字符的输入操作。

5.Writer(文件格式操作):抽象类,基于字符的输出操作。

6.RandomAccessFile(随机文件操作):一个独立的类,直接继承至Object.它的功能丰富,可以从文件的任意位置进行存取(输入输出)操作。

三.根据处理数据类型的不同分为字符流和字节流:

字节流: 以8位的字节形式来读写的流。他们的标志是名称以Stream结尾。InputStream与OutputStream分别是所有字节输入流与字节输出流的抽象父类。
字符流: 以字符形式来读写的流。它们的标志是名称以Reader或者Writer结尾。并且Reader和Writer分别是所有字符输入流与字符输出流的抽象父类。

四.字节流和字符流的区别:

读写单位不同:字节流以字节(8bit)为单位,字符流以字符为单位,根据码表映射字符,一次可能读多个字节。
处理对象不同:字节流能处理所有类型的数据(如图片、avi等),而字符流只能处理字符类型的数据。
结论:只要是处理纯文本数据,就优先考虑使用字符流。 除此之外都使用字节流。

五.根据数据流向不同分为输入流和输出流:

从流的方向上可分为两类(在java中是站在程序角度来区分流的方向,将数据读取到程序中就是输入流;反之,将程序中的数据写出去就是输出流):

  • 输入流: 从数据源中将数据读取到程序中的流。
  • 输出流:程序将数据写入到目的地的流。

字符输入输出流应用

一.字符的输入输出流

TestReaderAndWriter.java

import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.Reader;
import java.io.Writer;
import java.util.Arrays;
import java.util.Scanner;

import org.junit.Test;

/**
 * 字符输入输出流
 */
public class TestReaderAndWriter {

	/**
	 * 使用FileReader读取文件
	 */
	@Test
	public void in() {
		//1.创建文件对象,准备需要读取的文件
		File file = new File("D:"+File.separator+"IO"+File.separator+"File"+File.separator+"pet.template");
		//2.准备输入流
		//jdk1.7之后,可以直接放在括号中,结束时自动释放资源
		try (Reader read = new FileReader(file);){
			//3.准备需要读取内容的数组
			char[] c = new char[5];  //创建字符数组作为中转站
			//设置读取长度初始值
			int len = 0;
			//4.读取内容
			//len = read.read(c)  将字符读入数组
			while((len = read.read(c))!=-1) { //循环读取并追加字符
				System.out.println(Arrays.toString(c));
			}
			//5.关闭资源
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	

	/**
	 * 使用FileWriter写文件
	 */
	@Test
	public void out() {
		Scanner in = new Scanner(System.in);
		File file = new File("D:"+File.separator+"IO"+File.separator+"File"+File.separator+"hello.txt");
		try(Writer writ = new FileWriter(file)){
			String c = "";
			do {
				System.out.println("请输入要保存的内容:");
				String str = in.next();
				writ.write(str+"\n");  //采用字符串直接输出
				System.out.println("是否继续?y继续");
				c = in.next();
			}while(c.equals("y"));
			writ.flush();  //清空缓存
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

二.字符流的复制粘贴

copy.java

import org.junit.Test;

import java.io.*;

public class copy {
    /**
     * 字符流的复制粘贴
     */
    @Test
    public void copys() {
        try (Reader reader = new FileReader("D:"+ File.separator+"IO"+File.separator+"File"+File.separator+"hello.txt");
             //true表示将内容拼接到内容的末尾     默认为false  表示直接替换源文件
             Writer writ = new FileWriter("D:"+File.separator+"IO"+File.separator+"File"+File.separator+"test2.txt",true);
        ){
            char[] c = new char[1024];
            int len = 0;  //长度
            while((len=reader.read(c))!=-1) {
                //将读取的内容通过输出流输出到文件
                writ.write(c, 0, len);   //输出的长度为读取内容长度,而非整个数组长度
            }
            writ.flush();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

二.字符缓冲流

TestReaderAndWriter.java

import org.junit.Test;

import java.io.*;
import java.util.Scanner;

/**
 * 字符缓冲流
 */
public class TestReaderAndWriter {

    /**
     * BufferedReader:
     * public class BufferedReader extends Reader
     * 从字符输入流读取文本,缓冲字符,以提供字符,数组和行的高效读取。
     * 可以指定缓冲区大小,或者可以使用默认大小。 默认值足够大,可用于大多数用途。
     * 通常,由读取器做出的每个读取请求将引起对底层字符或字节流的相应读取请求。
     */
    @Test
    public void in() {
        //1.创建文件对象,准备需要读取的文件
        File file = new File("D:" + File.separator + "IO" + File.separator + "File" + File.separator + "pet.template");
        //2.准备输入流
        //jdk1.7之后,可以直接放在括号中,结束时自动释放资源
        try (Reader read = new FileReader(file);
             BufferedReader br = new BufferedReader(read);
        ) {
            //3.准备需要读取内容的数组
            char[] c = new char[1024];
            //设置读取长度初始值
            String str = null;
            //4.读取内容
            while ((str = br.readLine()) != null) {
                if (str.indexOf("{name}") >= 0) {
                    str = str.replace("{name}", "欧欧");
                }
                if (str.indexOf("{type}") != -1) {
                    str = str.replace("{type}", "雪纳瑞犬");
                }
                if (str.indexOf("{master}") != -1) {
                    str = str.replace("{master}", "波哥");
                }
                System.out.println(str);
            }
            //5.关闭资源
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    /**
     * BufferedWriter:
     * public class BufferedWriter extends Writer
     * 将文本写入字符输出流,缓冲字符,以提供单个字符,数组和字符串的高效写入。
     * 可以指定缓冲区大小,或者可以接受默认大小。 默认值足够大,可用于大多数用途。
     * 提供了一个newLine()方法,它使用平台自己的系统属性line.separator定义的行分隔符概念。 并非所有平台都使用换行符('\ n')来终止行。
     * 因此,调用此方法来终止每个输出行,因此优选直接写入换行符。
     */
    @Test
    public void out() {
        Scanner in = new Scanner(System.in);
        File file = new File("D:" + File.separator + "IO" + File.separator + "File" + File.separator + "hello.txt");
        try (Writer writ = new FileWriter(file);
             BufferedWriter bw = new BufferedWriter(writ);
        ) {
            String c = "";
            do {
                System.out.println("请输入要保存的内容:");
                String str = in.next();
                bw.write(str);  //缓冲流输出
                bw.newLine();    //另起一行
                System.out.println("是否继续?y继续");
                c = in.next();
            } while (c.equals("y"));
            writ.flush();  //清空缓存
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

字节输入输出流应用

字节流主要是操作byte类型数据,以byte数组为准,主要操作类时,字节输入流InputStream,字节输出流OutputStream.

一.字节的输入输出流

TestStream.java

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;

/**
 * 字节读写文件
 * 字节输入流:InputStream
 * 字节输出流:OutputStream
 */
public class TestStream {

	/**
	 * 单个字节读取文件中的内容
	 */
	@Test
	public void inSingle() {
		//实例化输入流对象
		try(InputStream in = new FileInputStream("D:"+File.separator+"IO"+File.separator+"File"+File.separator+"test1.txt");) {
			int b = 0;
			while((b=in.read())!=-1) {
				System.out.print((char)b);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 多个字节读取文件中的内容
	 */
	@Test
	public void inDuo() {
		try(InputStream in = new FileInputStream("D:"+File.separator+"IO"+File.separator+"File"+File.separator+"test1.txt");) {
			byte[] b = new byte[10];
			int len = 0;
			while((len=in.read(b))!=-1) {
				System.out.print(new String(b,0,len));   //读取数组中输入流读出的长度
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 向文件中写入内容
	 */
	@Test
	public void outStream() {
		try(OutputStream out = new FileOutputStream("D:"+File.separator+"IO"+File.separator+"File"+File.separator+"test1.txt",true)){
			String str = "alsjdflakdsjlkfnkladoshflsakdjfklads阿萨德很反感卡萨丁喝奶粉";
			//将字符串转换为字节数组输出
			out.write(str.getBytes()); 
			out.flush();  
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
}

二.字节流的复制粘贴

copy.java

package zuoye;

import org.junit.Test;
import java.io.*;

public class copy {

    /**
     * 复制粘贴视频
     */
    @Test
    public void CopyVideo() {
        String path = "D:\\java\\video.wmv";
        try (InputStream in = new FileInputStream(path);
             OutputStream out = new FileOutputStream("D:" + File.separator + "java" + File.separator + "new" + File.separator + "video1.wmv");
        ) {
            byte[] b = new byte[1024];
            int len = 0;
            while ((len = in.read(b)) != -1) {
                out.write(b, 0, len);
            }
            out.flush();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 复制粘贴图片
     */
    @Test
    public void CopyPicture() {
        String path = "D:\\java\\1.PNG";
        try (InputStream in = new FileInputStream(path);
             OutputStream out = new FileOutputStream("D:" + File.separator + "java" + File.separator + "new" + File.separator + "11.PNG");
        ) {
            byte[] b = new byte[1024];
            int len = 0;
            while ((len = in.read(b)) != -1) {
                out.write(b, 0, len);
            }
            out.flush();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 复制粘贴PPT
     */
    @Test
    public void CopyPPT() {
        String path = "D:\\java\\IO流.pptx";
        try (InputStream in = new FileInputStream(path);
             OutputStream out = new FileOutputStream("D:" + File.separator + "java" + File.separator + "new" + File.separator + "IO流2.pptx");
        ) {
            byte[] b = new byte[1024];
            int len = 0;
            while ((len = in.read(b)) != -1) {
                out.write(b, 0, len);
            }
            out.flush();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

三.字节缓冲流

TestBuffered.java

import org.junit.Test;

import java.io.*;

public class TestBuffered {

    /**
     * 字节输入输出流
     */
    @Test
    public void copy() {
        String path = "D:\\IO\\1.jpg";
        long start = System.currentTimeMillis(); //开始时间
        try (InputStream in = new FileInputStream(path);
             OutputStream out = new FileOutputStream("D:" + File.separator + "IO" + File.separator + "File" + File.separator + "che.jpg");
        ) {
            int len = 0;  //字节编号
            while ((len = in.read()) != -1) {
                out.write(len);
            }
            out.flush();
            long end = System.currentTimeMillis();//结束时间
            System.out.println("所用时间:" + (end - start));//356248
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    /**
     * 字节缓冲流
     */
    @Test
    public void biffererCopy(){
        String path = "D:\\IO\\1.jpg";
        long start = System.currentTimeMillis(); //开始时间
        //字节缓冲流,在读取内容过程中,在缓冲流中进行组装
        try(BufferedInputStream bis = new BufferedInputStream(new FileInputStream(path));
            BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("D:" + File.separator + "IO" + File.separator + "File" + File.separator + "haoche.jpg"))
        ) {
            int val = 0;  //字节编号
            while ((val=bis.read())!=-1) {
                bos.write(val);
            }
            bos.flush();
            long end = System.currentTimeMillis();//结束时间
            System.out.println("所用时间:" + (end - start));//300
        }catch (Exception e){
            e.printStackTrace();
        }
    }
    
}

总结

本文主要讲解了Java IO流,希望浏览文章的读者们能够通过该文章有所提升。

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 1024 设计师:白松林 返回首页