1 文件

1.1 文件的创建

  1. public void create01() {
  2. String filePath = "e:\\news1.txt";
  3. File file = new File(filePath);
  4. try {
  5. file.createNewFile();
  6. System.out.println("文件创建成功");
  7. } catch (IOException e) {
  8. e.printStackTrace();
  9. }
  10. }

1.2 文件常用的方法

  • getName:获取文件名
  • getAbsolutePath:获取文件绝对路径
  • getParent:获取父级目录
  • getlength:文件大小(字节)
  • exists:文件是否存在
  • isFile: 是不是文件
  • isDirectory:是不是目录
  • delet:删除文件
  • mkdir:创建目录
  • mdirs:创建多级目录

2 IO流

抽象基类 字节流 字符流
输入流 InputStream Reader
输出流 OutputStream Writer

这四个类是抽象类,其他IO流对象都是以这四个类派生出来

  • 节点流:直接和数据源相接(File,String,Pipe等)
  • 处理流:封装一个节点流,使用了模拟器模式(BufferedReader,BufferedWriter等)

2.1 FileInputStream

  1. 从文件读取单个字节
  1. public void readFile01() {
  2. String filePath = "e:\\hello.txt";
  3. int readData = 0;
  4. FileInputStream fileInputStream = null;
  5. try {
  6. //创建 FileInputStream 对象,用于读取 文件
  7. fileInputStream = new FileInputStream(filePath);
  8. //从该输入流读取一个字节的数据。 如果没有输入可用,此方法将阻止。
  9. //如果返回-1 , 表示读取完毕
  10. while ((readData = fileInputStream.read()) != -1) {
  11. System.out.print((char)readData);//转成char显示
  12. }
  13. } catch (IOException e) {
  14. e.printStackTrace();
  15. } finally {
  16. //关闭文件流,释放资源.
  17. try {
  18. fileInputStream.close();
  19. } catch (IOException e) {
  20. e.printStackTrace();
  21. }
  22. }
  23. }
  1. 用数组读取文件
  1. public void readFile02() {
  2. String filePath = "e:\\hello.txt";
  3. //字节数组
  4. byte[] buf = new byte[8]; //一次读取8个字节.
  5. int readLen = 0;
  6. FileInputStream fileInputStream = null;
  7. try {
  8. //创建 FileInputStream 对象,用于读取 文件
  9. fileInputStream = new FileInputStream(filePath);
  10. //从该输入流读取最多b.length字节的数据到字节数组。 此方法将阻塞,直到某些输入可用。
  11. //如果返回-1 , 表示读取完毕
  12. //如果读取正常, 返回实际读取的字节数
  13. while ((readLen = fileInputStream.read(buf)) != -1) {
  14. System.out.print(new String(buf, 0, readLen));//显示
  15. }
  16. } catch (IOException e) {
  17. e.printStackTrace();
  18. } finally {
  19. //关闭文件流,释放资源.
  20. try {
  21. fileInputStream.close();
  22. } catch (IOException e) {
  23. e.printStackTrace();
  24. }
  25. }
  26. }

2.2 FileOutputStream

  1. new FileOutputStream(filePath) 创建方式,当写入内容是,会覆盖原来的内容
  2. new FileOutputStream(filePath, true) 创建方式,当写入内容是,是追加到文件后面
  1. public void writeFile() {
  2. //创建 FileOutputStream对象
  3. String filePath = "e:\\a.txt";
  4. FileOutputStream fileOutputStream = null;
  5. try {
  6. //得到 FileOutputStream对象 对象
  7. //1. new FileOutputStream(filePath) 创建方式,当写入内容是,会覆盖原来的内容
  8. //2. new FileOutputStream(filePath, true) 创建方式,当写入内容是,是追加到文件后面
  9. fileOutputStream = new FileOutputStream(filePath);
  10. //写入一个字节
  11. //fileOutputStream.write('H');//
  12. //写入字符串
  13. String str = "hello,world!";
  14. //str.getBytes() 可以把 字符串-> 字节数组
  15. //fileOutputStream.write(str.getBytes());
  16. /*
  17. write(byte[] b, int off, int len) 将 len字节从位于偏移量 off的指定字节数组写入此文件输出流
  18. */
  19. fileOutputStream.write(str.getBytes());
  20. } catch (IOException e) {
  21. e.printStackTrace();
  22. } finally {
  23. try {
  24. fileOutputStream.close();
  25. } catch (IOException e) {
  26. e.printStackTrace();
  27. }
  28. }
  29. }

2.3 文件的拷贝

  1. 创建文件的输入流 , 将文件读入到程序
  2. 创建文件的输出流, 将读取到的文件数据,写入到指定的文件.
  1. public static void main(String[] args) {
  2. String srcFilePath = "e:\\Koala.jpg";
  3. String destFilePath = "e:\\Koala3.jpg";
  4. FileInputStream fileInputStream = null;
  5. FileOutputStream fileOutputStream = null;
  6. try {
  7. fileInputStream = new FileInputStream(srcFilePath);
  8. fileOutputStream = new FileOutputStream(destFilePath);
  9. //定义一个字节数组,提高读取效果
  10. byte[] buf = new byte[1024];
  11. int readLen = 0;
  12. while ((readLen = fileInputStream.read(buf)) != -1) {
  13. //读取到后,就写入到文件 通过 fileOutputStream
  14. //即,是一边读,一边写
  15. fileOutputStream.write(buf, 0, readLen);//一定要使用这个方法
  16. }
  17. System.out.println("拷贝ok~");
  18. } catch (IOException e) {
  19. e.printStackTrace();
  20. } finally {
  21. try {
  22. //关闭输入流和输出流,释放资源
  23. if (fileInputStream != null) {
  24. fileInputStream.close();
  25. }
  26. if (fileOutputStream != null) {
  27. fileOutputStream.close();
  28. }
  29. } catch (IOException e) {
  30. e.printStackTrace();
  31. }
  32. }
  33. }

2.4 FileReader

FileReader以字符为单位读取文件

java中的char

java里的char类型无论何时都是2字节的,字母’A’也不例外,只是在流中就不一定了,因为不同的编码方式有不同的规则。 unicode第一Plane总共有65536个空位,是16位的,占两个字节,因为java仅使用了unicode的第一个Plane,所以也是16位的。 从字符流中以某种字符编码读取读取字符时,会将流中的字节以某种字符编码的机内码规则进行解码,并转换为unicode的值存储到char类型变量中;向字符流以某种字符编码写入字符时,会将char类型的unicode码代表的字符以某种的字符编码的机内码规则进行编码,然后将编码后的字节写入到目标流中。

  1. /**
  2. * 单个字符读取文件
  3. */
  4. @Test
  5. public void readFile01() {
  6. String filePath = "e:\\story.txt";
  7. FileReader fileReader = null;
  8. int data = 0;
  9. //1. 创建FileReader对象
  10. try {
  11. fileReader = new FileReader(filePath);
  12. //循环读取 使用read, 单个字符读取
  13. while ((data = fileReader.read()) != -1) {
  14. System.out.print((char) data);
  15. }
  16. } catch (IOException e) {
  17. e.printStackTrace();
  18. } finally {
  19. try {
  20. if (fileReader != null) {
  21. fileReader.close();
  22. }
  23. } catch (IOException e) {
  24. e.printStackTrace();
  25. }
  26. }
  27. }
  28. /**
  29. * 字符数组读取文件
  30. */
  31. @Test
  32. public void readFile02() {
  33. System.out.println("~~~readFile02 ~~~");
  34. String filePath = "e:\\story.txt";
  35. FileReader fileReader = null;
  36. int readLen = 0;
  37. char[] buf = new char[8];
  38. //1. 创建FileReader对象
  39. try {
  40. fileReader = new FileReader(filePath);
  41. //循环读取 使用read(buf), 返回的是实际读取到的字符数
  42. //如果返回-1, 说明到文件结束
  43. while ((readLen = fileReader.read(buf)) != -1) {
  44. System.out.print(new String(buf, 0, readLen));
  45. }
  46. } catch (IOException e) {
  47. e.printStackTrace();
  48. } finally {
  49. try {
  50. if (fileReader != null) {
  51. fileReader.close();
  52. }
  53. } catch (IOException e) {
  54. e.printStackTrace();
  55. }
  56. }
  57. }

2.5 FileWriter

  1. String filePath = "e:\\note.txt";
  2. //创建FileWriter对象
  3. FileWriter fileWriter = null;
  4. char[] chars = {'a', 'b', 'c'};
  5. try {
  6. fileWriter = new FileWriter(filePath);//默认是覆盖写入
  7. // 3) write(int):写入单个字符
  8. fileWriter.write('C');
  9. // 4) write(char[]):写入指定数组
  10. fileWriter.write(chars);
  11. // 5) write(char[],off,len):写入指定数组的指定部分
  12. fileWriter.write("Curry".toCharArray(), 0, 3);
  13. // 6) write(string):写入整个字符串
  14. fileWriter.write(" 你好哦");
  15. fileWriter.write("君子慎独");
  16. // 7) write(string,off,len):写入字符串的指定部分
  17. fileWriter.write("上海天津", 0, 2);
  18. //在数据量大的情况下,可以使用循环操作.
  19. } catch (IOException e) {
  20. e.printStackTrace();
  21. } finally {
  22. //对应FileWriter , 一定要关闭流,或者flush才能真正的把数据写入到文件
  23. try {
  24. //fileWriter.flush();
  25. //关闭文件流,等价 flush() + 关闭
  26. fileWriter.close();
  27. } catch (IOException e) {
  28. e.printStackTrace();
  29. }
  30. }
  31. System.out.println("程序结束...");

2.6 BufferedReader

对字节操作使用BufferedInputStream

  1. public static void main(String[] args) throws Exception {
  2. String filePath = "f:\\hello.txt";
  3. //创建bufferedReader
  4. BufferedReader bufferedReader = new BufferedReader(new FileReader(filePath));
  5. //读取
  6. String line; //按行读取, 效率高
  7. //说明
  8. //1. bufferedReader.readLine() 是按行读取文件
  9. //2. 当返回null 时,表示文件读取完毕
  10. while ((line = bufferedReader.readLine()) != null) {
  11. System.out.println(line);
  12. }
  13. //关闭流, 这里注意,只需要关闭 BufferedReader ,因为底层会自动的去关闭 节点流
  14. bufferedReader.close();
  15. }

2.7 BufferedWriter

对字节操作使用BufferedOutputStream

  1. public static void main(String[] args) throws IOException {
  2. String filePath = "f:\\ok.txt";
  3. //创建BufferedWriter
  4. //说明:
  5. //1. new FileWriter(filePath, true) 表示以追加的方式写入
  6. //2. new FileWriter(filePath) , 表示以覆盖的方式写入
  7. BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(filePath));
  8. bufferedWriter.write("你一定能够成为你想要成为的人");
  9. bufferedWriter.newLine();//插入一个和系统相关的换行
  10. bufferedWriter.write("你一定能够成为你想要成为的人");
  11. bufferedWriter.newLine();
  12. bufferedWriter.write("你一定能够成为你想要成为的人");
  13. bufferedWriter.newLine();
  14. //说明:关闭外层流即可 , 传入的 new FileWriter(filePath) ,会在底层关闭
  15. bufferedWriter.close();
  16. }

2.9 ObjectOutputStream

序列化:在保存数据时,保存数据的值和数据类型,要实现可序列化,必须实现Serializable或者Externalizable接口。一般使用Serializable接口(标记化的,里面没有方法)

反序列化:恢复数据时,恢复数据的值和数据类型

对象处理流能够将数据序列化和反序列化

  1. public static void main(String[] args) throws Exception {
  2. //序列化后,保存的文件格式,不是纯文本,而是按照他的格式来保存
  3. String filePath = "f:\\data.dat";
  4. ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(filePath));
  5. //序列化数据到 e:\data.dat
  6. oos.writeInt(100);// int -> Integer (实现了 Serializable)
  7. oos.writeBoolean(true);// boolean -> Boolean (实现了 Serializable)
  8. oos.writeChar('a');// char -> Character (实现了 Serializable)
  9. oos.writeDouble(9.5);// double -> Double (实现了 Serializable)
  10. oos.writeUTF("你一定可以成为你想要成为的人");//String
  11. oos.close();
  12. System.out.println("数据保存完毕(序列化形式)");
  13. }

2.10 ObjectInputStream

  1. public static void main(String[] args) throws IOException, ClassNotFoundException {
  2. //指定反序列化的文件
  3. String filePath = "f:\\data.dat";
  4. ObjectInputStream ois = new ObjectInputStream(new FileInputStream(filePath));
  5. //读取
  6. //1. 读取(反序列化)的顺序需要和你保存数据(序列化)的顺序一致
  7. //2. 否则会出现异常
  8. System.out.println(ois.readInt());
  9. System.out.println(ois.readBoolean());
  10. System.out.println(ois.readChar());
  11. System.out.println(ois.readDouble());
  12. System.out.println(ois.readUTF());
  13. //关闭流, 关闭外层流即可,底层会关闭 FileInputStream 流
  14. ois.close();
  15. }

对象处理流的注意事项

  1. 读写顺序要一致
  2. 类中添加serialVersionUID 序列化的版本号,可以提高兼容性
  3. 序列化对象时,默认将所有的属性都序列化,除了static或transient修饰的成员
  4. 序列化具有可继承性,其子类默认实现可序列化
  5. 对象序列化时,对象的属性必须要可序列化

2.11 InputStreamReader

将字节流转为字符流,用InputStreamReader可以指定编码格式,解决乱码的问题

  1. public static void main(String[] args) throws IOException {
  2. String filePath = "f:\\a.txt";
  3. //1. 把 FileInputStream 转成 InputStreamReader
  4. //2. 指定编码 gbk
  5. //InputStreamReader isr = new InputStreamReader(new FileInputStream(filePath), "gbk");
  6. //3. 把 InputStreamReader 传入 BufferedReader
  7. //BufferedReader br = new BufferedReader(isr);
  8. //将2 和 3 合在一起
  9. BufferedReader br = new BufferedReader(new InputStreamReader(
  10. new FileInputStream(filePath), "gbk"));
  11. //4. 读取
  12. String s = br.readLine();
  13. System.out.println("读取内容=" + s);
  14. //5. 关闭外层流
  15. br.close();
  16. }

2.12 OutputStreamReader

  1. public static void main(String[] args) throws IOException {
  2. String filePath = "f:\\hello.txt";
  3. String charSet = "utf-8";
  4. OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(filePath), charSet);
  5. osw.write("你好啊,笨蛋");
  6. osw.close();
  7. System.out.println("按照 " + charSet + " 保存文件成功~");
  8. }