1. File 类

java.io.File 类:文件和目录路径名的抽象表示形式。通过File对象可以访问文件的属性、访问空文件或目录。

分隔符:

  • 路径分割符:File.pathSeparator(:
  • 名称分割符:File.separator(/

路径的表示方式:

path = “E:\test\2.jpg”; path = “E:” + File.separator + “test” + File.separator + “2.jpg”; path = “E:/test/2.jpg”;

第二种可以跨平台,推荐第三种

相对路径和绝对路径构造File对象:

  • 相对路径:
    1. File file = new File(parentPath,name);
    2. File file = new FIle(new File(parentPath),name);
    3. System.out.println(file.getName);
    4. System.out.println(file.getPath);
    绝对路径:
    File file = new FIle(E:/02.jpg);
    注意:没有盘符时,以 user.dir 构建

File的相关方法

1. 文件名

  1. getName() 文件名、路径名
  2. getPath() 路径名
  3. getAbsoluteFile() 绝对路径所对应的File对象
  4. getAbsolutePath() 绝对路径名
  5. getParent() 父目录,相对路径的父目录,可能为null
  6. renameTo(File newName) 重命名

2. 判断信息

  1. exists()
  2. canWrite()
  3. canReader()
  4. isFile()
  5. isDirectory() 是否是文件夹(不是真实存在的默认为文件夹)
  6. isAbsolute() 是否为绝对路径。消除平台差异,ie以盘符开头,其他的以/开头

3. 长度
length():返回字节数。

4. 创建、删除

  1. createNewFile() 不存在创建新文件
  2. delete() 删除文件
  3. static createTempFile(前缀3个字节长,后缀默认.temp) 默认临时空间
  4. static createTempFile(前缀3个字节长,后缀默认.temp,目录)
  5. deleteOnExit() 退出虚拟机时删除,常用于删除临时文件

5. 操作目录

  1. mkdir() 必须确保父目录存在,不存在则创建失败
  2. mkdirs() 如果目录链不存在,一同创建
  3. list() 文件|目录的名称
  4. listFiles() 文件|目录的Flile对象
  5. static listRoots() 根路径

2. IO 流

image.png

2.1 流的概念

流:流动流向。从一段到另一端,源头与目的地。

程序 与 文件|数组|网络连接|数据库。以程序为中心(即输出还是输出都是相对于程序来说的)。

2.2 IO 流分类

  • 1、流向:
    • 输入流
    • 输出流
  • 2、数据:
    • 字节流:二进制,可以是一切文件,包括纯文本、doc、音频、视频、图片
    • 字符流:纯文本文件
  • 3、功能
    • 节点流:包裹源头
    • 处理流:增强功能,提供性能

2.3 字节流与字符流(重点)与文件

2.3.1 字节流

  • 输入流
    • inputStream
      • read(byte[] b)
      • read(byte[] b, int off, int len)
      • close()
    • 实现类:FIleInputStream()
  • 输出流
    • outPutStream
      • write(byte[] b)
      • wirte(byte[] b, int off, int len)
      • flush()
      • close()
    • 实现类:FileOutputStream()

2.3.2 字符流

  • 输入流
    • reader
      • read(char[] cbuf)
      • read(char[] cbuf, int off, int len)
      • close()
    • 实现类:FileReader()
  • 输出流
    • writer
      • write(char[] cbuf)
      • write(char[] cbuf, int off, int len)
      • flush()
      • close()
    • 实现类:FileWritre()

四、操作

1、举例 —-> 读取文件

(1)关联房子 —-> 建立与文件联系

(2)选择搬家公司 —-> 选择对应的流

(3)搬家 —-> 读取|写出

  1. 卡车大小 —-> 数组大小
  2. 运输 —-> 读取、写出

(4)打发走over —-> 释放资源

2、操作

  1. 建立联系
  2. 选择流
  3. 操作
    1. 数组大小
    2. read、write
  4. 释放资源

2.4 实例代码

2.4.1 字节流

输入文件
  1. public class Demo03_inputStream {
  2. public static void main(String[] args) {
  3. // 1. 建立联系
  4. File file = new File("D:/test/a.txt");
  5. // 2. 选择流
  6. InputStream is = null;
  7. try {
  8. is = new FileInputStream(file);
  9. byte[] car = new byte[1024];
  10. int len = 0; // 接收实际读取大小
  11. // 循环读取
  12. try {
  13. // 3. 操作
  14. while (-1 != (len = is.read(car))) {
  15. // 输出 字节数组转化成字符串
  16. String info = new String(car, 0, len);
  17. System.out.println(info);
  18. }
  19. } catch (IOException e) {
  20. e.printStackTrace();
  21. System.out.println("读取文件失败");
  22. }
  23. } catch (FileNotFoundException e) {
  24. e.printStackTrace();
  25. System.out.println("文件不存在");
  26. } finally {
  27. if (null != is) {
  28. try {
  29. // 4. 释放资源
  30. is.close();
  31. } catch (IOException e) {
  32. e.printStackTrace();
  33. System.out.println("关闭输入流失败");
  34. }}}}}

写出文件
  1. public class Demo04_outputStream {
  2. public static void main(String[] args) {
  3. // 1. 建立联系
  4. File file = new File("D:/test/a.txt");
  5. // 2. 选择流
  6. OutputStream os = null;
  7. try {
  8. // 为true时,以追加形式写出文件;为false时,覆盖
  9. os = new FileOutputStream(file, true);
  10. String str = "this is a str \r\n";
  11. // 字符串转字节数组
  12. byte[] data = str.getBytes();
  13. os.write(data, 0, data.length);
  14. os.flush(); // 强制刷新数据
  15. } catch (FileNotFoundException e) {
  16. e.printStackTrace();
  17. System.out.println("文件没有找到");
  18. } catch (IOException e) {
  19. e.printStackTrace();
  20. System.out.println("文件写出失败");
  21. } finally {
  22. if (null != os) {
  23. try {
  24. os.close();
  25. } catch (IOException e) {
  26. e.printStackTrace();
  27. System.out.println("关闭输出流失败");
  28. }}}}}

文件拷贝
  1. public void copyFile(File src, File dest) throws IOException {
  2. if (!src.isFile()) {
  3. System.out.println("只能copy文件");
  4. throw new IOException("只能copy文件");
  5. }
  6. if (dest.isDirectory()) {
  7. System.out.println("不能建立与文件夹同名的文件");
  8. throw new IOException(dest.getAbsolutePath() + "不能建立与文件夹同名的文件");
  9. }
  10. InputStream is = null;
  11. OutputStream os = null;
  12. byte[] data = new byte[1024];
  13. int len = 0;
  14. is = new FileInputStream(src);
  15. os = new FileOutputStream(dest);
  16. while (-1 != (len = is.read(data))) {
  17. os.write(data, 0, len);
  18. }
  19. os.flush();
  20. // 先开的后关闭
  21. os.close();
  22. is.close();
  23. }

文件夹的拷贝
  1. /**
  2. * 文件夹的copy 1、文件:复制 copyFile 2、文件夹:创建 mkdirs() 3、递归查找子孙级
  3. */
  4. public static void copyDir(String srcPath, String destPath) {
  5. File src = new File(srcPath);
  6. File dest = new File(destPath);
  7. if (src.isDirectory()) {
  8. dest = new File(destPath, src.getName());
  9. }
  10. copyDieDetails(src, dest);
  11. }
  12. private static void copyDieDetails(File src, File dest) {
  13. if (src.isFile()) {
  14. try {
  15. copyFile(src, dest);// 调用上面文件拷贝的方法
  16. } catch (IOException e) {
  17. e.printStackTrace();
  18. }
  19. } else if (src.isDirectory()) {
  20. dest.mkdirs();
  21. for (File sub : src.listFiles()) {
  22. copyDieDetails(sub, new File(dest, sub.getName()));
  23. }
  24. }
  25. }

2.4.2 字符流

只能处理纯文本,全部为可见字符。.txt.html
对应的节点流:

  • Reader —> FileReader
  • Writer —> FileWriter

使用方式和字节流相似:

  • 建立联系
  • 选择流: FileReadre、FileWriter
  • 读取 char[] flush = new char[1024]
  • 关闭

2.4.3. 处理流

  • 缓冲流
    • 字节缓冲流
      • BufferedInputStream
      • BufferedOutputStream
    • 字符缓冲流
      • BufferedReader(Reader in) 创建一个使用默认大小输入缓冲区的缓冲字符输入流。
      • BufferedReader(Reader in, int sz) 创建一个使用指定大小输入缓冲区的缓冲字符输入流。
        • readLine() 读取一个文本行。
      • BufferedWriter(Writer out)
      • BufferedWriter(Writer out, int sz)
        • newLine() 写入一个行分隔符

字符缓冲流 实现文件拷贝
  1. public class Demo07_bufferedChar {
  2. public static void main(String[] args) {
  3. File src = new File("D:/test/a.txt");
  4. File dest = new File("D:/test/b.txt");
  5. BufferedReader reader = null;
  6. BufferedWriter writer = null;
  7. try {
  8. reader = new BufferedReader(new FileReader(src));
  9. writer = new BufferedWriter(new FileWriter(dest));
  10. // 旧的读取方法
  11. /*
  12. * char[] flush = new char[1024]; int len = 0;
  13. * while(-1!=(reader.read(flush))){ writer.write(flush, 0, len); }
  14. */
  15. // 新增方法的操作
  16. String line = null;
  17. while (null != (line = (reader.readLine()))) {
  18. writer.write(line);
  19. // writer.append("\r\n");
  20. writer.newLine();// 换行符号
  21. }
  22. writer.flush();
  23. } catch (FileNotFoundException e) {
  24. e.printStackTrace();
  25. } catch (IOException e) {
  26. e.printStackTrace();
  27. }}}

2.4.4 转换流

字节流转为字符流,设计处理乱码问题。

  1. 编码与解码概念
    1. 编码: 字符 —-编码字符集—>二进制
    2. 解码: 二进制 —-解码字符集—>字符
  2. 乱码
    1. 编码与解码的字符集不统一
    2. 字节缺少,长度丢失

转换流

  • 输入流 InputStreamReader (解码)
  • 输出流 OutputStreamWriter (编码)

2.4.5. 其他流

字节流
  • 字节数组 节点流
    • 输入流: ByteArrayInputStream read(byte[] b, int off, int len) + close();(close可用可不用
    • 输出流: ByteArrayOutputStream write(byte[] b, int off, int len) + toByteArray() (不要使用多态)

处理流
  • 数据类型处理流(基本类型+String)
    • 输入流:DataInputStream readXxx
      • read(byte[] b)
      • read(byte[] b, int off, int len)
      • readBoolean()
      • readByte()
      • readByte()
      • readDouble()
      • readFloat()
      • readFully
    • 输出流:DataOutputstream WriteXxx
      • 。。。同上
  • 引用类型(对象) 保留数据+类型
    • 反序列化 ObjectOutputStream readObject()
    • 序列化 ObjectInputStream wirteObject()
    • 注意:
      • 先序列化后反序列化。反序列化顺序必须和序列化顺序一致
      • 不是所有的对象都可以序列化,必须实现java.io.Serilizable接口。
      • 不是所有的属性都序列化,不需要序列化的属性用transient

注意:

  • java.io.EOFException:没有读取到相关的内容
  • 读取顺序可能存在数据问题

ByteArrayInputstream 和 ByteArrayOutputStream

  1. public static void main(String[] args) throws IOException {
  2. byte[] data = getBytesFromFile("D:/test/a.txt");
  3. toFileFromByteArray(data, "D:/test/c.txt");
  4. }
  5. /**
  6. * 文件 --> 程序--> 字节数组
  7. *
  8. * @throws IOException
  9. */
  10. public static byte[] getBytesFromFile(String path) throws IOException {
  11. File file = new File(path);
  12. byte[] dest = null;
  13. InputStream is = new BufferedInputStream(new FileInputStream(file));
  14. ByteArrayOutputStream bos = new ByteArrayOutputStream();
  15. byte[] flush = new byte[1024];
  16. int len = 0;
  17. while (-1 != (len = is.read(flush))) {
  18. bos.write(flush, 0, len);
  19. }
  20. bos.flush();
  21. dest = bos.toByteArray();
  22. // 先开后关
  23. bos.close();
  24. is.close();
  25. return dest;
  26. }
  27. /**
  28. * 字节数组 --> 程序 --> 文件
  29. *
  30. * @throws IOException
  31. */
  32. public static void toFileFromByteArray(byte[] src, String dest) throws IOException {
  33. File file = new File(dest);
  34. InputStream is = new BufferedInputStream(new ByteArrayInputStream(src));
  35. OutputStream os = new BufferedOutputStream(new FileOutputStream(file));
  36. byte[] flush = new byte[1024];
  37. int len = 0;
  38. while (-1 != (len = is.read(flush))) {
  39. os.write(flush, 0, len);
  40. }
  41. os.flush();
  42. os.close();
  43. is.close();
  44. }

对象通过流实现序列化和反序列化

Object:

  1. /**
  2. * 空接口只是一个标识,说明可以序列化
  3. * 不需要序列化的属性加 transient
  4. */
  5. public class Employee implements java.io.Serializable {
  6. private static final long serialVersionUID = 1L;
  7. private transient String name;
  8. private double salary;
  9. ...

ObjectInputStream 和 ObjectOutputStream

  1. public static void main(String[] args) throws FileNotFoundException, IOException, ClassNotFoundException {
  2. seri("D:/test/seri.txt");
  3. read("D:/test/seri.txt");
  4. }
  5. // 序列化
  6. public static void seri(String destPath) throws FileNotFoundException, IOException {
  7. Employee emp = new Employee("张三", 5000);
  8. int[] arr = { 1, 2, 3, 54 };
  9. File dest = new File(destPath);
  10. ObjectOutputStream oos = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(dest)));
  11. oos.writeObject(emp);
  12. oos.writeObject(arr);
  13. oos.flush();
  14. oos.close();
  15. }
  16. // 反序列化
  17. public static void read(String destPath) throws FileNotFoundException, IOException, ClassNotFoundException {
  18. File dest = new File(destPath);
  19. ObjectInputStream ois = new ObjectInputStream(new BufferedInputStream(new FileInputStream(dest)));
  20. Object obj = ois.readObject();
  21. if (obj instanceof Employee) {
  22. Employee emp = (Employee) obj;
  23. System.out.println(emp.getName());
  24. System.out.println(emp.getSalary());
  25. }
  26. int[] arr = (int[]) ois.readObject();
  27. System.out.println(Arrays.toString(arr));
  28. ois.close();
  29. }

2.4.6. 关闭流方法

  1. public class Demo11_FileUtil {
  2. /**
  3. * 关闭流 可变参数 ...: 代表参数随意指定。只能放在形参的最后一个位置,处理方式与数组一致
  4. * 使用:Demo11_FileUtil.close(is, os, oos)
  5. */
  6. public static void close(Closeable... io) {
  7. for (Closeable temp : io) {
  8. if (null != temp) {
  9. try {
  10. temp.close();
  11. } catch (IOException e) {
  12. e.printStackTrace();
  13. }}}}
  14. /**
  15. * 使用泛型
  16. */
  17. public static <T extends Closeable> void closeAll(Closeable... io) {
  18. for (Closeable temp : io) {
  19. if (null != temp) {
  20. try {
  21. temp.close();
  22. } catch (IOException e) {
  23. e.printStackTrace();
  24. }}}}}