IO流的基本原理和使用

目录

一:用file来进行文件操作

1.1 file类使用的准备

1.2 File类常用方法-基本文件操作

1.3 File类常用方法-目录操作

 1.4 File类常用方法-文件属性操作

1.5 File类常用方法-其他操作

​ 

 二:流

2.1流的概念

2.2什么是输入输出流

 2.3 什么是字节流,字符流

2.4 字节流

2.4.1         FileInputStream 和 FileOutputStream

2.4.2字节缓冲流 BufferedInputStream 和 BufferedOutputStream

三:字符流

3.1 字符流 FileReader 和 FileWriter

public class FileReader extends InputStreamReader

 3.2 、字符缓冲流 BufferedReader 和 BufferedWriter

四:字节流对比字符流

总结:


一:用file来进行文件操作

1.1 file类使用的准备

java.io.File 类是一个普通的类 , 如果要实例化对象,则常用到两个构造方法 IO流的基本原理和使用_第1张图片

1.2 File类常用方法-基本文件操作

IO流的基本原理和使用_第2张图片

代码1:检验文件是否存在

package com.bittech;
import java.io.File;
public class FileDemo {
    public static void main(String[] args){
        String path = "E:\\java_code\\file\\";
        String name = "demo.txt";
        String pathname = path + name;
        File file = new File(pathname);
        boolean res = file.exists();
        System.out.println("文件" + pathname + "是否存在: " + res);
   }
}

 结果如下:

代码2:检验是否是目录,文件并删除

package com.bittech;
import java.io.File;
public class FileDemo {
    public static void main(String[] args){
        String path = "E:\\java_code\\file\\";
        String name = "demo.txt";
        String pathname = path + name;
        File file = new File(pathname);
        boolean res = file.exists();
        System.out.println("文件" + pathname + "是否存在: " + res);
        res = file.isDirectory();
        System.out.println("文件" + pathname + "是否是目录: " + res);
        res = file.isFile();
        System.out.println("文件" + pathname + "是否是文件: " + res);
        file.delete();
        if(!file.exists()){
            System.out.println("删除文件成功!");
       }
        else{
            System.out.println("删除文件失败!");
       }
   }
}

 结果如下:

IO流的基本原理和使用_第3张图片

 代码3:创建新文件

package com.bittech;
import java.io.File;
import java.io.IOException;
public class FileDemo {
    public static void main(String[] args) throws IOException {
        String path = "E:\\java_code\\file\\";
        String new_name = "demo1.txt";
        String pathname = path + new_name;
        File file = new File(pathname);
        if(!file.exists()){ //注意'!', 表示取反
            try {
                //有创建失败的风险,需要捕捉异常,异常如果不了解,可以先使用,不必关心细节
                file.createNewFile(); 
           }catch (IOException e){ //文件部分异常,常见为IOException
                System.out.println("文件" + pathname + "创建失败");
                //e.printStackTrace();
           }
       }
        else{
            System.out.println("文件" + pathname + "已经存在,不需创建");
       }
   }
}
结果: E:\java_code\file 路径下,新增指定 dome1.txt 文件。可以再次运行,就会看到已经存在的
提示

1.3 File类常用方法-目录操作

IO流的基本原理和使用_第4张图片

代码1:创建指定一个或者多个目录的路径

package com.bittech;
import java.io.File;
import java.io.IOException;
public class FileDemo {
    public static void main(String[] args) throws IOException {
        String path = "E:\\java_code\\file\\";
        String dir_name = "demo_dir"; //想要创建的目录
        //String dir_name = "demo_dir\\dir1\\dir2\\dir3"; //想要创建的目录路径
        String pathname = path + dir_name;
        File file = new File(pathname);
        if(!file.exists()){
            file.mkdir(); //创建一个空目录
            //file.mkdirs(); //创建一个可能具有多个目录的路径
       }
        else{
            System.out.println("路径已经存在,不需创建");
       }
   }
}

 结果:

代码2:获取父路径

package com.bittech;
import java.io.File;
import java.io.IOException;
public class FileDemo {
    public static void main(String[] args) throws IOException {
        String path = "E:\\java_code\\file\\";
        String dir_name = "demo_dir\\dir1\\dir2\\dir3";
        String pathname = path + dir_name;
        File file = new File(pathname);
        System.out.println(file.getParent());
   }
}

结果:

代码3:获取父目录 File 对象,并在父目录下,创建文件 demo.java

package com.bittech;
import java.io.File;
import java.io.IOException;
public class FileDemo {
    public static void main(String[] args) throws IOException {
        String path = "E:\\java_code\\file\\";
        String dir_name = "demo_dir\\dir1\\dir2\\demo.java";
        String pathname = path + dir_name;
        File file = new File(pathname);
        File pfile = file.getParentFile(); //获取父目录File对象
        if(!pfile.exists()){//检测路径是否存在,不存在创建
            pfile.mkdirs();
            //获取File对象的绝对路径,后面学,这个先用起来
            System.out.println("路径" + pfile.getAbsolutePath() + "不存在,创建");
       }
        if(!file.exists()){
           file.createNewFile();
       }
   }
}

 结果:

 1.4 File类常用方法-文件属性操作

IO流的基本原理和使用_第5张图片

代码1:获取示例信息

package com.bittech;
import java.io.File;
import java.io.IOException;
import java.util.Date;
public class FileDemo {
    public static void main(String[] args) throws IOException {
        String path = "E:\\java_code\\file\\";
        String name = "demo.txt";//可以替换成你想检测的文件
        String pathname = path + name;
        File file = new File(pathname);
        if(!file.exists()){
            file.createNewFile();
       }
        System.out.println("文件 " + name + "size : " + file.length());
        //Date类我们后面学
        System.out.println("文件 " + name + "最近修改时间: " +  new
Date(file.lastModified()));
   }
}

 结果:

1.5 File类常用方法-其他操作

代码1:列出desktop目录中的全部组成

package com.bittech;
import java.io.File;
import java.io.IOException;
import java.util.Date;
public class FileDemo {
    public static void main(String[] args) throws IOException {
        // 要操作的文件
        File file = new File("C:\\Users\\whb\\Desktop");
        // 保证是个目录且存在
        if (file.exists() && file.isDirectory()) {
            // 列出目录中的全部内容
            File[] result = file.listFiles();
            for (File file2 : result) {
                System.out.println(file2);
           }
       }
   }
}

 二:流

2.1流的概念

流:  Java 中所有数据都是使用流读写的。流是一组有顺序的,有起点和终点的字节集合,是对数据传
输的总称或抽象。即数据在两设备间的传输称为流,流的本质是数据传输,根据数据传输特性将流抽象
为各种类,方便更直观的进行数据操作。
1. 按照流向分:输入流;输出流
2. 按照处理数据的单位分:字节流 (8 位的字节 ) ;字符流 (16 位的字节 ).

2.2什么是输入输出流

输入 就是将数据从各种输入设备(包括文件、键盘等)中读取到内存中。
输出 则正好相反,是将数据写入到各种输出设备(比如文件、显示器、磁盘等)。
例如键盘就是一个标准的输入设备,而显示器就是一个标准的输出设备, 但是文件既可以作为输入设
备,又可以作为输出设备。
IO流的基本原理和使用_第6张图片

 2.3 什么是字节流,字符流

File 类不支持文件内容处理,如果要处理文件内容,必须要通过流的操作模式来完成。
java.io 包中,流分为两种:字节流与字符流
字节流:数据流中最小的数据单元是字节 。 InputStream OutputStream
字符流:数据流中最小的数据单元是字符, Java 中的字符是 Unicode 编码,一个字符占用两个字节
Reader Writer.
Java IO 流的体系结构如图
IO流的基本原理和使用_第7张图片

2.4 字节流

2.4.1         FileInputStream FileOutputStream

FileInputStream 从文件系统中的某个文件中获得输入字节。
FileInputStream 用于读取诸如图像数据之类的原始字节流。
IO流的基本原理和使用_第8张图片

文件输出流是用于将数据写入到输出流 File 或一个 FileDescriptor 。 文件是否可用或可能被
创建取决于底层平台。
特别是某些平台允许一次只能打开一个文件来写入一个 FileOutputStream (或其他文件写入对
象)。 在这种情况下,如果所涉及的文件已经打开,则此类中的构造函数将失败。
IO流的基本原理和使用_第9张图片

2.4.2字节缓冲流 BufferedInputStream BufferedOutputStream

问题一:为什么需要有缓冲流?
答:当我们用 read() 读取文件时,每读一个字节,访问一次硬盘,效率很低 。文件过大时,操作
起来也不是很方便。因此我们需要用到 buffffer 缓存流, 当创建 buffffer 对象时,会创建一个缓冲区
数组。 当我们读一个文件时,先从硬盘中读到缓冲区,然后直接从缓冲区输出即可,效率会更
高。
BufferedInputStream 为另一个输入流添加了功能,即缓冲输入和支持 mark reset 方法的功
能。 当创建 BufferedInputStream 时,将创建一个内部缓冲区数组。
当从流中读取或跳过字节时,内部缓冲区将根据需要从所包含的输入流中重新填充,一次有多个字
节。 mark 操作会记住输入流中的一点,并且 reset 操作会导致从最近的 mark 操作之后读取的所
有字节在从包含的输入流中取出新的字节之前重新读取。
IO流的基本原理和使用_第10张图片

该类实现缓冲输出流。 通过设置这样的输出流,应用程序可以向底层输出流写入字节,而不必为
写入的每个字节导致底层系统的调用。
IO流的基本原理和使用_第11张图片

示例使用 BufferedInputStream BufferedOutputStream 实现文件拷贝:

import java.io.*;
public class TestBufferStreamCopy {
    public static void main(String[] args) throws IOException {
        File file=new File("bit.txt");
        if(!file.isFile()){   return;   }
        BufferedInputStream bfis=new BufferedInputStream(new
FileInputStream(file));
        BufferedOutputStream  bfos=new BufferedOutputStream(new
FileOutputStream("src\\"+file.getName()));//copy到src目录下
        byte bytes[]=new byte[1024];
        int temp=0;      //边读边写
        while ((temp=bfis.read(bytes))!=-1){//读
            bfos.write(bytes,0,temp);   //写
       }
        bfos.flush();
        bfos.close();
        bfis.close();
        System.out.println("copy成功!");
   }
}

 有无缓冲效率的对比(以读为例)

import java.io.*;
public class BufferByte {
    public static void main(String[] args) throws IOException {
        //bit.txt 大小大约为1500KB
        File file=new File("bit.txt");
        //缓冲流
        BufferedInputStream bfis=new BufferedInputStream(new
FileInputStream(file));
        int temp=0;
        long time=System.currentTimeMillis();//获取当前时间至1970-1-1的毫秒数
        while ((temp=bfis.read())!=-1){
            //System.out.print((char) temp);
 }
        time=System.currentTimeMillis()-time;
        bfis.close();
        System.out.println("缓冲流读:"+time+"ms");
        //非缓冲
        FileInputStream fis=new FileInputStream(file);
        temp=0;
        time=System.currentTimeMillis();
        while ((temp=fis.read())!=-1){
            //System.out.print((char) temp);
       }
        time=System.currentTimeMillis()-time;
        fis.close();
        System.out.println("非缓冲区读:"+time+"ms");
   }
}

结果输出:

三:字符流

3.1 字符流 FileReader FileWriter

public class FileReader extends InputStreamReader

如果要从文件中读取内容,可以直接使用 FileReader 子类。
FileReader 是用于读取字符流。 要读取原始字节流,请考虑使用 FileInputStream
IO流的基本原理和使用_第12张图片

如果是向文件中写入内容,应该使用 FileWriter 子类
FileWriter 是用于写入字符流。 要编写原始字节流,请考虑使用 FileOutputStream
IO流的基本原理和使用_第13张图片

 示例使用 FileReader FileWriter 复制文件:

public class CopyFileDemo {
 public static void main(String[] args) throws IOException {
方法 解释
BufferedReader(Reader in) 创建使用默认大小的输入缓冲区的缓冲字符输入
流。
BufferedReader(Reader in, int
sz)
创建使用指定大小的输入缓冲区的缓冲字符输入
流。
方法 解释
BufferedWriter(Writer out) 创建使用默认大小的输出缓冲区的缓冲字符输出流。
BufferedWriter(Writer out, int
sz)
创建一个新的缓冲字符输出流,使用给定大小的输出缓
冲区。
2、字符缓冲流 BufferedReader 和 BufferedWriter
为了提高字符流读写的效率,引入了缓冲机制,进行字符批量的读写,提高了单个字符读写的效率。
BufferedReader 用于加快读取字符的速度, BufferedWriter 用于加快写入的速度。
BufferedReader 和 BufferedWriter 类各拥有 8192个 字符的缓冲区。当 BufferedReader在 读取文
本文件时,会先尽量从文件中读入字符数据并放满缓冲区,而之后若使用read()方法,会先从缓冲区中
进行读取。如果缓冲区数据不足,才会再从文件中读取,使用 BufferedWriter 时,写入的数据并不会
先输出到目的地,而是先存储至缓冲区中。如果缓冲区中的数据满了,才会一次对目的地进行写出。
从字符输入流读取文本,缓冲字符,以提供字符,数组和行的高效读取
将文本写入字符输出流,缓冲字符,以提供单个字符,数组和字符串的高效写入。
示例使用 BufferedReader 和 BufferedWriter 进行文件拷贝
 //创建输入流对象
 FileReader fr = new FileReader("E:\\bit\\bitSrc.java");
 //创建输出流对象
 FileWriter fw = new FileWriter("E:\\bit\\bitCopy.java");
 
 //读写数据
 int ch;
 while((ch=fr.read())!=-1) {
 fw.write(ch);
 } 
 //释放资源
 fw.close();
 fr.close();
 }

 3.2 、字符缓冲流 BufferedReader BufferedWriter

为了提高字符流读写的效率,引入了缓冲机制,进行字符批量的读写,提高了单个字符读写的效率。
BufferedReader 用于加快读取字符的速度, BufferedWriter 用于加快写入的速度。
BufferedReader BufferedWriter 类各拥有 8192 字符的缓冲区。当 BufferedReader 读取文
本文件时,会先尽量从文件中读入字符数据并放满缓冲区,而之后若使用 read() 方法,会先从缓冲区中
进行读取。如果缓冲区数据不足,才会再从文件中读取,使用 BufferedWriter 时,写入的数据并不会
先输出到目的地,而是先存储至缓冲区中。如果缓冲区中的数据满了,才会一次对目的地进行写出。
从字符输入流读取文本,缓冲字符,以提供字符,数组和行的高效读取
IO流的基本原理和使用_第14张图片

将文本写入字符输出流,缓冲字符,以提供单个字符,数组和字符串的高效写入。

IO流的基本原理和使用_第15张图片

示例使用 BufferedReader BufferedWriter 进行文件拷贝  

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class FileWrite {
public static void main(String[] args) throws IOException {
 
 FileReader reader=new FileReader("E:\\BIT\\bit.txt"); 
 BufferedReader bReader=new BufferedReader(reader);
 FileWriter writer=new FileWriter(":\\BIT\\bit2.txt");
 BufferedWriter bWriter=new BufferedWriter(writer);
 String content="";
 //readLine一行一行的读取
 while((content=bReader.readLine())!=null){
 //\r\n换行
 bWriter.write(content+"\r\n");
 }
 /**
  * 关闭流的顺序:
  * 当A依赖B的时候先关闭A,再关闭B
  * 带缓冲的流最后关闭的时候会执行一次flush
  */
 reader.close();
 bReader.close();
 bWriter.close();
 writer.close();
 }
}

四:字节流对比字符流

1 、字节流操作的基本单元是字节;字符流操作的基本单元为 Unicode 码元。
2 、字节流在操作的时候本身不会用到缓冲区的,是与文件本身直接操作的;而字符流在操作的时候使
用到缓冲区的。
3 、所有文件的存储都是字节 (byte) 的存储,在磁盘上保留的是字节。
4 、在使用字节流操作中,即使没有关闭资源( close 方法),也能输出;而字符流不使用 close 方法的
话,不会输出任何内容。

总结:

   码文不易,大家多多支持,望不吝赐教,感激不尽!越来越好!!!

你可能感兴趣的:(Java基础,java)