Java中的IO流和反射

简介: 流是指一连串流动的字符,是以先进先出的方式发送信息的通道。程序和数据之间是通过流进行关联的。

一、定义

流是指一连串流动的字符,是以先进先出的方式发送信息的通道。程序和数据之间是通过流进行关联的。

二、分类

1、按流向分
输出流:OutputStream和Writer作为基类
输入流:InputStream和Reader作为基类
2、按处理数据的单元划分
字节流:nputStream/OutputStream作为基类
字符流:Reader/Writer作为基类

三、流之间的层级关系

上层为基类
1、输入
Reader
InputStreamReader(可设置字符编码)    Bufferendreader(带有缓冲区)
InputStream
FileInputStream objecInputStream(反序列化) DateInputStream(读二进制文件)
2、输出
Writer
OuputStreamWriterr(可设置字符编码)    BufferendWriterr(带有缓冲区)
InputStream
FileOutputStream objecOutputStream(序列化) DateIOutputStream(读二进制文件)

四、流的正确使用

1、File类操作文件

package demo1;
import java.io.File;
import java.io.IOException;
/*
 * 使用File类创建文件,并实现更删除、显示文件名和路径操作
 */
public class Test1 {
  public static void main(String[] args) throws IOException {
    File file = new File("D:\\test1.txt");
    if(!file.exists()) {
      file.createNewFile();//不存在创建
    }else {
      file.delete();//存在删除
    }
    System.out.println("该文件的绝对路径名为"+file.getAbsolutePath());
    System.out.println("该文件名为:"+file.getName());
  }
}

特别注意:创建File对象的时候可以放决相对路径也可以放决对路径
直接写test.txt代表的是在该项目底下的文件
而如果携程D:\test.txt的话是代表此文件 在D盘下的文件

File类常用方法:

方法

说明

boolean exisit()

判断文件是否存在

String getName()

获得文件名

boolean creatNewFile()

创建文件(创建前要判断文件是否存在 )

2、使用字节流FileInputStream读文本文件

package demo2;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
/*
 * 字节流FileInputStream读取文件
 */
public class Test1 {
  public static void main(String[] args) throws Exception {
    File file =new File("demo2.txt");
    FileInputStream fis = new FileInputStream(file);
    byte[] b = new byte[fis.available()];
    int data=-1;
    while((data=fis.read(b))!=-1) {
    }
    String str = new String(b);//将字节数组变为字符串
    System.out.println(str);
    fis.close();
  }
}

FileInputStream 常用方法

方法

说明

inr read((byte[] b)

将数据缓存在字节数组中最后通过String的构造方法将字节数组转换成字符串输出

int read()

一个字节一个字节的读

3、使用字节流FileInputStream和FileOutputStream复制文本文件

package demo2;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
/*
 * 复制文件
 */
public class Test2 {
  public static void main(String[] args) {
    FileInputStream fis =null;
    FileOutputStream fos=null;
    try {
      fis= new FileInputStream("D:\\demo1.txt");
      byte[] b = new byte[fis.available()];
      int date =-1;
      while((date=fis.read(b))!=-1){
      }
      fos = new FileOutputStream("E:\\Java\\java学习\\代码\\demo1.txt");
      fos.write(b);
    } catch (FileNotFoundException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    } catch (IOException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }finally{
      if(null!=fos){
        try {
          fos.close();
        } catch (IOException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
        }
      }
      if(null!=fis){
        try {
          fis.close();
        } catch (IOException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
        }
      }
    }
  }
}

4、使用DataInputStream和DataOutputStream读写二进制文件

package demo3;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
/*
 * 复制图片,二进制流的应用
 */
public class Test1 {
  public static void main(String[] args) throws Exception {
    DataInputStream dis = new DataInputStream(new FileInputStream("D:\\1.jpg"));
    DataOutputStream  dos =new DataOutputStream(new FileOutputStream("E:\\Java\\java学习\\代码\\t.jpg"));
    int date=-1;
    while((date=dis.read())!=-1){
      dos.write(date);
    }
    dos.close();
    dis.close();
  }
}

5、字符流FileReader & FileWriter

package demo4;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
/*
 * 字符流FileReader & FileWriter
 */
public class Test1 {
  public static void main(String[] args) throws Exception {
    FileReader fr = new FileReader("demo2.txt");
    //方式一、一个字符一个字符的读
//    int date=-1;
//    while((date=fr.read())!=-1) {
//      System.out.print((char)date);
//    }
    //方式二:字符数组读文件
    char[] c = new char[1024];
    int data =-1;
    while((data=fr.read(c))!=-1) {
    }
    System.out.println(c);
    //为读出的文本文件追加字符
    FileWriter fw = new FileWriter("demo2.txt",true);
    fw.write("我做主");
    //关闭流
    fw.close();
    fr.close();
  }
}

6、使用带有缓冲区的流输入输出,异常处理

package demo5;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
/*
 * 使用带有缓冲区的流输入输出,异常处理
 */
public class Test1 {
  public static void main(String[] args) {
    InputStream is = null;
    InputStreamReader isr = null;
    BufferedReader br = null;
    BufferedWriter bw = null;
    try {
      // 读取文件
      is = new FileInputStream("demo5.txt");
      isr = new InputStreamReader(is, "GBK");
      br = new BufferedReader(isr);
      String info = null;
      while ((info = br.readLine()) != null) {
        System.out.println(info);
      }
      // 写入新的文本
      bw = new BufferedWriter(new FileWriter("demo5.txt", true));//熟悉之后都可以采用这种方式进行简写
      bw.newLine();
      bw.write("今天也要元气满满哦!");
    } catch (FileNotFoundException e) {
      e.printStackTrace();
    } catch (UnsupportedEncodingException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    } finally {//注意如果不管流的话会导致很多东西出现bug,如果有bug先找是否正确的关闭流了
      if (null != bw) {
        try {
          bw.close();
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
      if (null != br) {
        try {
          br.close();
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
      if (null != isr) {
        try {
          isr.close();
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
      if (null != is) {
        try {
          is.close();
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
    }
  }
}

注意指定字符编码,请确认是GBK还是UTF-8

五、一个重要综合性利用流的例子

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
public class IoDemo1 {
  public static void main(String[] args) {
    InputStream is = null;
    InputStreamReader isr = null;
    BufferedReader br = null;
    OutputStream os = null;
    OutputStreamWriter osw = null;
    BufferedWriter bw = null;
    try {
      // 读
      is = new FileInputStream("t1.txt");
      isr = new InputStreamReader(is, "GBK");
      br = new BufferedReader(isr);
      String info = br.readLine();
      System.out.println(info);
      // 写
      os = new FileOutputStream("t2.txt",true);
      osw = new OutputStreamWriter(os, "GBK");
      bw = new BufferedWriter(osw);
      bw.newLine();
      bw.write(info);
    } catch (FileNotFoundException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    } catch (UnsupportedEncodingException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    } catch (IOException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    } finally {
      try {
        bw.close();
        osw.close();
        os.close();
        br.close();
        isr.close();
        is.close();
      } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
      }
    }
  }
}

特别注意:一定要关闭流,有时候没关闭会出现很多的错误

六、序列化和反序列化

1、使用序列化保存对象信息(写出 objecOutputStream)

2、使用反序列化获取对象信息(写出 objecInputStream)
3、例子:

package Demo1;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
/*
 * 序列化和反序列化
 */
public class Test1 {
  public static void main(String[] args) throws Exception, IOException {
    ArrayList<Student> list = new ArrayList<Student>();
    Student stu1 =new Student("jck",12,"男");
    Student stu2 =new Student("lick",13,"男");
    Student stu3 =new Student("as",12,"女");
    list.add(stu1);
    list.add(stu2);
    list.add(stu3);
    //反序列化储存
    ObjectOutputStream oos =new ObjectOutputStream(new FileOutputStream("demo1.txt"));
    oos.writeObject(list);
    //反序列化
    ObjectInputStream ois =new ObjectInputStream(new FileInputStream("demo1.txt"));
    Object obj=ois.readObject();
    ArrayList<Student> stuList = (ArrayList<Student> )obj;
    for(int i =0;i<stuList.size();i++) {
      Student stu=stuList.get(i);
      System.out.println(stu);
    }
  }
}

七、反射

package Demo2;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class Test1 {
  public static void main(String[] args) {
    //先获取Student类对应的Class对象
    Class cla=Student.class;
    //获取所有构造方法
    Constructor[] cons=cla.getConstructors();
    //获取所有构造方法的个数
    System.out.println(cons.length);
    //获取所有构造方法名字
    for (int i = 0; i < cons.length; i++) {
      System.out.println(cons[i].getName());
    }
    //获取共有的属性(只能是public修饰的)
    Field[] fields=cla.getFields();
    for (int i = 0; i < fields.length; i++) {
      System.out.println(fields[i].getName());
    }
    //获取所有的属性
    Field[] fis=cla.getDeclaredFields();
    for (int i = 0;  i< fis.length; i++) {
      System.out.println(fis[i].getType());
    }
    //获取类的方法
    Method[] methods=cla.getMethods();
    for (int i = 0; i < methods.length; i++) {
      System.out.println(methods[i].getName());
    }
  }
}
package Demo2;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
/**
 * 通过反射使用有参构造方法构造Student对象
 * @author Administrator
 *
 */
public class Test2 {
  public static void main(String[] args) throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
    //获取Student对应的Class对象
    Class<Student> cla=Student.class;
    //获取Class对象中的构造方法
    Constructor<Student> cons=cla.getConstructor(String.class,int.class,String.class);
    //为构造方法传递参数
    Student stu=cons.newInstance("jack",100,"123456");
    System.out.println(stu);
  }
}
package Demo2;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
/*
 * 通过反射使用有参构造方法构造Student对象
 */
public class Test3 {
  public static void main(String[] args) throws Exception, SecurityException {
    //获取Student的class对象
    Class cla = Student.class;
    //获取Class对象中的构造方法
    Constructor<Student> cons=cla.getConstructor();
    Student stu=cons.newInstance();
    //获得指定set方法为属性赋值
    Method setNameMethod=cla.getDeclaredMethod("setName", String.class);
    setNameMethod.invoke(stu, "jack");
    Method setAgeMethod=cla.getDeclaredMethod("setAge", int.class);
    setAgeMethod.invoke(stu, 18);
    Method setSexMethod=cla.getDeclaredMethod("setSex", String.class);
    setSexMethod.invoke(stu, "男");
    System.out.println(stu);
  }
}
package Demo2;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
/*
 *通过反射直接为私有属性赋值 
 */
public class Test4 {
  public static void main(String[] args) throws Exception, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
    // 获取Student的class对象
    Class cla = Student.class;
    // 获取Class对象中的构造方法
    Constructor<Student> cons = cla.getConstructor();
    Student stu = cons.newInstance();
    //访问私有成员
    Field nameField=cla.getDeclaredField("name");
    //获取私有属性的操作权限
    nameField.setAccessible(true);
    nameField.set(stu, "张三");
    Field ageField=cla.getDeclaredField("age");
    //获取私有属性的操作权限
    ageField.setAccessible(true);
    ageField.set(stu, 30);
    Field sexField=cla.getDeclaredField("sex");
    //获取私有属性的操作权限
    sexField.setAccessible(true);
    sexField.set(stu, "男");
    System.out.println(stu);
  }
}

反射机制在java框架中会用到!
掌握流的类名,通过相关的构造方法去构造流!

目录
相关文章
|
1月前
|
存储 缓存 Java
java基础:IO流 理论与代码示例(详解、idea设置统一utf-8编码问题)
这篇文章详细介绍了Java中的IO流,包括字符与字节的概念、编码格式、File类的使用、IO流的分类和原理,以及通过代码示例展示了各种流的应用,如节点流、处理流、缓存流、转换流、对象流和随机访问文件流。同时,还探讨了IDEA中设置项目编码格式的方法,以及如何处理序列化和反序列化问题。
67 1
java基础:IO流 理论与代码示例(详解、idea设置统一utf-8编码问题)
|
23天前
|
存储 Java
[Java]反射
本文详细介绍了Java反射机制的基本概念、使用方法及其注意事项。首先解释了反射的定义和类加载过程,接着通过具体示例展示了如何使用反射获取和操作类的构造方法、方法和变量。文章还讨论了反射在类加载、内部类、父类成员访问等方面的特殊行为,并提供了通过反射跳过泛型检查的示例。最后,简要介绍了字面量和符号引用的概念。全文旨在帮助读者深入理解反射机制及其应用场景。
15 0
[Java]反射
|
2月前
|
安全 Java 索引
Java——反射&枚举
本文介绍了Java反射机制及其应用,包括获取Class对象、构造方法、成员变量和成员方法。反射允许在运行时动态操作类和对象,例如创建对象、调用方法和访问字段。文章详细解释了不同方法的使用方式及其注意事项,并展示了如何通过反射获取类的各种信息。此外,还介绍了枚举类型的特点和使用方法,包括枚举的构造方法及其在反射中的特殊处理。
62 9
Java——反射&枚举
|
1月前
|
安全 Java 测试技术
🌟Java零基础-反射:从入门到精通
【10月更文挑战第4天】本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
25 2
|
2月前
|
安全 Java API
【Java面试题汇总】Java基础篇——String+集合+泛型+IO+异常+反射(2023版)
String常量池、String、StringBuffer、Stringbuilder有什么区别、List与Set的区别、ArrayList和LinkedList的区别、HashMap底层原理、ConcurrentHashMap、HashMap和Hashtable的区别、泛型擦除、ABA问题、IO多路复用、BIO、NIO、O、异常处理机制、反射
【Java面试题汇总】Java基础篇——String+集合+泛型+IO+异常+反射(2023版)
|
1月前
|
Java 数据处理 开发者
揭秘Java IO流:字节流与字符流的神秘面纱!
揭秘Java IO流:字节流与字符流的神秘面纱!
35 1
|
1月前
|
自然语言处理 Java 数据处理
Java IO流全解析:字节流和字符流的区别与联系!
Java IO流全解析:字节流和字符流的区别与联系!
76 1
|
29天前
|
Java
Java 中 IO 流的分类详解
【10月更文挑战第10天】不同类型的 IO 流具有不同的特点和适用场景,我们可以根据具体的需求选择合适的流来进行数据的输入和输出操作。在实际应用中,还可以通过组合使用多种流来实现更复杂的功能。
46 0
|
2月前
|
Java 大数据 API
Java 流(Stream)、文件(File)和IO的区别
Java中的流(Stream)、文件(File)和输入/输出(I/O)是处理数据的关键概念。`File`类用于基本文件操作,如创建、删除和检查文件;流则提供了数据读写的抽象机制,适用于文件、内存和网络等多种数据源;I/O涵盖更广泛的输入输出操作,包括文件I/O、网络通信等,并支持异常处理和缓冲等功能。实际开发中,这三者常结合使用,以实现高效的数据处理。例如,`File`用于管理文件路径,`Stream`用于读写数据,I/O则处理复杂的输入输出需求。
|
1月前
|
IDE Java 编译器
java的反射与注解
java的反射与注解
16 0