java IO流详细总结(二、字符输入输出流,File文件操作类)

简介: java IO流详细总结(二、字符输入输出流,File文件操作类)

再次回忆一下什么是字节流、字符流:


IO流以单位划分:

字节流:以字节(8bit)为单位,能够传输所有类型的文件。

字符流:以字符为单位,一次可能读多个字节。.只能传输文本文件(能够被记事本打开.java/.txt/.html,并且不改变内容的文件)


只要是处理纯文本数据,就优先考虑使用字符流。 除此之外都使用字节流。

所以字符流顾名思义就是主要操作字符的!


四、字符流的编码问题

字符是我们能读懂的一些文字和符号,但在计算机中存储的却是我们看不懂的byte 字节,那 么在这两者之间的转换规则就需要一个统一的标准,否则就会出现乱码了现象;

那这就存在关于字符编码解码的问题。所以在学习IO的字符流之前我们先了解些常见的编码格式有哪些:

ASCII       128个字符(英文、数字、字符等,可对应ASCII码表) 
ISO8859-1    西欧
GBK          简体中文  
GB-2312    简体中文
BIG5         繁体中文
Unicode  万国码
UTF-8     国际通用

五、java IO字符流对象

1、字符输入流Reader:

执行读操作,将计算机磁盘文件中的内容读入java虚拟机JVM内存中;

Reader 是所有的输入字符流的父类,它是一个抽象类。常用方法如下:

      int read():一次读取一个字符,返回值类型为int,表示读取的字符的整数表现形式
            若没有字符,则返回-1
      int read(char[] c):一次读取多个字符,存储到char数组中
            返回值表示读取到的有效字符个数,若读取不到 则返回-1
      int read(char[] c,int off,int len):
          将读取的字符 存储在char数组中 
          存储的起始下标 off  ,读取的长度 为len

例如使用Reader读取一个文本文件中的信息到控制台的程序如下:

FileReader是Reader的一个子类, 文件字符输入流,用于读取文件中的信息

package test;
import java.io.FileReader;
import java.io.IOException;
/**
 * @author 超伟
 * @date 2019年5月17日  
 * @博客: https://blog.csdn.net/MacWx  
 */
public class testReader {
  /**
   * @param args 
   * @throws IOException 
   */
  public static void main(String[] args) throws IOException {
    //创建字符输入流对象
    FileReader fileReader = new FileReader("file/IO.java");
    //利用死循环遍历该文件中的所有字符,
    //如果遍历到结尾,即没有字符返回-1的时候跳出死循环
    while(true){
      //Reader对象的read()方法,一次读取一个字符,返回值类型为int,表示读取的字符的整数表现形式
      int read = fileReader.read();
      //若没有字符,则返回-1
      if (read == -1) {
        break;//跳出死循环
      }
      //依次在控制台输出遍历到到的文件中的每一个字符
      System.out.print((char)read);
    }
    //关闭IO流资源
    fileReader.close();
  }
}

2、字符输出流Writer:

执行写操作,将java虚拟机JVM内存中的数据按照字符形式写入磁盘(文件)中

Writer:是所有的输出字符流的父类,它是一个抽象类。该抽象类的常用方法如下:

      write(int a): 一次写入一个字符
      write(String s):一次性写入多个字符(字符串)
      write(char[] c):一次写入多个字符,为char数组的元素

例如使用Writer向文件中写入一个字符或者字符串的程序如下

FileWriterr是Writer的一个子类, 文件字符输出流,用于写入磁盘文件中的信息

package test;
import java.io.FileWriter;
import java.io.IOException;
/**
 * @author 超伟
 * @date 2019年5月17日  
 * @博客: https://blog.csdn.net/MacWx  
 */
public class testWriter {
  /**
   * @param args 
   * @throws IOException 
   */
  public static void main(String[] args) throws IOException {
    // TODO Auto-generated method stub
    //创建文件字符输出流对象
    FileWriter fileWriter = new FileWriter("file/test.txt");
    //两参构造第二个参数设为true即为添加操作,不写或false为覆盖
    //FileWriter fileWriter = new FileWriter("file/test.txt",true);
    //向文件中写入一个字符串
    fileWriter.write("今天星期五,\n明天周六不上课,\n啦啦啦啦!!!");
    //关闭流资源
    fileWriter.close();
  }
}

3,桥转换流:字节流和字符流之间相互转换的桥梁

InputStreamReader,将字节输入流转换为字符输入流。是字节流通向字符流的桥梁,可以指定字节流转换为字符流的字符集。

package test;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
public class TestInputStreamReader {
  public static void main(String[] args){
    BufferedReader br = null;
    try{
      //创建字节流
      FileInputStream fileInputStream = new FileInputStream("file/a.txt");
      //创建桥转换流,将字节输入流转换为字符输入流  并且设置 解码方式
      InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream,"UTF-8");
      //包装流
      br = new BufferedReader(inputStreamReader);
      //读操作
      while(true){
        String readLine = br.readLine();
        if(readLine==null) break;
        System.out.println(readLine);
      }
    }catch(IOException e){
      e.printStackTrace();
    }finally{
      if(br!=null){
        //关闭资源
        try {
          br.close();
        } catch (IOException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
        }       
      }     
    }
  }
}

OutputStreamWriter:将字节输出流转为字符输出流,是字节流通向字符流的桥梁,可使用指定的 charset 将要写入流中的字符编码成字节。它使用的字符集可以由名称指定或显式给定,否则将接受平台默认的字符集。

package test;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
public class TestOutputStreamWriter {
  public static void main(String[] args){
    PrintWriter pw = null;
    try{
      //创建一个字节流对象
      FileOutputStream fileOutputStream = new FileOutputStream("file/f.txt");
      //创建桥转换流  字节流---->字符流设置编码格式 :utf-8
      OutputStreamWriter osw = new OutputStreamWriter(fileOutputStream,"UTF-8");
      //包装桥转换流 :增强功能   (写或不写都可以)
      pw = new PrintWriter(osw);
      //写操作
      pw.println(new Student("学生对象name=macw",22));
    }catch(IOException e){
      e.printStackTrace();
    }finally{
      //关闭流
      if(pw!=null){
        pw.close();
      }
    }
  }
}

4,包装流,也叫过滤流、缓冲流。

BufferedReader,字节输入缓冲流,从字符输入流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取。

BufferedReader 由Reader类扩展而来,提供通用的缓冲方式文本读取,而且提供了很实用的readLine。

String readLine() 读取一个文本行,返回值类型为String。若文件到达尾部,返回值为null

package day23;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class TestBufferedReader {
  public static void main(String[] args) throws IOException{
    //创建节点流对象
    FileReader fileReader = new FileReader("file/a.txt");
    //创建过滤流对象  指定要进行包装的节点流
    BufferedReader bufferedReader = new BufferedReader(fileReader);
    //读操作
    while(true){
      String readLine = bufferedReader.readLine();
      if(readLine==null) break;
      System.out.println(readLine);
    }
    //关闭资源
    bufferedReader.close();
  }
}

BufferedWriter(缓冲流):字节输出缓冲流,将文本写入字符输出流,缓冲各个字符,从而提供单个字符、数组和字符串的高效写入。 可以指定缓冲区的大小,或者接受默认的大小。在大多数情况下,默认值就足够大了。 该类提供了 newLine() 方法,增加一行。


但是实际使用过程中发现这个通过newLine来增加一行实现换行操作很繁琐,所以Writer下有一个独有的过滤流子类PrintWriter,它可以:

①可以操作基本数据类型

②可以操作字符串

print(String s): 写入不换行

println(String s):写入换行

③可以操作对象

println(Object o):写入对象

注意:写入的数据 为对象的toString的返回值

package test;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
public class TestPrintWriter {
  public static void main(String[] args) throws IOException {
    //创建节点流
    FileWriter fileWriter = new FileWriter("file/d.txt");
    //过滤流 PrintWriter
    PrintWriter printWriter = new PrintWriter(fileWriter);  
    //进行写操作
    printWriter.println("哈哈哈哈哈");
    printWriter.println("嘤嘤嘤嘤嘤");
    printWriter.println("汪汪汪汪汪");
    printWriter.println("呵呵呵呵呵");
    //还可以写入对象,且对象不需要实现序列化接口
    Student student = new Student("macw",22);
    printWriter.println(student);
    //关闭资源
    printWriter.close();  
  }
}

六、java File文件操作类

其中IO流是对文件内容进行操作

而File类是对文件本身进行操作。例如:删除文件、创建文件、重命名

File类对象没有无参构造,所以必须穿参数

File类的常见方法有:

String getName() 获取文件的名称


boolean canRead() 判断文件是否是可读的


boolean canWrite() 判断文件是否可被写入


int length() 获取文件的长度(以字节为单位)


String getAbsolutePath() 获取文件的绝对路径


String getParent() 获取文件的父路径


boolean isDirectory() 判断此抽象路径名表示的是否是一个目录


boolean isHidden 判断文件是否是隐藏文件


long lastModified() 获取文件最后修改时间


boolean delete() 删除由此抽象路径名表示的文件或目录。


File[] listFiles() 返回一个抽象路径名数组,表示由该抽象路径名表示的目录中的文件。


String[] list() 返回一个字符串数组,命名由此抽象路径名表示的目录中的文件和目录。


boolean mkdirs() 创建由此抽象路径名命名的目录,包括任何必需但不存在的父目录。可创建多层文件包


boolean mkdir() 创建由此抽象路径名命名的目录。只能创建一层文件包


boolean reNameTo(File dest) 重命名由此抽象路径名表示的文件。


最后演示一个综合案例,来概括整理今天学习的所有知识:

从命令行中读入一个文件名,判断该文件是否存在,如果该文件存在,则在原文件相同路径下创建一个文件名为“copy_原文件名”的新文件,该文件内容为原文件的拷贝。

例如读入一个“file/girl.jpg”的文件,则创建一个“file/copy_girl.jpg”,新文件和源文件内容相同。

package work;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Scanner;
/**
 * @author 超伟
 * @date 2019年5月17日  
 * @博客: https://blog.csdn.net/MacWx  
 */
public class t18 {
  /**
   * @param args 
   * @throws IOException 
   */
  public static void main(String[] args) throws IOException {
    // TODO Auto-generated method stub
    Scanner sc = new Scanner(System.in);
    System.out.println("请输入一个文件名:");
    String sname = sc.next();
    //创建在当前项目相对路径下的file文件夹名对象
    File file = new File("file");
    //listFiles方法返回的是该文件夹目录下所有的文件和目录
    File[] listFiles = file.listFiles();
    //定义布尔变量用来测试输入的文件名自否匹配到
    boolean b = true;
    //遍历获取文件名
    for (File file2 : listFiles) {
      //获取单个文件的文件名
      String name = file2.getName();
      //如果找到文件名,则进行复制操作
      if (sname.equals(name)) {
        b = false;
        //创建文件输入流对象,先读取到输入的文件名字的所有内容
        FileReader fileReader = new FileReader("file/"+sname);
        //创建文件输入包装流
        BufferedReader bufferedReader = new BufferedReader(fileReader);
        //创建字符文件输出流对象,输出到要复制到的文件夹中
        FileWriter fileWriter = new FileWriter("file/"+"copy_"+sname);
        //BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);
        //事实证明,printWriter要比bufferedWriter方法强大, 
        //自动换行就很爽!!!!
        PrintWriter printWriter = new PrintWriter(fileWriter);
        //死循环遍历文件中的所有内容,然后依次写入要复制的文件中
        while(true){
          String readLine = bufferedReader.readLine();
          if (readLine == null) {
            break;
          }
          //System.out.println(readLine);
          //再写入到要复制的文件中
          printWriter.println(readLine);
        }
        //统统关闭资源
        bufferedReader.close();
        printWriter.close();
        sc.close();
      }     
    }
    if (b) {
      System.out.println(sname+"文件在此文件夹中不存在!");
    }   
  }
}

IO流的相关内容有点多,要多练才行!

目录
相关文章
|
3月前
|
Java 开发者
重学Java基础篇—Java类加载顺序深度解析
本文全面解析Java类的生命周期与加载顺序,涵盖从加载到卸载的七个阶段,并深入探讨初始化阶段的执行规则。通过单类、继承体系的实例分析,明确静态与实例初始化的顺序。同时,列举六种触发初始化的场景及特殊场景处理(如接口初始化)。提供类加载完整流程图与记忆口诀,助于理解复杂初始化逻辑。此外,针对空指针异常等问题提出排查方案,并给出最佳实践建议,帮助开发者优化程序设计、定位BUG及理解框架机制。最后扩展讲解类加载器层次与双亲委派机制,为深入研究奠定基础。
113 0
|
1月前
|
人工智能 安全 Java
Java并发包下Atomic相关类的使用
本文介绍了 `java.util.concurrent.atomic` 包下的各类原子类及其使用场景,包括基本类型原子类(如 `AtomicInteger`、`AtomicLong`)、数组类型原子类(如 `AtomicIntegerArray`)、引用类型原子类(如 `AtomicReference`)、对象属性修改原子类(如 `AtomicIntegerFieldUpdater`)以及原子操作增强类(如 `LongAdder` 和 `LongAccumulator`)。同时,详细对比了不同原子类在高并发场景下的性能表现,展示了 `LongAdder` 的高效性。
77 31
|
27天前
|
存储 安全 Java
【高薪程序员必看】万字长文拆解Java并发编程!(7):不可变类设计指南
🌟 ​大家好,我是摘星!​ 🌟今天为大家带来的是并发编程中Java不可变类设计指南,废话不多说让我们直接开始。
35 0
|
2月前
|
Java 数据安全/隐私保护
Java 类和对象
本文介绍了Java编程中类和对象的基础知识,作为面向对象编程(OOP)的核心概念。类是对象的蓝图,定义实体类型;对象是具体实例,包含状态和行为。通过示例展示了如何创建表示汽车的类及其实例,并说明了构造函数、字段和方法的作用。同时,文章还探讨了访问修饰符的使用,强调封装的重要性,如通过getter和setter控制字段访问。最后总结了类与对象的关系及其在Java中的应用,并建议进一步学习继承等概念。
|
3月前
|
缓存 安全 Java
《从头开始学java,一天一个知识点》之:输入与输出:Scanner与System类
你是否也经历过这些崩溃瞬间?三天教程连`i++`和`++i`都说不清,面试时`a==b`与`equals()`区别大脑空白,代码总是莫名报NPE。这个系列就是为你打造的Java「速效救心丸」!每天1分钟,地铁通勤、午休间隙即可学习。直击高频考点和实际开发中的“坑位”,拒绝冗长概念,每篇都有可运行代码示例。涵盖输入输出基础、猜数字游戏、企业编码规范、性能优化技巧、隐藏技能等。助你快速掌握Java核心知识,提升编程能力。点赞、收藏、转发,助力更多小伙伴一起成长!
70 19
|
3月前
|
存储 监控 安全
重学Java基础篇—类的生命周期深度解析
本文全面解析了Java类的生命周期,涵盖加载、验证、准备、解析、初始化、使用及卸载七个关键阶段。通过分阶段执行机制详解(如加载阶段的触发条件与技术实现),结合方法调用机制、内存回收保护等使用阶段特性,以及卸载条件和特殊场景处理,帮助开发者深入理解JVM运作原理。同时,文章探讨了性能优化建议、典型异常处理及新一代JVM特性(如元空间与模块化系统)。总结中强调安全优先、延迟加载与动态扩展的设计思想,并提供开发建议与进阶方向,助力解决性能调优、内存泄漏排查及框架设计等问题。
107 5
|
3月前
|
缓存 安全 Java
《从头开始学java,一天一个知识点》之:字符串处理:String类的核心API
🌱 **《字符串处理:String类的核心API》一分钟速通!** 本文快速介绍Java中String类的3个高频API:`substring`、`indexOf`和`split`,并通过代码示例展示其用法。重点提示:`substring`的结束索引不包含该位置,`split`支持正则表达式。进一步探讨了String不可变性的高效设计原理及企业级编码规范,如避免使用`new String()`、拼接时使用`StringBuilder`等。最后通过互动解密游戏帮助读者巩固知识。 (上一篇:《多维数组与常见操作》 | 下一篇预告:《输入与输出:Scanner与System类》)
97 11
|
3月前
|
安全 IDE Java
重学Java基础篇—Java Object类常用方法深度解析
Java中,Object类作为所有类的超类,提供了多个核心方法以支持对象的基本行为。其中,`toString()`用于对象的字符串表示,重写时应包含关键信息;`equals()`与`hashCode()`需成对重写,确保对象等价判断的一致性;`getClass()`用于运行时类型识别;`clone()`实现对象复制,需区分浅拷贝与深拷贝;`wait()/notify()`支持线程协作。此外,`finalize()`已过时,建议使用更安全的资源管理方式。合理运用这些方法,并遵循最佳实践,可提升代码质量与健壮性。
101 1
|
2月前
|
Java
java中一个接口A,以及一个实现它的类B,一个A类型的引用对象作为一个方法的参数,这个参数的类型可以是B的类型吗?
本文探讨了面向对象编程中接口与实现类的关系,以及里氏替换原则(LSP)的应用。通过示例代码展示了如何利用多态性将实现类的对象传递给接口类型的参数,满足LSP的要求。LSP确保子类能无缝替换父类或接口,不改变程序行为。接口定义了行为规范,实现类遵循此规范,从而保证了多态性和代码的可维护性。总结来说,接口与实现类的关系天然符合LSP,体现了多态性的核心思想。
55 0
|
3月前
|
Java
java常见的集合类有哪些
Map接口和Collection接口是所有集合框架的父接口: 1. Collection接口的子接口包括:Set接口和List接口 2. Map接口的实现类主要有:HashMap、TreeMap、Hashtable、ConcurrentHashMap以及 Properties等 3. Set接口的实现类主要有:HashSet、TreeSet、LinkedHashSet等 4. List接口的实现类主要有:ArrayList、LinkedList、Stack以及Vector等