Java IO详解

一、流的概念

流(stream)的概念源于UNIX中管道(pipe)的概念。在UNIX中,管道是一条不间断的字节流,用来实现程序或进程间的通信,或读写外围设备、外部文件等。

流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象。 一个流,必有源端和目的端。

流机制是Java及C++中的一个重要机制,通过流我们可以自由地控制文件、内存、IO(Input输入/Output输出)设备等数据的流向。而IO流就是用于处理设备上的数据,如:硬盘、内存、键盘录入等。

一个形象的比喻是——水流,文件===程序,文件和程序之间连接一个管道,水流就在管道中形成了,自然也就出现了方向:可以流进,也可以流出

二、流的分类

  • 根据处理数据的单位不同可分为字节流和字符流
  • 根据流向的不同可分为输入流和输出流
  • 根据流的功能可以分为节点流(低级流)和处理流(高级流,也叫过滤流)

IO流

字节流:以字节为单位操作流

  • InputStream
  • OutputStream

字符流:以字符为单位操作流

  • Reader
  • Writer

输入流:从程序角度来看,输入到程序中的流

  • InputStream
  • Reader

输出流:从程序角度来看,从程序中输出的流

  • OutputStream
  • Writer

节点流:直接与数据源相连,操作流

处理流:直接使用节点流,读写不方便,为了更快的读写文件,有了处理流。处理流不直接连接数据源,而是连接在已存在的流(节点流或处理流)上,通过对数据的处理为程序提供更强大的处理能力

三、文件类

java.io包中的File类提供了管理文件与目录的功能,是文件和目录路径名的抽象表示形式。该类也是我们在使用IO流的时候经常会用到的一个类。下面列举类中常用到的方法:

|方法 |说明 ||:--------------|:----------------------------------------------------------||delete() |删除文件或目录,如果此路径名表示一个目录,则该目录必须为空才能删除 ||exists() |判断文件或目录是否存在 ||isFile() |判断是否为文件 ||isDirectory() |判断是否为目录 ||lastModified() |获取最后一次修改时间 ||length() |获得文件的长度 ||list() |返回一个字符串数组,这些字符串指定目录中的文件和子目录 ||listFiles() |返回一个抽象路径名数组,这些路径名表示此目录中的File对象 ||mkdir() |创建此抽象路径名指定的目录 ||mkdirs() |创建此抽象路径名指定的目录,包括所有必需但不存在的父目录 |

更多方法的详细信息,请参考JDK API文档查看

四、如何使用

1. 文件类
import java.io.File;
import java.io.IOException;
import java.util.Date;

/**
 * File类测试
 * @author 小明
 *
 */
public class FileTest {

    public static void main(String[] args) {
        // 创建File对象
        File file = new File("E:\\jg\\exercise_bak.txt");

        // 能否读
        System.out.println("能否读:" + file.canRead());

        // 删除
        System.out.println("删除成功:" + file.delete());

        // 重新创建文件对象
        file = new File("E:\\jg\\exercise_bak.txt");

        // 判断文件是否存在
        System.out.println("是否存在:" + file.exists());

        // 目录或文件名称
        System.out.println("名称:" + file.getName());

        // 是否目录、文件
        System.out.println("是否目录:" + file.isDirectory());
        System.out.println("是否文件:" + file.isFile());

        // 最后一次修改时间
        System.out.println("最后一次修改时间:" + new Date(file.lastModified()));

        // 文件大小
        System.out.println("文件大小:" + file.length());

        // 重新创建File对象
        file = new File("E:\\jg");

        System.out.println("文件目录列表:");
        // 返回一个字符串数组,这些字符串指定此抽象路径名表示的目录中的文件和目录
        String[] list = file.list();
        for (String string : list) {
            System.out.println(string);
        }
        System.out.println("*******************************");

        // 返回一个抽象路径名数组,这些路径名表示此抽象路径名表示的目录中的文件对象
        File[] files = file.listFiles();
        for (File item : files) {
            if (item.isDirectory()) { // 当前File对象为目录,则遍历该目录下所有子目录与文件
                System.out.println(item.getName() + " 目录下子目录与文件:");
                String[] it = item.list();
                for (String i : it) {
                    System.out.println(i);
                }
                System.out.println("*******************************");
                continue;
            }

            System.out.println(item.getName() + "  文件");
        }

        // 重新创建File对象
        file = new File("E:\\jg\\test\\demo\\test.txt");
        if (!file.exists()) { // 文件不存在
            // 获取文件路径
            File dir = file.getParentFile();
            if (!dir.exists()) { // 目录不存在,则创建路径中所有不存在的目录
                dir.mkdirs();
            }

            try {
                // 创建空文件
                System.out.println("文件是否创建成功:" + file.createNewFile());
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }
}
2. 字节流
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

/**
 * 字节输入输出流测试
 * 
 * @author 小明
 *
 */
public class IOTest {

    public static void main(String[] args) {
        StringBuffer buffer = new StringBuffer(); // 字符串缓冲

        /* 输入流 */
        InputStream in = null;

        try {
            // 1. 打开输入流
            in = new FileInputStream("E:\\jg\\exercise.txt");
            // 2. 读取
            byte[] b = new byte[1024 * 4];
            int len = in.read(b); // 返回读取到的字节数,返回-1表示读取到流结尾
            while(len != -1){
                buffer.append(new String(b, 0, len)); // 将读取到的字节解析为String追加到缓冲
                len = in.read(b);
            }
            System.out.println(buffer.toString());
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 3. 释放资源,关闭输入流
            if (in != null){
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        /* 输出流 */
        OutputStream out = null;

        try {
            File file = new File("D:\\test\\demo\\test.txt");
            if (!file.getParentFile().exists()){ // 文件路径不存在,则创建路径中所有不存在的目录
                file.getParentFile().mkdirs();
            }
            // 1. 打开输出流
            out = new FileOutputStream(file);
            // 2. 写
            out.write(buffer.toString().getBytes());
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 3. 释放输出流资源
            if (out != null){
                try {
                    out.flush();
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
3. 字符流
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Reader;
import java.io.Writer;

/**
 * 字符输入输出流测试
 * 
 * @author 小明
 *
 */
public class IOTest2 {

    public static void main(String[] args) {
        StringBuffer buffer = new StringBuffer();

        /* 输入流 */
        Reader reader = null;

        try {
            // 1. 打开流
            reader = new FileReader("E:\\jg\\exercise.txt");
            // 2. 读取
            char[] ch = new char[128]; // 缓冲区
            int len;
            do {
                len = reader.read(ch);
                if (len == -1)
                    break;
                buffer.append(new String(ch, 0, len));
            } while (len != -1);
            System.out.println(buffer.toString());
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 3. 释放资源
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        /* 输出流 */

        Writer writer = null;

        try {
            // 1. 打开流
            writer = new FileWriter("d:\\test.txt");
            // 2. 写入
            writer.write(buffer.toString());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 3. 释放资源
            if (writer != null) {
                try {
                    writer.flush();
                    writer.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

归纳总结

  • 流的使用步骤:

    1. 打开一个输入/输出流对象
    2. 读取或写入数据
    3. 释放资源,关闭输入/输出流对象
  • InputStream和OutputStream主要用来处理可以被直接读作byte的数字

  • Reader和Writer主要用来处理文本
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值