【Java IO】1、Java IO入门

目录

一、文件

1、构造器

2、文件操作

二、Java IO

1、I/O 和 Stream

2、I/O流的分类


一、文件

Java I/O操作最常见的就是文件了。文件,可以理解为是一种外部设备,是记录或汇聚数据的地方。当然Java的世界里,文件对应的是java.io包下File类,文件本质上是数据,或是路径的抽象。

1、构造器

File类的构造器是用来创建文件对象的,大致有以下三种方式:

// 1:全路径(常用)
String path="D:\\ADC\\xxx.txt";
File file1 = new File(path);
// 2:URL(常用)
Stirng URL="";
File file2 = new file(URL); // 不同操作系统的路径表示不同
// 3:父路径+子路径
File file3 = new file("D:\\ADC\\","xxx.txt"); // 父路径为String
File file4 = new file(new File("D:\\ADC\\"),"xxx.txt"); // 父路径为File

2、文件操作

文件常见的操作方式有:(可以参考File类的相关API)

  • 文件类型判断(比如:可读,可写,可执行,是否为隐藏文件、存在、目录、文件等)
  • 文件路径API(绝对路径,相对路径等)

文件路径有关的测试:getPath方法、getAbsolutePath方法、getCanonicalPath方法

// 测试绝对路径
File file3 = File.createTempFile("2020-12-09-", ".log"
        , new File("E:\\test\\filetest"));
logger.info("------getPath------》" + file3.getPath());
logger.info("------getAbsolutePath------》" + file3.getAbsolutePath());
logger.info("------getCanonicalPath------》" + file3.getCanonicalPath());

结果:

全部为绝对路径

// 测试相当路径 .
File file4 = File.createTempFile("yesterday", ".log", new File(".\\src\\main\\resources\\templates"));
logger.info("------getPath------》" + file4.getPath());
logger.info("------getAbsolutePath------》" + file4.getAbsolutePath());
logger.info("------getCanonicalPath------》" + file4.getCanonicalPath());
logger.info("------getParent------》" + file4.getParent());

结果:

  1. getPath方法获取的构造器指定的路径;
  2. getAbsolutePath方法获取的是user.id + getPath方法的结果;
  3. getCanonicalPath方法则是在getAbsolutePath方法基础上做了路径的规范,去除.。

// 测试相对路径 ..
// 全路径为:E:\test\filetest\abc\rs.txt
File file5 = new File("..\\abc\\rs.txt");
logger.info("------getPath------》" + file5.getPath());
logger.info("------getAbsolutePath------》" + file5.getAbsolutePath());
logger.info("------getCanonicalPath------》" + file5.getCanonicalPath());
logger.info("------getParent------》" + file5.getParent());

结果:

  1. getPath方法获取的构造器指定的路径;
  2. getAbsolutePath方法获取的是user.id + getPath方法的结果;
  3. getCanonicalPath方法则是在getAbsolutePath方法基础上做了路径的规范,去除..。
  • 目录/文件的CRUD操作、权限设置等(文件/目录的创建,删除,遍历,设置可读可写可执行等权限)
public static void main(String[] args) throws IOException {
    // 创建目录
    File dir = new File("E:\\Pock");
    if (!dir.exists()) {
        System.out.println("目录不存在,正在创建...");
        dir.mkdir();
    }
    // 创建文件
    File file = new File("E:\\Pock\\1.txt");
    if (!file.isFile()) {
        System.out.println("文件不存在,正在创建...");
        file.createNewFile();
    }
    // 删除目录/文件
    file.delete();
//    file.deleteOnExit();//JVM关闭时删除
    dir.delete();

    // 创建临时文件:为了避免出错,不指定文件路径
    File tempFile = File.createTempFile("222", ".tt");
    if (tempFile.exists()) {
        System.out.println("临时文件已创建!");
    }
    tempFile.delete();
    if (!tempFile.exists()) {
        System.out.println("临时文件已被删除!");
    }

// 文件遍历测试:带有文件名称过滤器的list() 或 listFiles()
// 网易云音乐的安装目录
    File dirM = new File("D:\\WangYi Software\\云音乐\\CloudMusic");
    File[] dirList = dirM .listFiles(new FilenameFilter() {
        @Override
        public boolean accept(File dir, String name) {
            // 过滤后缀为.exe文件
            if(name.endsWith(".exe"))
                return true;
            return false;
        }
    });  // cloudmusic.exe
    for (int i = 0; i < dirList.length; i++) {
        // 控制前缀为cloudmusic
        if (dirList[i].getName().startsWith("cloudmusic"))
            System.out.print(dirList[i].getName() + "\n");
    }  // cloudmusic_util.exe


    File deepFile = new File("D:\\Pock2\\");
    deepeach(deepFile); 

    File widthFile = new File("D:\\POCK2\\");
    widthForEach(widthFile); 
}

/**
* 深度优先遍历:遍历从根节点开始,先左遍历,再右遍历。
*       利用递归的思想对目录和文件进行遍历。
*/
public static void deepeach(File dir){
    if(!dir.exists()){
        return;  
    }
    File []file=dir.listFiles();
    for (int i = 0; i < file.length; i++) {
        if(file[i].isFile()){//如果是文件,直接打印出来
             System.out.println("file is:"+file[i].getName());
         }else{//如果是目录
            System.out.println("dir is="+file[i].getName());
            deepeach(file[i]);//递归
        }
    }   
}

/**
*  广度优先遍历:层级输出
*/
public static void widthForEach(File dir){
    //创建队列
    Queue<File> queue=new LinkedList<File>();
    queue.offer(dir);//入队
    while(!queue.isEmpty()){
        //不知道循环多少层级出队入队,所以用while
        File poll = queue.poll();//目录出队
        File[] lf = poll.listFiles();//得到子元素并遍历
        for (File file : lf) {
            if(file.isFile()){
                System.out.println("file is"+file.getName());
            }else{
                System.out.println("dir is"+file.getName());
                queue.offer(file);//下一级目录入队
            }
        }           
    }
}

二、Java IO

1、I/O 和 Stream

I/O:指的是输入Input方式和输出Output方式,是应用程序与外部设备(如文件、内存、管道、网络连接等)之间的数据传递。Stream:流,可理解为一个传输一串串数据的通道,这里的数据是字节或字符,Java中通过流处理I/O的,应用程序从外部设备读取数据时,是通过输入流InputStream实现的,而向外部设备写入数据,则是通过输出流OutputStream实现的。画个图就很容易理解:

当然,流的特点也很明显:FIFO方式(读数据是先进先出的,写数据也是先进先出的),顺序存取(读取的顺序是按写入的顺序来的,除了RandomAccessFile外),只读或只写(即一个流不能同时提供读和写操作)。

2、I/O流的分类

I/O流的分类方式,主要有以下3种:

  • 按数据流的方向:输入流、输出流。
  • 按处理数据单位:字节流、字符流。
  • 按功能:节点流、处理流。

2.1  输入流 和 输出流

比如文件读写,读取文件是输入流,写文件是输出流。

2.2  字节流 和 字符流

二者用法几乎相同,区别在于操作的数据单元不同。字节流操作的数据单元是8位的字节,一般用来处理图像、视频、音频、PPT、Word等类型的文件;字符流操作的数据单元为16位的字符,一般用于处理纯文本类型的文件,如txt文件等,它不能处理图像、音视频等非文本文件。

字节流本身没有缓冲区的,缓冲字节流相对于字节流来说,效率则非常高。而字符流本身带有缓冲区,缓冲字符流的话,相对于字符流效率就不是那么大。

2.3  节点流 和 处理流

节点流,比如 FileInputStream,用来直接操作数据读写,而处理流,比如 BufferedInputStream,则是对也存在的流进行包装,增强强大而灵活的读写能力。处理流可以看作是节点流的一种增强方式,涉及到的设计模式则是包装模式了。

2.4 I/O流的基类及子类

I/O流有四个抽象基类:

  • 字节输入流:InputStream          
  • 字节输出流:OutputStream    
  • 字符输入流:Reader   
  • 字符输出流:Writer

子类的话,总结为以下表格:(红色标记的为基类)

分类

字节输入流

字节输出流

字符输入流

字符输出流

抽象基类

InputStream

OutputStream

Reader

Writer

访问文件

FileInputStream

FileOutputStream

FileReader

FileWriter

访问数组

ByteArrayInputStream

ByteArrayOutputStream

CharArrayReader

CharArrayWriter

访问管道

PipedInputStream

PipedOutputStream

PipedReader

PipedWriter

缓冲流

BufferedInputStream

BufferedOutputStream

BufferedReader

BufferedWriter

转换流

  

InputStreamReader

OutputStreamWriter

对象流

ObjectInputStream

ObjectOutputStream

  

抽象基类

FilterInputStream

FilterOutputStream

FilterReader

FilterWriter

打印流

 

PrintStream

 

PrintWriter

特殊流

DataInputStream

DataOutputStream

  

总结:

Java I/O流的简单入门就是这样,接下来会将结合源码的方式,对不同类型的流进行分析和举例。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值