首页 > 编程语言 >Java SE 宋红康 days04-高级篇-IO流

Java SE 宋红康 days04-高级篇-IO流

时间:2022-10-03 12:01:01浏览次数:44  
标签:文件目录 文件 Java IO 读入 days04 File new public

1. File 类的使用

  ① File类的一个对象,代表一个文件或一个文件目录(俗称:文件夹)

  ② File类声明在 java.IO 包下

  ③ 常用构造器

    public File(String pathname):以pathname为路径创建File对象,可以是绝对路径或者相对路径

      在 main 里的相对路径:相较于当前工程的路径

      在 单元测试方法里的相对路径:相对于当前Module的路径

    public File(String parent,String child):以parent为父路径 ,child为子路径创建File对象

    public File(File parent,String child):根据一个父File对象和子文件路径创建File对象

  ④ 路径分隔符

    为了解决不同系统下路径分隔符的问题,使用 public static final String separator,根据操作系统,动态的提供分隔符。

    windows和DOS系统默认使用“\”来表示,UNIX和URL使用“/”来表示,

    eg. new File("d:" + File.separator + "atguigu" + File.separator + "info.txt");

  ⑤ File 的常用方法

    获取功能

      public String getAbsolutePath():获取绝对路径

      public String getPath() :获取路径

      public String getName() :获取名称

      public String getParent():获取上层文件目录路径。若无,返回null  

      public long length() :获取文件长度(即:字节数),不能获取目录的长度

      public long lastModified() :获取最后一次的修改时间,毫秒值

      public String[ ] list() :获取指定目录下的所有文件或者文件目录的名称数组

      public File[ ] listFiles() :获取指定目录下的所有文件或者文件目录的File数组

    重命名功能:public boolean renameTo(File dest):把文件重命名为指定的文件路径

      file1.renameTo(file2):前提是需要 file1 在硬盘中存在,且 file2 在硬盘中不存在

    判断功能:

      public boolean isDirectory():判断是否是文件目录

      public boolean isFile() :判断是否是文件

      public boolean exists() :判断是否存在

      public boolean canRead() :判断是否可读

      public boolean canWrite() :判断是否可写

      public boolean isHidden() :判断是否隐藏

    创建功能:

      public boolean createNewFile() :创建文件。若文件存在,则不创建,返回false

      public boolean mkdir() :创建文件目录。如果此文件目录存在,就不创建了。如果此文件目录的上层目录不存在,也不创建

      public boolean mkdirs() :创建文件目录。如果上层文件目录不存在,一并创建

      注意事项:如果你创建文件或者文件目录没有写盘符路径,那么默认在项目路径下

    删除功能:

      public boolean delete():删除文件或者文件夹(文件目录内不能包含文件或者文件目录)

2. IO流

  ① 流的分类

    a. 按操作数据单位不同分:字节流(8bit,非文本类用)、字符流(16bit)

    b. 按数据流的流向不同分:输入流、输出流

    c. 按流的角色的不同分:节点流(直接作用在文件上)、处理流(作用在已有的流之上)

    抽象基类:   字节流    字符流

        输入流  InputStream    Reader

        输出流   OutputStream    Writer

      IO流涉及40多个类,都是从以上4个抽象基类中派生的,派生出的子类都是以其父类名作为子类名后缀

  ② IO流体系(蓝底重点)

    

 

 


3. 字符流读入数据(try-catch抛出异常,finally可以关闭流)

  标准4个步骤:

    a. 实例化 File 类的对象,指明要读入的文件

    b. 提供具体的流(FileReader)的对象

    c. 数据的读入

    d. 流的关闭操作:close();

  读入方法说明:

    read():返回读入的一个字符,如果到达文件尾会返回 -1

    read(char[ ] cBuffer):返回每次读入 cBuffer 数组中的字符个数,如果到达文件尾会返回 -1,即(len = (fr.read(cBuf)) != -1);

      注意:遍历打印 read(char[ ] cBuffer) 读的数据时,for 循环放的不是cBuffer 数组的长度,而应该是 len 的大小

    非常容易出现读入的数据不正确的情况,要注意应读数组的长度

4. 字符流写出数据(从内存中写出数据到硬盘文件)

  标准4个步骤:

    a. 实例化 File 类的对象,指明写出到的文件

    b. 提供具体的流(FileWriter)的对象

    c. 数据的写出

    d. 流的关闭操作:close();

  写出操作说明:输出对应的 File 可以不存在;

    如果不存在,在输出过程中会自动创建此文件

    如果存在(此时需要判断文件写出流使用的构造器):

      FileWriter(file, false) 或 FileWriter(file) 对原有文件的覆盖

      FileWriter(file, true) 对原有文件尾部追加字符

 1             // 1. 创建File类的对象,指明读入和写出的文件
 2             File srcFile = new File("A.txt");
 3             File destFile = new File("B.txt");
 4             // 2. 创建输入流和输出流的对象
 5             FileReader fr = new FileReader(srcFile);
 6             FileWriter fw = new FileWriter(destFile);
 7             // 3. 数据的读入和写出操作
 8             char[] cbuf = new char[6];
 9             int len;// 记录每次读入到 cbuf 数组中字符的个数
10             while ((len = fr.read(cbuf)) != -1) {
11                 // 每次写出len个字符
12                 fw.write(cbuf, 0, len);
13             }
14             // 4. 关闭资源流
15             fw.close();
16             fr.close();

5. 字节流读入/写出数据(和字符流的流程一样)

6. 结论:

  对于文本文件(.txt、.java、.c、.cpp),使用字符流处理

  对于非文本文件(.jpg、.mp3、.mp4、.avi、.doc、.ppt、...)使用字节流处理

  如果单纯是复制的话,文本文件也可以使用字节流处理;


7. 缓冲流:(提供流的读取、写入的速度)

  提高读写速度的原因:内部提供了一个缓冲区,可以使用 bos.flush() 对缓冲区刷新,默认缓冲区长度为原来8倍(8192)

          字节流         字符流

  输入流  BufferedInputStream    BufferedReader

  输出流   BufferedOutputStream    BufferedWriter

  

 1             // 1. 造文件:创建File类的对象,指明读入和写出的文件
 2             File srcFile = new File("A.txt");
 3             File destFile = new File("B.txt");
 4             // 2. 造流:
 5             // 2.1 造节点流:输入流和输出流的对象
 6             FileInputStream fis = new FileInputStream(srcFile);
 7             FileOutputStream fos = new FileOutputStream(destFile);
 8             // 2.2 造缓冲流
 9             BufferedInputStream bis = new BufferedInputStream(fis);
10             BufferedOutputStream bos = new BufferedOutputStream(fos);
11             // 3. 数据的读入和写出操作
12             byte[] buffer = new byte[10];
13             int len;// 记录每次读入到 cbuf 数组中字符的个数
14             while ((len = bis.read(buffer)) != -1) {
15                 // 每次写出len个字符
16                 bos.write(buffer, 0, len);
17             }
18             // 4. 关闭资源流(先关闭外层流,再关闭内层流)
19             bos.close();
20             bis.close();
21             // 关闭外层流的同时,内层流也会自动进行关闭,因此可以省略
 1         // br=bufferedReader、bw=bufferedWriter
 2         // 数据的读入和写出操作 
 3         // 方法二:按行读入,不读换行符
 4         String date;
 5         while ((date = br.readLine()) != null) {
 6             // 添加换行的方法一
 7             bw.write(data + "\"); // data中不包含换行符
 8             // 添加换行的方法二
 9             bw.write(data);
10             bw.newLine();
11         }

8. 转换流(提供字符流和字节流之间的转换)

  1. 转换流的使用(属于字符流)

    InputStreamReader:将一个字节的输入流转换字符的输入流

    OutputStreamWriter:将一个字符的输出流转换字节的输出流

  2. 解码:字节、字节数组 ---->  字符数组、字符串

   编码:字符数组、字符串 ----> 字节、字节数组  

 1         // 1. 造文件、造流
 2         File file1 = new File("dbcp.txt");
 3         File file2 = new File("dbcp.gbk.txt");
 4 
 5         FileInputStream fis  = new FileInputStream(file1);
 6         FileOutputStream fos = new FileOutputStream(file2);
 7 
 8         InputStreamReader isr = new InputStreamReader(fis);
 9         OutputStreamWriter osw = new OutputStreamWriter(fos);
10         // 2. 读写过程
11         char[] cbuf = new char[20];
12         int len;
13         while ((len = isr.read()) != -1) {
14             osw.write(cbuf, 0, len);
15         }
16         // 3. 关闭资源
17         isr.close();
18         osw.close();

9. 标准输入输出流、打印流、数据流

  重定向(输入输出流 ):通过System类的setIn,setOut方法对默认设备进行改变。

    public static void setIn(InputStream in)

    public static void setOut(PrintStream out)

  打印流:实现将基本数据类型的数据格式转化为字符串输出

  数据流:为了方便地操作Java语言的基本数据类型和String的数据。

// 把"标准"输入流(键盘输入)这个字节流包装成字符流,再包装成缓冲流
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String s = null;
try {
  while ((s = br.readLine()) != null) { // 读取用户输入的一行数据 --> 阻塞程序
    if ("e".equalsIgnoreCase(s) || "exit".equalsIgnoreCase(s)) {
      System.out.println("安全退出!!");
      break;
  }
  // 将读取到的整行字符串转成大写输出
  System.out.println("-->:" + s.toUpperCase());
  System.out.println("继续输入信息");
}
br.close(); // 关闭过滤流时,会自动关闭它包装的底层节点流
FileOutputStream fos = new FileOutputStream(new File("D:\\IO\\text.txt"));
// 创建打印输出流,设置为自动刷新模式(写入换行符或字节 '\n' 时都会刷新输出缓冲区)
ps = new PrintStream(fos, true);
if (ps != null) {// 把标准输出流(控制台输出)改成文件
    System.setOut(ps);
}
for (int i = 0; i <= 255; i++) { // 输出ASCII字符
    System.out.print((char) i);
    if (i % 50 == 0) { // 每50个数据一行
        System.out.println(); // 换行
    }
}
ps.close();
// 创建连接到指定文件的数据输出流对象
DataOutputStream dos = new DataOutputStream(new FileOutputStream("destData.dat"));
dos.writeUTF("我爱北京天安门"); // 写UTF字符串
dos.writeBoolean(false); // 写入布尔值
dos.writeLong(1234567890L); // 写入长整数
dos.flush(); System.out.println("写文件成功!"); dos.close();

10. 对象流(ObjectInputStream 和OjbectOutputSteam)

  用于存储和读取基本数据类型数据或对象的处理流(可以把Java中的对象写入到数据源中,也能把对象从数据源中还原回来)

  序列化:用ObjectOutputStream类保存基本类型数据或对象的机制

  反序列化:用ObjectInputStream类读取基本类型数据或对象的机制

11. 对象序列化机制

  序列化过程:允许把内存中的Java对象转换成平台无关的二进制流,从而允许把这种二进制流持久地保存在磁盘上,或通过网络将这种二进制流传输到另一个网络节点。

  反序列化过程:当其它程序获取了这种二进制流,就可以恢复成原来的Java对象;

12. 自定义类的可序列化

  自定义类的可序列化需要满足以下要求:

  ① 需要实现如下两个接口之一:Serializable、Externalizable

  ② 当前类提供一个静态全局常量,标识序列化版本标识符:private static final long serialVersionUID;

  ③ 除了当前类需要实现 Serializable 接口之外,还必须保证其内部所有属性也必须是可序列化的;(默认基本数据类型可序列化)    

  :ObjectOutputStream 和 ObjectInputStream 不能序列化 static 和 transient 修饰的成员变量

13. 随机存储文件流(RandomAccessFile的使用)

  ① RandomAccessFile直接继承于java.lang.Object类,实现 DataInputDataOutput 接口;

  ② 既可以作为一个输入流,又可以作为一个输出流

  ③ 如果作为输出流时:

    写出到的文件如果不存在,则执行过程中自动创建;

    写出到的文件如果存在,则会对原有文件进行覆盖(默认情况从头覆盖,能覆盖几个字符就几个字符,不是对整个文件覆盖)

  ④ 可以通过相关操作,实现 RandomAccessFile “插入”数据的效果

  ⑤ RandomAccessFile.seek(pos):把指针调到角标为 pos 的位置

标签:文件目录,文件,Java,IO,读入,days04,File,new,public
From: https://www.cnblogs.com/LinxhzZ/p/16749521.html

相关文章