Java---IO流(一)

IO流:

​ 大多数应用程序都需要实现与设备之间的数据传输, 对于任何程序设计语言而言,输入输出(Input/Output)系统都是非常核心的功能。在Java中,将这种通过不同输入输出设备(键盘,内存,显示器,网络等)之间的数据传输抽象表述为“流”,程序允许通过流的方式与输入输出设备进行数据传输。Java中的“流”都位于java.io包中,称为IO(输入输出)流。

​ IO流有很多种,按照操作数据的不同,可以分为字节流和字符流,按照数据传输方向的不同又可分为输入流和输出流,程序从输入流中读取数据,向输出流中写入数据。

流的分类:

  • 按数据单位分为:字节流(8bit),字符流(16bit);
  • 按数据流向不同分为:输入流,输出流;
  • 按流的角色不同分为:节点流,处理流;

image-20210405171951455

下面为几个常用流:

字节流(输入) 字节流(输出) 字符流(输入) 字符流(输出)
基本流 InputStream OutpuStream Reader Writer
访问文件 FileInputStream FileOutputStream FileReader FileWriter
缓冲流 BufferedInputStream BufferedOutputStream BufferedReader BufferedWriter
转换流 InputStreamReader OutputStreamWriter
对象流 ObjectInputStream ObjectOutputStream

在计算机中,无论是文本、图片、音频还是视频,所有文件都是以二进制(字节)形式存在的,IO流中针对字节的输入输出提供了一系列的流,统称为字节流。在JDK中,提供了两个抽象类InputStream和OutputStream,它们是字节流的顶级父类,所有的字节输入流都继承自InputStream,所有的字节输出流都继承自OutputStream。为了方便理解,可以把InputStream和OutputStream比作两根“水管”,如图所示:

image-20210406004038515

在JDK中,InputStream和 OutputStream提供了一系列与读写数据相关的方法,

InputStream方法,如下图所示:

image-20210406004111964

OutputStream方法,如下图所示:

image-20210406004236573

在程序中操作字符,可以使用字符流,分别是Reader和Writer。其中Reader是字符输入流,用于从某个源设备读取字符,Writer是字符输出流,用于向某个目标设备写入字符。Reader和Writer作为字符流的顶级父类,也有许多子类:

image-20210406005043759

如果想从文件中直接读取字符便可以使用字符输入流FileReader,通过此流可以从关联的文件中读取一个或一组字符。

如果想对文件进行字符的写出可以使用字符写出流FileWriter。

File类

​ File类用于封装一个路径,这个路径可以是从系统盘符开始的绝对路径,也可以是相对于当前目录而言的相对路径。在File类中提供了针对这些文件或目录的一些常规操作。接下来首先介绍一下File类常用的构造方法,如表所示:(三种实现File的方式:)

image-20210405174526690

        File file1 = new File("G:\\java\\javaSE\\数据类型");			//类型一
        File file2 = new File("G:\\java\\javaSE","数据类型");			//类型二
        File file3 = new File(file2,"数据类型");						//类型三

File类中提供了一系列方法,用于操作其内部封装的路径指向的文件或者目录,例如判断文件/目录是否存在、创建、删除文件/目录等。

image-20210405174821025

        File f = new File("D:\\a.txt");
        f.createNewFile();
        f.renameTo(new File("D:\\aa.txt"));       
		//将文件重命名   注意:将一个file()传到另外一个file()时,要保证第二个file不存在。

        System.out.println(System.getProperty("user.dir"));
        File f = new File("aa.txt");

        System.out.println("判断File是否存在:---" + f.exists());
        System.out.println("判断File是否为目录:---" + f.isDirectory());
        System.out.println("判断File是否为文件:---" + f.isFile());
        System.out.println("判断File是否为可读文件:---" +f.canRead());
        System.out.println("判断File是否为可写文件:---" +f.canWrite());
        System.out.println("判断File是否为隐藏文件:---" +f.isHidden());
        System.out.println("返回最后修改的时间:---" + new Date(f.lastModified()));
        System.out.println("返回文件的大小:---" + f.length());
        System.out.println("返回文件名:---" + f.getName());
        System.out.println("返回文件的目录绝对路径:---" + f.getAbsolutePath());
        System.out.println("获取文件上层目录:---" +f.getParent());

创建指定路径下的文件:createNewFile(),删除文件:delete(),创建目录:mkdir():

//        f.createNewFile();    //创建f对应路径的文件,如果文件存在则不能创建,返回false
//        f.delete();           //删除对应路径的文件,如果文件不存在则不能删除。目录下不能有文件
//        f.mkdir();            //创建对应路径的文件目录,如果文件上层目录不存在,则不能创建。
//        f.mkdirs();           //创建对应路径的文件目录,如果文件上层目录不存在,会一并创建。

遍历目录下的文件:使用list()方法,该方法用于遍历某个指定目录下的所有文件的名称: list()listFiles()

        File file = new File("D:\\JavaFile文件目录\\Java文件");
        file.createNewFile();
        String[] list = file.list();        //获取当前目录下的所有文件或目录的名字的数组
        for (String i : list) {
            System.out.println(i);
            }
        System.out.println("********************");
        File[] files = file.listFiles();      //获取当前文件目录的所有绝对路径的数组
        for (File j : files) {
            System.out.println(j);
        }

我们还可以将文件重命名 。 注意:重命名是将一个file()传到另外一个file(),要保证第二个file不存在。也就是修改的名字不能已经存在。

        File f = new File("D:\\a.txt");				//a.txt
        f.createNewFile();
        f.renameTo(new File("D:\\aa.txt"));      //将文件重命名
		System.out.println(f.getName());		//aa.txt	

再window中,我们再路径中每个\都要再加上\进行转义,如:D:\\a.txt。除此之外还可以使用File.separator 代替\

 File file = new File("D:" + File.separator + "JavaFile文件目录"
                + File.separator +"Java文件");		
//上面中的File.separator等同于"\\"

File基本流

​ 基本字节流:InputSteam()和OutputStream();

​ 基本字符流:Reader()和Writer();

这些基本文件流都可以对文件简单的输出写入的操作,但是一般都会使用访问文件流来操作。

对于IO文件流的基本步骤解析:

  • 提供具体的流;
  • 实例化流的对象;
  • 数据读写操作;(字符流read()返回读入的一个字符,达到末尾时为-1);
  • 关闭使用的流;

文件字节流&文件字符流

​ 文件字节流一般使用的是FileInputStream()FIleOutputStream()

  • FileInputStream():通过字节的方式读取文件,适合读取所有类型的文件(图像、视频、文本文件等)。

  • FIleOutputStream():通过字节的方式写数据到文件中,适合所有类型的文件。

  • 文件字节流中也可以使用Reader()和Writer()的方法;

使用文件字节流对.txt文件进行读取:

  • 使用字节流对.txt文件进行读取在控制台输出有可能出现乱码的情况;
  • 使用字节流对.txt文件进行读取再写入到数据文件中,则不会出现乱码的情况。
 		FileInputStream fi = null;
        try {
            File file = new File("src\\IOstream\\text2.txt");
            fi = new FileInputStream(file);
            byte[] bytes = new byte[5];
            int leng;
            while ((leng = fi.read(bytes)) != -1) {
               String str = new String(bytes,0,leng);
                System.out.print(str);					//输出.txt文件,可能出现乱码
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (fi != null)
                    fi.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

使用字节流对图片复制:

       	FileInputStream fi = null;
        FileOutputStream fo = null;
        try {
            File file1 = new File("src\\IOstream\\img1.jpg");
            File file2 = new File("src\\IOstream\\img2.jpg");

            fi = new FileInputStream(file1);
            fo = new FileOutputStream(file2);

            byte[] bytes = new byte[10];
            int leng;
            while ((leng = fi.read(bytes)) != -1){
               fo.write(bytes,0,leng);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (fi != null)
                    fi.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (fo != null)
                    fo.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

注意:1、为了提高效率,通常设置缓存数组。相应地,读取时使用的方法为:read(byte[] b);写入时的方法为:write(byte[ ] b, int off, int length)

​ 2、如果程序中有多个流,那么每个流都要关闭,防止其中一个流出现问题导致后面也出现问题。

文件字符流一般使用FileReader()FileWriter()

上面讲过使用文件字节流来处理文本文件,可能会出现乱码的情况。但是使用文件字符流来处理文本就不会出现乱码的情况了。所以,处理文本文件一般都会使用字符流来处理。

//对文本文件就行读取操作:	
	FileReader fr = null;
    try {
        File file = new File("src\\IOstream\\text1.txt");        //提供具体的流
        fr = new FileReader(file);                               //实例化file对象
        char[] cbuf = new char[5];                               //使用read()数字类型
        int leng;
        
        while ((leng = fr.read(cbuf)) != -1) {
            for (int i = 0; i < cbuf.length; i++) {
                System.out.print(cbuf[i]);
            }
        }
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if (fr != null)
            try {
                fr.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
    }

使用FileWrite类型:文件可以不存在,不存在时会自动创建。
实例化FileWrite有两种情况:1)FileWrite(file,true)----->允许在原有文件里插入数据,不会覆盖原有数据;
2) FileWrite(file,false)----->不允许在原有文件里插入数据,添加的数据将会

覆盖原有数据。

//从文件中读取数据,再写出到另外一个文件中去:		
        FileReader fr = null;
        FileWriter fw = null;
        try {
            File file1 = new File("src\\IOstream\\text1.txt");
            File file2 = new File("src\\IOstream\\text3.txt");

            fr = new FileReader(file1);
            fw = new FileWriter(file2);

            char[] cbuf = new char[5];
            int leng;
            while ((leng = fr.read(cbuf)) != -1) {
                fw.write(cbuf,0,leng);
                }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
                try {
                    if (fw != null)
                        fw.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            try {
                if (fw != null)
                    fw.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
posted @ 2021-04-17 00:20  VXZX  阅读(148)  评论(0)    收藏  举报