IO流-2

1. IO流概述

  1. 当需要进行数据的传输的时候可以使用IO流来进行。例如:把磁盘中文件的数据读取到内存中。把内存中的数据写入到磁盘中。把网络中的数据读取到内存中。

2. IO流分类

  1. IO流根据处理数据类型的不同分为字符流和字节流,根据数据流向不同分为输入流和输出流,对输入流只能进行读操作,对输出流只能进行写操作。
数据类型 流向 顶层父类
字节流 输入(读) java.io.InputStream
字节流 输出(写) java.io.OutputStream
字符流 输入(读) java.io.Reader
字符流 输出(写) java.io.Writer

3. 字节输入流

  1. 所有字节输入流的父类是 java.io.InputStream ,它是以字节为单位的输入流
  2. 我们就以FileInputStream为例进行学习。

3.1 FileInputStream概述

  1. FileInputStream是用来读取文件数据的字节输入流。

3.2 FileInputStream对象创建

构造方法如下:

  1. FileInputStream(String name) throws FileNotFoundException //传入文件路径创建对象
  2. FileInputStream(File file) throws FileNotFoundException //传入文件路径的File对象来创建流对象

范例:

  1. public static void main(String[] args) throws FileNotFoundException {
  2. //创建对象
  3. FileInputStream fis = new FileInputStream("C:\\Users\\root\\Desktop\\test\\11.txt");
  4. System.out.println(fis);
  5. File file = new File("C:\\Users\\root\\Desktop\\test\\11.txt");
  6. FileInputStream fis2 = new FileInputStream(file);
  7. System.out.println(fis);
  8. }

3.3 读取数据

  1. 我们可以使用FileInputStream来读取文件中的字节数据。

3.3.1 一次读取一个字节

核心方法如下:

  1. public int read() throws IOException // 读取一个字节的数据作为返回值返回 返回值为-1时代表以及没有内容了

范例:

  1. public static void main(String[] args) throws IOException {
  2. FileInputStream fis = new FileInputStream("C:\\Users\\root\\Desktop\\test\\11.txt");
  3. //读取数据
  4. int b;
  5. while((b=fis.read())!=-1){
  6. System.out.println(b);
  7. }
  8. //释放资源
  9. fis.close();
  10. }

3.3.2 一次读取一个字节数组

核心方法如下:

  1. public int read(byte b[]) throws IOException //传入一个字节数组,最多读取一个字节数组的数据,并且会把数据存入数组中,返回值代表本次读取到的字节的个数。 如果返回值为-1代表没有数据了

范例:

  1. public static void main(String[] args) throws IOException {
  2. FileInputStream fis = new FileInputStream("C:\\Users\\root\\Desktop\\test\\11.txt");
  3. //读取数据 一次读一个字节数组
  4. byte[] bytes = new byte[1024*2];
  5. int len;
  6. while ((len=fis.read(bytes))!=-1){
  7. System.out.println(new String(bytes,0,len));
  8. }
  9. //释放资源
  10. fis.close();
  11. }

3.4 资源释放

  1. 我们在前面处理异常的时候都同意做了声明抛出的处理。但是这很可能导致在出现了异常时资源没有被正确的释放。所以我们要更合理的处理异常,尤其是处理资源释放的问题。

3.4.1 JDK6版本

  1. private static void test() {
  2. FileInputStream fis = null;
  3. try{
  4. fis = new FileInputStream("C:\\Users\\root\\Desktop\\test\\11.txt");
  5. //读取数据 一次读一个字节数组
  6. byte[] bytes = new byte[1024*2];
  7. int len;
  8. while ((len=fis.read(bytes))!=-1){
  9. System.out.println(new String(bytes,0,len));
  10. }
  11. }catch (IOException e){
  12. e.printStackTrace();
  13. }finally {
  14. //释放资源
  15. if(fis!=null){
  16. try {
  17. fis.close();
  18. } catch (IOException e) {
  19. e.printStackTrace();
  20. }
  21. }
  22. }
  23. }

3.4.2 JDK7版本

可以使用try…catch…resource的写法,在try的后面可以加小括号,把需要释放的资源在小括号中定义。我们就不需要自己去释放资源,jvm会帮我们再最后调用close方法释放资源的。

  1. private static void test2() {
  2. try(FileInputStream fis =new FileInputStream("C:\\Users\\root\\Desktop\\test\\11.txt"); ){
  3. //读取数据 一次读一个字节数组
  4. byte[] bytes = new byte[1024*2];
  5. int len;
  6. while ((len=fis.read(bytes))!=-1){
  7. System.out.println(new String(bytes,0,len));
  8. }
  9. }catch (IOException e){
  10. e.printStackTrace();
  11. }
  12. }

3.4.3 JDK9版本

资源的定义也可以不放在try的小括号中,只要在try的小括号中声明要释放的资源即可。

  1. private static void test3() throws FileNotFoundException {
  2. FileInputStream fis =new FileInputStream("C:\\Users\\root\\Desktop\\test\\11.txt");
  3. try(fis ){
  4. //读取数据 一次读一个字节数组
  5. byte[] bytes = new byte[1024*2];
  6. int len;
  7. while ((len=fis.read(bytes))!=-1){
  8. System.out.println(new String(bytes,0,len));
  9. }
  10. }catch (IOException e){
  11. e.printStackTrace();
  12. }
  13. }

4. 字节输出流

  1. 所有字节输出流的父类是 java.io.OutputStream ,它是以字节为单位的输出流
  2. 我们就以FileOutputStream为例进行学习。

4.1 FileOutputStream概述

  1. FileOutputStream是用来往文件中写入数据的字节输出流。

4.2 FileOutputStream对象创建

常用构造方法如下:

  1. FileOutputStream(String name) throws FileNotFoundException //传入文件路径创建对象
  2. FileOutputStream(File file) throws FileNotFoundException //传入文件路径的File对象来创建流对象

示例:

  1. public static void main(String[] args) throws FileNotFoundException {
  2. FileOutputStream fos = new FileOutputStream("C:\\Users\\root\\Desktop\\test\\11.txt");
  3. File file = new File("C:\\Users\\root\\Desktop\\test\\11.txt");
  4. FileOutputStream fos2 = new FileOutputStream(file);
  5. }

4.3 写数据

  1. 我们可以使用FileOutputStream来往文件中写入字节数据。

4.3.1 一次写一个字节

核心方法如下:

  1. public void write(int b) throws IOException //传入一个字节数据,把字节数据写入文件

范例:

  1. public static void main(String[] args) throws IOException {
  2. File file = new File("C:\\Users\\root\\Desktop\\test\\11.txt");
  3. FileOutputStream fos = new FileOutputStream(file);
  4. fos.write('a');
  5. fos.close();
  6. }

4.3.2 一次写一个字节数组

核心方法如下:

  1. public void write(byte b[]) throws IOException // 存入一个字节数组,把字节数组中的数据全部写入文件
  2. public void write(byte b[], int off, int len) throws IOException //存入一个字节数组,把字节数组中从off索引开始len个元素写入文件

范例:

  1. public static void main(String[] args) throws IOException {
  2. File file = new File("C:\\Users\\root\\Desktop\\test\\11.txt");
  3. FileOutputStream fos = new FileOutputStream(file);
  4. byte[] bytes = "abc".getBytes();
  5. // fos.write(bytes);
  6. fos.write(bytes,0,2);
  7. fos.close();
  8. }

4.4文件续写

  1. 如果用之前的构造方法创建的流对象,每次流对象创建的时候就会把文件中的内容情况。所以没有办法实现续写的效果。如果需要续写就需要使用另外的构造方法。
  1. FileOutputStream(String name, boolean append) throws FileNotFoundException //第二个参数代表是否续写
  2. FileOutputStream(File file, boolean append) throws FileNotFoundException //第二个参数代表是否续写
  1. 使用什么的构造创建流对象,并且第二个参数传入true,就不会清空文件中原有的内容。实现文件续写的效果。

范例:

  1. public static void main(String[] args) throws IOException {
  2. File file = new File("C:\\Users\\root\\Desktop\\test\\11.txt");
  3. FileOutputStream fos = new FileOutputStream(file,true);
  4. byte[] bytes = "abc".getBytes();
  5. // fos.write(bytes);
  6. fos.write(bytes,0,2);
  7. fos.close();
  8. }

5.练习

5.1 文件复制

  1. 要求定义一个方法,该方法能够实现文件的复制
  1. public static void main(String[] args) throws IOException {
  2. // 要求定义一个方法,该方法能够实现文件的复制
  3. // 文件的复制就是循环的读写,直到操作完所有数据为止
  4. File src = new File("C:\\Users\\root\\Desktop\\test\\11.txt");
  5. File destDir = new File("C:\\Users\\root\\Desktop\\test\\a");
  6. copyFile(src,destDir);
  7. }
  8. //源文件的路径 File srcFile
  9. //目标文件的存放目录路径 File destDir
  10. public static void copyFile(File srcFile,File destDir) throws IOException {
  11. //在destDir下创建一个和srcFile同名的文件
  12. File destFile = new File(destDir,srcFile.getName());
  13. //读取源文件 把读到的数据写入目标文件destFile
  14. FileInputStream fis = new FileInputStream(srcFile);
  15. FileOutputStream fos = new FileOutputStream(destFile);
  16. byte[] bytes = new byte[1024];
  17. int len;
  18. while((len=fis.read(bytes))!=-1){
  19. //把读到的内容写入新文件中
  20. fos.write(bytes,0,len);
  21. }
  22. //释放资源
  23. fis.close();
  24. fos.close();
  25. }

5.2 文件夹复制

  1. 要求定义一个方法,该方法能够实现文件夹的复制
  1. public class Test09 {
  2. public static void main(String[] args) throws IOException {
  3. //要求定义一个方法,该方法能够实现文件夹的复制,考虑有子文件夹的情况
  4. File srcDir = new File("C:\\Users\\root\\Desktop\\test");
  5. File dest = new File("C:\\Users\\root\\Desktop\\test2");
  6. copyDir(srcDir,dest);
  7. }
  8. //File srcDir 源文件夹
  9. //File dest要复制到哪个目录
  10. public static void copyDir(File srcDir,File dest ) throws IOException {
  11. if(!(srcDir.exists()&&srcDir.isDirectory())){
  12. throw new RuntimeException("源文件夹必须存在并且是一个文件夹");
  13. }
  14. if(!dest.isDirectory()){
  15. throw new RuntimeException("目标文件夹必须是一个文件夹");
  16. }
  17. //1.在目标文件夹下创建一个和源文件夹同名的文件夹destDir
  18. File destDir = new File(dest,srcDir.getName());
  19. destDir.mkdirs();
  20. //2.获取源文件夹下的所有子文件
  21. File[] files = srcDir.listFiles();
  22. if(files!=null){
  23. //3.遍历数组,复制每一个文件到目标文件夹destDir下
  24. for (File file : files) {
  25. if(file.isFile()){
  26. copyFile(file,destDir);
  27. }else {
  28. //复制文件夹
  29. copyDir(file,destDir);
  30. }
  31. }
  32. }
  33. }
  34. //源文件的路径 File srcFile
  35. //目标文件的存放目录路径 File destDir
  36. public static void copyFile(File srcFile,File destDir) throws IOException {
  37. //在destDir下创建一个和srcFile同名的文件
  38. File destFile = new File(destDir,srcFile.getName());
  39. //读取源文件 把读到的数据写入目标文件destFile
  40. FileInputStream fis = new FileInputStream(srcFile);
  41. FileOutputStream fos = new FileOutputStream(destFile);
  42. byte[] bytes = new byte[1024];
  43. int len;
  44. while((len=fis.read(bytes))!=-1){
  45. //把读到的内容写入新文件中
  46. fos.write(bytes,0,len);
  47. }
  48. //释放资源
  49. fis.close();
  50. fos.close();
  51. }
  52. }