Java IO(File、字节输入输出流、字符输入输出流、打印流)附带相关面试题

简介: 1.File类,2.字节输入输出流(InputStream Outputstream),3.Writer与Reader字符输入输出流,4.打印流



1.File类

file类专门用于管理file文件的,比如文件的创建,删除,修改名称等等

以下是File类的常用方法:

方法 描述
exists() 判断文件或目录是否存在
canRead() 判断文件是否可读
canWrite() 判断文件是否可写
isFile() 判断路径是否表示一个文件
isDirectory() 判断路径是否表示一个目录
getName() 获取文件或目录的名称
getParent() 获取文件或目录的父级路径
getPath() 获取文件或目录的路径
isAbsolute() 判断路径是否为绝对路径
lastModified() 获取文件或目录的最后修改时间
length() 获取文件的大小
mkdir() 创建目录
mkdirs() 创建目录及其父目录
createNewFile() 创建新文件
delete() 删除文件或目录
renameTo() 重命名文件或目录
list() 返回目录下的文件和目录列表
listFiles() 返回目录下的文件和目录数组
getAbsolutePath() 获取文件或目录的绝对路径

文件路径需要掌握File.separator分隔符相当于"\\",为什么要有这个东西呢?因为在不同的操作系统中路径的分隔符并不一样,由此出现File.separator,会根据自己的系统自动转换相应的分隔符

1.使用案例:在一个路径上,如果存在一个文件java.txt,则将其删除,如果不存在则创建一个文件java.txt,再将其名字改为java.html并且输出上次的修改日期

package Example1605;
import java.io.File;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
public class javaDemo {
    public static void main(String[] args)throws Exception {
        File file = new File("E:"+File.separator+"jiawa"+File.separator+"java.txt");
//        判断文件是否存在
        if (file.exists()){
            file.delete();
        }else {
//            创建文件
            file.createNewFile();
//            实现文件改名
            String newName = file.getName().substring(0,file.getName().lastIndexOf('.'))+".html";
            File newFile = new File(file.getParentFile(),newName);
            file.renameTo(newFile);
//            上次修改日期
            System.out.println(new Date(file.lastModified()));
        }
    }
}

image.gif

image.gif编辑

2.通过递归实现输出C盘所有文件内容

package Example1601;
import java.io.File;
public class javaDemo {
    public static void main(String[] args) {
        int count = 0;
       File file =  new File("C:"+ File.separator);
       list(file,count);
        System.out.println(count);
    }
    public static void list(File file,int count){
//        判断是否目录如果是则深入目录
        if (file.isDirectory()){
            File result[] = file.listFiles();
//            判断目录里面是否有内容没有就跳过,有则继续深入
            if (result!=null){
                for (int i=0;i< result.length;i++){
                    list(result[i],count++);
                }
            }
        }
    }
}

image.gif

*面试题Files的常用方法都有哪些?

exist、createFile、createDirectory、write、read、copy、size、delete、move


2.字节输入输出流(InputStream Outputstream)

字节输入输出流的最基本单位是byte字节,注意InputStream和OutputStream都是抽象类,所以实例化对象分别是其子类FileInputStream(File file)与FileOutputStream(File file)

首先介绍OutoutStream字节输出流的常用方法:

方法 描述
write(byte[] buffer) 将byte数组中的数据写入输出流
write(byte[] buffer, int off, int len) 将byte数组中指定范围的数据写入输出流
write(int b) 将单个字节写入输出流
flush() 刷新输出流,确保所有缓冲区中的数据都被写出
close() 关闭输出流,并释放相关资源

InputStream的常用方法:

方法 描述
read() 读取输入流中的下一个字节
read(byte[] buffer) 将输入流中的数据读入到byte数组中
read(byte[] buffer, int off, int len) 将输入流中的数据读入到指定范围的byte数组中
skip(long n) 跳过并丢弃输入流中的n个字节
available() 返回可以从输入流中读取(或跳过)的字节数
close() 关闭输入流,并释放相关资源

案例代码:

实现在java.txt中通过OutputStream的wirte函数实现第一次覆盖内容实现输入Hello,第二次实现追加在Hello后面加入World

package Example1603;
import java.io.*;
import java.nio.charset.StandardCharsets;
public class javaDemo {
    public static void main(String[] args)throws Exception {
//        确保路径有效可以对其进行判定此处暂略
        File file =  new File("E:"+File.separator+"jiawa"+File.separator+"java.txt");
//        正常情况下
        OutputStream out = new FileOutputStream(file);
        out.write("Hello".getBytes(StandardCharsets.UTF_8));
        out.close();
//        通过构造方法设置true实现文件内容追加
        OutputStream outer = new FileOutputStream(file,true);
        outer.write("World".getBytes(StandardCharsets.UTF_8));
        outer.close();
//        输出文件内容
        InputStream input = new FileInputStream(file);
        byte[] data = new byte[1024];
        int len =  input.read(data);
        System.out.println(new String(data,0,len));
    }
}

image.gif

image.gif编辑

注意在创建实例化对象执行完函数后都要进行close();除非使用AutoCloseable接口

案例2:在刚才基础上读取时候跳过Hello

package Example1604;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
public class javaDemo {
    public static void main(String[] args)throws Exception {
        File file =  new File("E:"+File.separator+"jiawa"+File.separator+"java.txt");
        InputStream input = new FileInputStream(file);
        byte[] data =new byte[1024];
        input.skip(5);
        int len = input.read(data);
        System.out.println(new String(data,0,len));
        input.close();
    }
}

image.gif


3.Writer与Reader字符输入输出流

1.字符输入流与字节输入流有什么区别:

    1. 数据单位:字节流以字节为单位进行输入和输出,而字符流以字符为单位进行输入和输出。字符流可以直接处理Unicode字符,而字节流需要通过字符编码和解码来处理文本数据。
    2. 编码支持:字符流默认使用平台默认的字符编码(如UTF-8),并提供了更多的字符编码支持(如UTF-16、ISO-8859-1等)。字节流不关心编码,只是原样传输字节数据。
    3. 数据处理:字符流提供了更高级别的数据处理功能,能够方便地读取和写入文本数据,包括按行读取、字符缓冲等操作。字节流主要用于二进制数据的读写,处理相对底层。
    4. 效率:由于字符流需要进行字符编码和解码,所以在处理大量数据时可能会比字节流略慢。对于文本数据的处理,字符流的效率通常比较高。

    综上所述,字符流更适合处理文本数据,提供了更多的字符编码支持和便捷的高级功能;而字节流适用于处理二进制数据,更为底层和灵活。选择使用哪种流类型取决于具体的输入/输出需求和数据类型。

    2.Writer与Reader也都是抽象类,所以实例化的时候需要向上转型为其子类,FileWriter与FileReader

    Writer的常用方法:

    方法 描述
    write(int c) 将指定字符写入输出流
    write(char[] cbuf) 将字符数组的所有字符写入输出流
    write(String str) 将字符串中的所有字符写入输出流
    write(String str, int off, int len) 将字符串中指定范围的字符写入输出流
    append(CharSequence csq) 将指定的字符序列追加到输出流
    append(CharSequence csq, int start, int end) 将指定范围的字符序列追加到输出流
    flush() 刷新输出流,将缓冲区的数据写入目标设备
    close() 关闭输出流,并释放相关资源

    Reader的常用方法:

    方法 描述
    read() 读取单个字符,返回读取的字符的ASCII码值或-1(如果已达到流的末尾)
    read(char[] cbuf) 将字符读入数组,并返回读取的字符数
    read(char[] cbuf, int off, int len) 将字符读入数组的指定范围,并返回读取的字符数
    read(CharBuffer target) 将字符读入CharBuffer对象中,并返回读取的字符数
    skip(long n) 跳过n个字符的读取
    ready() 判断是否可以读取(准备读取)
    mark(int readAheadLimit) 在当前位置设置一个标记,以供稍后的reset()方法使用
    reset() 将位置重置为最近的标记位置
    close() 关闭输入流,并释放相关资源

    案例代码1:

    package Example1606;
    import java.io.File;
    import java.io.FileWriter;
    import java.io.IOException;
    import java.io.Writer;
    public class javaDemo {
        public static void main(String[] args)throws Exception {
            File file = new File("E:"+File.separator+"jiawa"+File.separator+"java.txt");
            try{
                if (file.exists()){
                    Writer out = new FileWriter(file);
                    out.write("大家好,我系渣渣辉");
    //                Witer的追加是通过函数apend()
                    out.append(",其实我不系了啦");
                    out.close();
                }
            }catch (IOException e){
                e.printStackTrace();
            }
        }
    }

    image.gif

    image.gif编辑

    案例代码2:

    package Example1607;
    import java.io.File;
    import java.io.FileReader;
    import java.io.IOException;
    import java.io.Reader;
    public class javaDemo {
        public static void main(String[] args) {
            File file =new File("E:"+File.separator+"jiawa"+File.separator+"java.txt");
            try {
                Reader read = new FileReader(file);
                char data[] =new char[1024];
                int len = read.read(data);
                System.out.println(new String(data,0,len));
                read.close();
            }catch (IOException e){
                e.printStackTrace();
            }
        }
    }

    image.gif

    面试题java 中 IO 流分为几种?

    (1)按流划分,可以分为输入流和输出流;

    (2)按单位划分,可以分为字节流和字符流;

    字节流:inputStream、outputStream;

    字符流:reader、writer


    4.打印流

    虽然说io中对数据的输出可以通过OutputStream与Writer,但是两者都有一定的限制,比如OutputStream只允许输出字节数据,Writer只允许输出字符数据和字符串数据,在实际的开发过程会有多种数据类型的输出就引出了PrintWriter

    下面介绍PrintWriter的常用方法:

    void print(boolean x) 将boolean值打印到输出流。
    void print(char x) 将字符打印到输出流。
    void print(int x) 将整数打印到输出流。
    void print(long x) 将长整数打印到输出流。
    void print(float x) 将浮点数打印到输出流。
    void print(double x) 将双精度浮点数打印到输出流。
    void print(char[] x) 将字符数组打印到输出流。
    void print(String x) 将字符串打印到输出流。
    void println() 打印一个换行符。
    void println(boolean x) 打印boolean值,并在结尾添加换行符。
    void println(char x) 打印字符,并在结尾添加换行符。
    void println(int x) 打印整数,并在结尾添加换行符。
    void println(long x) 打印长整数,并在结尾添加换行符。
    void println(float x) 打印浮点数,并在结尾添加换行符。
    void println(double x) 打印双精度浮点数,并在结尾添加换行符。
    void println(char[] x) 打印字符数组,并在结尾添加换行符。
    void println(String x) 打印字符串,并在结尾添加换行符。
    void format(String format, Object... args) 使用指定格式将参数写入输出流。
    void write(char[] buf, int off, int len) 将字符数组的一部分写入输出流。
    void flush() 刷新输出流,即将缓冲区的内容写入目标设备。
    void close() 关闭输出流,释放相关资源。

    1.通过打印一个print.txt内容为:

    姓名:黄小龙

    年龄15

    案例代码:

    package Example08;
    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.PrintWriter;
    public class javaDemo {
        public static void main(String[] args) {
            File file =  new File("E:"+File.separator+"jiawa"+File.separator+"print.txt");
            if (!file.exists()){
                try {
                    file.createNewFile();
                    PrintWriter w = new PrintWriter(new FileOutputStream(file));
                    w.println("姓名:黄小龙");
                    w.print("年龄");
                    w.println(15);
    //                释放资源
                    w.close();
                }catch (IOException e){
                    e.printStackTrace();
                }
            }
        }
    }

    image.gif

    image.gif编辑

    构造方法PrintWriter(File file)与PrintWriter(FileOutputStream out)有什么区别:

    `PrintWriter(File file)` 和 `PrintWriter(FileOutputStream out)` 都创建了一个新的 `PrintWriter` 对象,用于写入字符流。它们的区别在于它们的构造函数参数类型不同。

    `PrintWriter(File file)` 构造函数接受一个 `File` 对象作为参数,表示要写入的文件。当您使用这个构造函数创建一个 `PrintWriter` 对象时,它将自动为您创建一个 `FileOutputStream` 对象并将其与您指定的文件关联。这意味着您可以直接向 `PrintWriter` 对象写入字符,而不必手动创建 `FileOutputStream` 对象。

    例如,以下代码使用 `PrintWriter(File file)` 构造函数创建一个新的 `PrintWriter` 对象,并将其用于向 `example.txt` 文件写入字符:

    ```java

    File file = new File("example.txt");

    PrintWriter writer = new PrintWriter(file);

    writer.println("Hello, world!");

    writer.close();

    ```

    相比之下,`PrintWriter(FileOutputStream out)` 构造函数接受一个 `FileOutputStream` 对象作为参数,表示要与该对象关联的输出流。如果您已经有一个 `FileOutputStream` 对象,并且希望将其用作 `PrintWriter` 对象的输出流,可以使用这个构造函数。

    例如,以下代码创建一个新的 `FileOutputStream` 对象,并将其用作 `PrintWriter` 对象的输出流:

    ```java

    FileOutputStream outputStream = new FileOutputStream("example.txt");

    PrintWriter writer = new PrintWriter(outputStream);

    writer.println("Hello, world!");

    writer.close();

    ```

    总之,这两种构造函数都可以用于创建一个 `PrintWriter` 对象,但是它们的参数类型不同,并且在用法上略有不同。


    目录
    相关文章
    |
    3月前
    |
    缓存 Java API
    Java 面试实操指南与最新技术结合的实战攻略
    本指南涵盖Java 17+新特性、Spring Boot 3微服务、响应式编程、容器化部署与数据缓存实操,结合代码案例解析高频面试技术点,助你掌握最新Java技术栈,提升实战能力,轻松应对Java中高级岗位面试。
    334 0
    |
    4月前
    |
    缓存 Java 关系型数据库
    2025 年最新华为 Java 面试题及答案,全方位打造面试宝典
    Java面试高频考点与实践指南(150字摘要) 本文系统梳理了Java面试核心考点,包括Java基础(数据类型、面向对象特性、常用类使用)、并发编程(线程机制、锁原理、并发容器)、JVM(内存模型、GC算法、类加载机制)、Spring框架(IoC/AOP、Bean生命周期、事务管理)、数据库(MySQL引擎、事务隔离、索引优化)及分布式(CAP理论、ID生成、Redis缓存)。同时提供华为级实战代码,涵盖Spring Cloud Alibaba微服务、Sentinel限流、Seata分布式事务,以及完整的D
    201 1
    |
    4月前
    |
    算法 架构师 Java
    Java 开发岗及 java 架构师百度校招历年经典面试题汇总
    以下是百度校招Java岗位面试题精选摘要(150字): Java开发岗重点关注集合类、并发和系统设计。HashMap线程安全可通过Collections.synchronizedMap()或ConcurrentHashMap实现,后者采用分段锁提升并发性能。负载均衡算法包括轮询、加权轮询和最少连接数,一致性哈希可均匀分布请求。Redis持久化有RDB(快照恢复快)和AOF(日志更安全)两种方式。架构师岗涉及JMM内存模型、happens-before原则和无锁数据结构(基于CAS)。
    112 5
    |
    4月前
    |
    安全 Java API
    2025 年 Java 校招面试常见问题及详细答案汇总
    本资料涵盖Java校招常见面试题,包括Java基础、并发编程、JVM、Spring框架、分布式与微服务等核心知识点,并提供详细解析与实操代码,助力2025校招备战。
    197 1
    |
    4月前
    |
    算法 Java 微服务
    2025 年 Java 面试宝典社招春招秋招实操全方位攻略
    2025年Java面试宝典涵盖核心技术及最新趋势,分为四大板块:1. Java基础:深入数据类型、多态等特性,结合学生信息管理等实例;2. JVM核心:解析内存模型与GC算法,附多线程转账等场景应用;3. 高并发方案:详解synchronized与线程池配置,提供Web服务器优化案例;4. Spring生态:剖析IoC/AOP原理,演示微服务架构实现。特别新增Java 17+特性实操,包括Record类、密封接口等语法糖,整合Spring Boot 3、响应式编程及云原生技术,通过订单状态机、API网关配置。
    261 1
    |
    4月前
    |
    缓存 算法 NoSQL
    校招 Java 面试高频常见知识点深度解析与实战案例详细分享
    《2025校招Java面试核心指南》总结了Java技术栈的最新考点,涵盖基础语法、并发编程和云原生技术三大维度: 现代Java特性:重点解析Java 17密封类、Record类型及响应式Stream API,通过电商案例演示函数式数据处理 并发革命:对比传统线程池与Java 21虚拟线程,详解Reactor模式在秒杀系统中的应用及背压机制 云原生实践:提供Spring Boot容器化部署方案,分析Spring WebFlux响应式编程和Redis Cluster缓存策略。
    91 0
    |
    4月前
    |
    Java API 微服务
    2025 年 Java 校招面试全攻略:从面试心得看 Java 岗位求职技巧
    《2025年Java校招最新技术要点与实操指南》 本文梳理了2025年Java校招的核心技术栈,并提供了可直接运行的代码实例。重点技术包括: Java 17+新特性(Record类、Sealed类等) Spring Boot 3+WebFlux响应式编程 微服务架构与Spring Cloud组件 Docker容器化部署 Redis缓存集成 OpenAI API调用 通过实际代码演示了如何应用这些技术,如Java 17的Record类简化POJO、WebFlux构建响应式API、Docker容器化部署。
    149 5
    JAVA高频面试题目集锦(6)
    JAVA高频面试题目集锦(6)
    227 0
    JAVA高频面试题目集锦(6)
    |
    存储 安全 Java
    JAVA高频面试题目集锦(5)
    JAVA高频面试题目集锦(5)
    235 0
    JAVA高频面试题目集锦(5)