Java IO流笔记

2021-10-02  本文已影响0人  zqyadam

File类

功能与作用

实例化

常用构造器

路径分隔符

常用方法

获取功能

重命名功能

判断功能

创建功能

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

删除功能

IO流概述

流的分类

  1. Java的IO流共涉及40多个类,实际上非常规则,都是从如下4个抽象基类派生的。
  2. 由这四个类派生出来的子类名称都是以其父类名作为子类名后缀。

流的体系结构

蓝色背景的类为重点

抽象基类 节点流(或文件流) 缓冲流(处理流的一种)
InputStream FileInputStream BufferedInputStream
OutputStream FileOutputStream BufferedOutputStream
Reader FileReader BufferedReader
Writer FileWriter BufferedWriter

InputStream & Reader

InputStream

Reader

OutputStream & Writer

OutputStream

Writer

节点流(或文件流)

FileReader

使用read()逐个字符进行读取

FileReader fr = null;
try {
  // 1. 实例化File类的对象,指明要操作的文件
  File file = new File("hello.txt");
  // 2. 提供具体的流
  fr = new FileReader(file);
  // 3. 数据的读入
  // 方式1:
  int i = fr.read();
  while (i != -1) {
    System.out.print((char) i);
    i = fr.read();
  }
  // 方式2:
  int data;
  while ((data = fr.read()) != -1) {
    System.out.print((char) data);
  }
} catch (IOException e) {
  // TODO Auto-generated catch block
  e.printStackTrace();
} finally {
  // 4. 流的关闭操作
  try {
    if (fr != null)
      fr.close();
  } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
  }
}

说明:

  1. read()的理解:返回读入的一个字符。如果达到文件末尾,返回-1
  2. 异常的处理:为了保证流资源的一定可以执行关闭操作。需要使用try-catch-finally处理
  3. 读入的文件一定要存在,否则就会报FileNotFoundException

使用read(char[] cbuf)一次读取指定长度的字符

FileReader fileReader = null;
try {
  fileReader = new FileReader("hello.txt");

  char[] cbuf = new char[4];
  int len;
  while ((len = fileReader.read(cbuf)) != -1) {
    // 方式1
    for (int i = 0; i < len; i++) {
      System.out.print(cbuf[i]);
    }

    // 方式2
    String str = new String(cbuf, 0, len);
    System.out.print(str);
  }
} catch (IOException e) {
  // TODO Auto-generated catch block
  e.printStackTrace();
} finally {
  try {
    if (fileReader != null) {
      fileReader.close();
    }
  } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
  }
}

FileWriter

FileWriter fileWriter = null;
try {
  // 1. 提用File类的对象,指明写出到的文件
  File file = new File("hello1.txt");

  // 2. 提供FileWriter的对象,用于数据的写出
  fileWriter = new FileWriter(file);

  // 3. 写出的操作
  fileWriter.write("Hello world!");
  fileWriter.write("I have a dream.");
} catch (IOException e) {
  e.printStackTrace();
} finally {
  // 4. 流资源的关闭
  try {
    if (fileWriter != null) {
      fileWriter.close();
    }
  } catch (IOException e) {
    e.printStackTrace();
  }
}

说明:

  1. 输出操作,对应的File可以不存在。不会报异常。
  2. File对应的硬盘中的文件如果不存在,在输出的过程中会自动创建此文件。
  3. File对应的硬盘中的文件如果存在:
    • 如果流使用的构造器是:FileWriter(file, false)/FileWriter(file),则对原有文件进行覆盖
    • 如果流使用的构造器是:FileWriter(file, true),则是追加内容

复制文本文件

public void CopyText(String src, String dest) {
  FileReader srcFileReader = null;
  FileWriter destFileWriter = null;
  try {
    File srcFile = new File(src);
    File destFile = new File(dest);

    srcFileReader = new FileReader(srcFile);
    destFileWriter = new FileWriter(destFile);

    char[] data = new char[1024];
    int len;
    while ((len = srcFileReader.read(data)) != -1) {
      destFileWriter.write(data, 0, len);
    }
  } catch (IOException e) {
    // TODO: handle exception
  } finally {
    try {
      if (srcFileReader != null) {
        srcFileReader.close();
      }

    } catch (IOException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }

    if (destFileWriter != null) {
      try {
        destFileWriter.close();
      } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
      }
    }
  }
}

缓冲流的使用

public void test1() {
  BufferedReader br = null;
  BufferedWriter bw = null;
  try {
    // 创建缓冲流对象:它是处理流,是对节点流的包装
    br = new BufferedReader(new FileReader("d:\\IOTest\\source.txt"));
    bw = new BufferedWriter(new FileWriter("d:\\IOTest\\dest.txt"));
    String str;
    while ((str = br.readLine()) != null) { // 一次读取字符文本文件的一行字符
      bw.write(str); // 一次写入一行字符串
      bw.newLine(); // 写入行分隔符
    }
    bw.flush(); // 刷新缓冲区
  } catch (IOException e) {
    e.printStackTrace();
  } finally {
    // 关闭IO流对象
    try {
      if (bw != null) {
        bw.close(); // 关闭过滤流时,会自动关闭它所包装的底层节点流
      }
    } catch (IOException e) {
      e.printStackTrace();
    }
    try {
      if (br != null) {
        br.close();
      }
    } catch (IOException e) {
      e.printStackTrace();
    }
  }
}

转换流的使用

InputStreamReader

OutputStreamWriter

public void testMyInput() throws Exception {
  FileInputStream fis = new FileInputStream("hello.txt");
  FileOutputStream fos = new FileOutputStream("hello_gbk.txt");
  InputStreamReader isr = new InputStreamReader(fis, "UTF-8");
  OutputStreamWriter osw = new OutputStreamWriter(fos, "GBK");
  BufferedReader br = new BufferedReader(isr);
  BufferedWriter bw = new BufferedWriter(osw);
  String str = null;
  while ((str = br.readLine()) != null) {
    bw.write(str);
    bw.newLine();
    bw.flush();
  }
  bw.close();
  br.close();
}

其他流的使用

标准输入、输出流(了解)

System.out.println("请输入信息(退出输入e或exit):");
// 把"标准"输入流(键盘输入)这个字节流包装成字符流,再包装成缓冲流
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("继续输入信息");
  }
} catch (IOException e) {
  e.printStackTrace();
} finally {
  try {
    if (br != null) {
      br.close(); // 关闭过滤流时,会自动关闭它包装的底层节点流
    }
  } catch (IOException e) {
    e.printStackTrace();
  }
}

打印流(了解)

PrintStream ps = null;
try {
  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(); // 换行
    }
  }
} catch (FileNotFoundException e) {
  e.printStackTrace();
} finally {
  if (ps != null) {
    ps.close();
  }
}

数据流(了解)

输出对象:

DataOutputStream dos = null;
try { // 创建连接到指定文件的数据输出流对象
  dos = new DataOutputStream(new FileOutputStream("destData.dat"));
  dos.writeUTF("我爱北京天安门"); // 写UTF字符串
  dos.writeBoolean(false); // 写入布尔值
  dos.writeLong(1234567890L); // 写入长整数
  System.out.println("写文件成功!");
} catch (IOException e) {
  e.printStackTrace();
} finally { // 关闭流对象
  try {
    if (dos != null) {
      // 关闭过滤流时,会自动关闭它包装的底层节点流
      dos.close();
    }
  } catch (IOException e) {
    e.printStackTrace();
  }
}

输入对象

DataInputStream dis = null;
try {
  dis = new DataInputStream(new FileInputStream("destData.dat"));
  String info = dis.readUTF();
  boolean flag = dis.readBoolean();
  long time = dis.readLong();
  System.out.println(info);
  System.out.println(flag);
  System.out.println(time);
} catch (Exception e) {
  e.printStackTrace();
} finally {
  if (dis != null) {
    try {
      dis.close();
    } catch (IOException e) {
      e.printStackTrace();
    }
  }
}

对象流的使用

对象的序列化

使用对象流序列化对象

序列化

//序列化:将对象写入到磁盘或者进行网络传输。
//要求对象必须实现了Serializable接口

ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(“data.txt"));
Person p = new Person("韩梅梅", 18, "中华大街", new Pet());
oos.writeObject(p);
oos.flush();
oos.close();

反序列化

//反序列化:将磁盘中的对象数据源读出。

ObjectInputStream ois = new ObjectInputStream(new FileInputStream(“data.txt"));
Person p1 = (Person)ois.readObject();
System.out.println(p1.toString());
ois.close();

java.io.Serializable 接口的理解

RandomAccessFile的使用

RandomAccessFile类

读取文件内容

RandomAccessFile raf = new RandomAccessFile(“test.txt”, “rw”);
raf.seek(5);
byte [] b = new byte[1024];
int off = 0;
int len = 5;
raf.read(b, off, len);
String str = new String(b, 0, len);
System.out.println(str);
raf.close();

写入文件内容

例1:

RandomAccessFile raf = new RandomAccessFile("test.txt", "rw");
raf.seek(5);
//先读出来
String temp = raf.readLine();
raf.seek(5);
raf.write("xyz".getBytes());
raf.write(temp.getBytes());
raf.close();

例2:

RandomAccessFile raf1 = new RandomAccessFile("hello.txt", "rw");
raf1.seek(5);
//方式一:
//StringBuilder info = new StringBuilder((int) file.length());
//byte[] buffer = new byte[10];
//int len;
//while((len = raf1.read(buffer)) != -1){
////info += new String(buffer,0,len);
//info.append(new String(buffer,0,len));
//}
//方式二:
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[10];
int len;
while((len = raf1.read(buffer)) != -1){
    baos.write(buffer, 0, len);
}

Path、Paths、Files的使用

Java NIO

|-----java.nio.channels.Channel

|-----FileChannel:处理本地文件
|-----SocketChannel:TCP网络编程的客户端的Channel
|-----ServerSocketChannel:TCP网络编程的服务器端的Channel
|-----DatagramChannel:UDP网络编程中发送端和接收端的Channel

NIO.2

随着JDK 7的发布,Java对NIO进行了极大的扩展,增强了对文件处理和文件系统特性的支持,以至于我们称他们为NIO.2。因为NIO提供的一些功能,NIO已经成为文件处理中越来越重要的部分。

Path 、Paths 和Files 核心API

  
- 但在Java7中,我们可以这样写:

  ```java
  import java.nio.file.Path;
  import java.nio.file.Paths;
  Path path = Paths.get("index.html");

Path接口

Files 类

上一篇下一篇

猜你喜欢

热点阅读