Java反射和IO流知识点很基础,你真的融会贯通吗???

2022-08-10  本文已影响0人  一眼万年的星空

反射

1. 概念

官方解释:反射是指在程序运行过程中,动态的获取类的信息,并且访问

我们通过反射还是获取类的信息(属性,方法,构造方法),然后访问,只不过我们现在不再以new的方式获取

Java中反射相关的API都位于java.lang.reflect包下

万物皆对象

Class 类

Method 方法

Field 属性

Constructor 构造方法

2. 使用反射获取属性

2.1 获取public修饰的属性

getFields() 获取所有的public修饰的属性对象

getField(String name) 根据名字获取单个属性对象

2.2 获取已声明的属性

getDeclaredFields()获取所有已经定义的属性对象,包括private,默认修饰符,protected,public

getDeclaredField(String name)根据名字获取单个属性对象,可以是任意访问修饰符

3. 使用反射获取方法

3.1 获取public修饰的和继承父类的方法

getMethods()获取所有public修饰的方法和继承父类的方法

getMethod()获取单个的方法

3.2获取本类定义的方法

getDeclaredMethod(String name,Class<?>.....parameterTypes>获取单个本类中声明的方法,如果访问权限不足,可以使用setAccessable(true)修改权限

getDeclaredMethods()获取所有本类中已定义的方法

4.使用反射获取构造器

4.1获取所有public修饰的构造器

getConStructors()获取public修饰的所有构造方法

getConstructor(Class.....type)获取单个的构造器对象

4.2 获取本类中定义的构造方法

getDeclaredConstructors()获取本类中定义的所有构造方法

getDeclaredConstructor()获取单个的构造方法

IO流

1.File类

File 类提供了一些用于查看文件信息的方法

package com.qfedu.test4;

import java.io.File;
import java.io.IOException;

/**
 *  java.io.File类
 *  此类提供了一些用于获取文件信息的方法
 *  比如 名称  大小 等等  
 * @author WHD
 *
 */
public class TestFile {
    public static void main(String[] args) throws IOException {
        File file = new File("a.txt");
        file.createNewFile(); // 创建一个新文件
        System.out.println("文件名" + file.getName());
        System.out.println("相对路径" + file.getPath());
        System.out.println("绝对路径" + file.getAbsolutePath());
        System.out.println("是否存在" + file.exists());
        System.out.println("是否是一个文件" + file.isFile());
        System.out.println("是否是一个文件夹" + file.isDirectory());
        System.out.println("文件大小" + file.length());
        System.out.println("删除文件" + file.delete());
        
        File dir = new File("A");
        dir.mkdir();
        System.out.println("是否是一个文件夹" + dir.isDirectory());
        
        
        File dir1 = new File("E/F/G");
        dir1.mkdirs();
        
        File f = new File("C:\\Users\\WHD\\Desktop\\2103.txt");
        f.createNewFile();
        
        
    }
}

2.字节流

2.1 InputStream

字节流读取类父类,是一个抽象类,提供了各种read方法

2.1.1 FileInputStream

提供了用于读写字节的方法,可以一次读取一个字节,也可以读取一个字节数组

package com.qfedu.test5;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

/**
 *  InputStream
 *  FileInputStream 字节读取(输入流)流类
 *      read() 每次读取一个字节 返回值为读取的内容的ascii码值
 *      
 *      close() 关闭资源
 *      available() 获取当前文件可读字节数  
 * 
 *  构造方法
 *      FileInputStream(File file)
 *      FileInputStream(String name)    
 * @author WHD
 *
 */
public class TestFileInputStream1 {
    public static void main(String[] args) throws IOException {
        FileInputStream fis = new FileInputStream("a.txt");
        int data = -1;
        while((data = fis.read()) != -1) {
            System.out.println((char)data);
        }
        
        fis.close(); // 关闭资源
        
        
    }
}
package com.qfedu.test5;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

/**
 *  使用字节流每次读取一个byte数组
 *  read(byte [] datas) 每次读取指定长度的字节 返回值为读取的长度 读取的内容在byte数组
 * @author WHD
 *
 */
public class TestFileInputStream2 {
    public static void main(String[] args) {
        FileInputStream  fis = null;
        try {
            fis = new FileInputStream("b.txt");
            System.out.println(fis.available());
            byte [] datas = new byte[fis.available()];
            int dataCount = -1;
            while((dataCount = fis.read(datas)) != -1) {
//              System.out.println(dataCount);
                System.out.println(new String(datas, 0, dataCount));
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                if(fis != null) {
                    fis.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }   
}

2.2 OutputStream

字节写入流父类,抽象类,提供了各种wirte方法

2.2.1 FileOutputStream

字节写入流类,可以一次写入一个字节,也可以一次写入一个字节数组

package com.qfedu.test6;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 *  OutputStream 父类 抽象类
 *  FileOutputStream 
 *  write(int chars);
 *  write(byte [] datas);
 *  close();
 *  flush(); 将内存中的内容 刷新到硬盘中 字节流是直接操作硬盘的 
 * @author WHD
 *
 */
public class TestFileOutputStream {
    public static void main(String[] args) throws IOException {
        FileOutputStream fos = new FileOutputStream("c.txt", true); // 第二个参数为是否追加 默认为false
        fos.write(98);
        fos.close();
    }
}
package com.qfedu.test6;

import java.io.FileOutputStream;
import java.io.IOException;

/**
 *  每次写入一个字节数组
 * @author WHD
 *
 */
public class TestFileOutputStream2 {
    public static void main(String[] args) throws IOException {
        FileOutputStream fos = new FileOutputStream("d.txt", true);
        String info = "hello world 世界你好";
        fos.write(info.getBytes());
        fos.write("你好".getBytes());
        fos.close();
    }
}

3.字符流

3.1 Reader

字符读取流父类,抽象类。提供了各种read方法。

3.1.1 InputStreamReader

此类提供各种read方法,可以一次读取一个字符,也可以一次读取一个char数组,还支持指定读取的编码格式

package com.qfedu.test1;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;

/**
 *  Reader类抽象类父类
 *  InputStreamReader子类
 *  字符读取流:
 *  read 每次读取一个字符 返回值为读取的内容
 *  read(char [] datas) 每次读取一个字符数组  返回值是读取的长度 内容在char数组
 *  
 *  close 关闭资源
 * @author WHD
 *
 */
public class TestInputStreamReader1 {
    public static void main(String[] args) throws IOException {
        FileInputStream fis = new FileInputStream("a.txt");
        InputStreamReader isr = new InputStreamReader(fis);
        int data = -1;
        
        while((data = isr.read()) != -1){
            System.out.println((char)data);
        }
        
        
        // 关闭的顺序 先用后关
        isr.close();
        fis.close();
        
    }
}
package com.qfedu.test1;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;

/**
 *  每次读取一个字符数组
 * @author WHD
 *
 */
public class TestInputStreamReader2 {
    public static void main(String[] args) throws IOException {
        InputStreamReader isr = new InputStreamReader(new FileInputStream("a.txt"));
        char [] chars = new char[5];
        int readCount = 0;
        while((readCount = isr.read(chars)) != -1) {
//          System.out.println(readCount);
            System.out.println(chars);
            System.out.println(new String(chars, 0, readCount));
            System.out.println("========================"); 
        }
        // 关闭资源
        isr.close();    
    }
}
package com.qfedu.test1;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;

/**
 *  使用InputStreamReader构造方法指定编码格式 解决乱码问题
 * 
 *  乱码产生的原因:
 *      编码和解码方式不统一 将会产生乱码
 *  解决方案:
 *      让编码和解码使用一种编码格式就可以了
 *  
 *  UTF-8 Unicode编码格式 万国码 支持中文及其他国家的语言
 *  GBK 国标扩展板 支持大部分的中文简体和繁体
 *  GB2312 国标2312 支持大部分的中文简体
 *  ISO-8859-1 最原始的编码格式  用于处理字符串内容乱码
 *  ANSI在不同的操作系统表示不同的编码格式  在中文Win10 表示 GBK
 * @author WHD
 *
 */
public class TestInputStreamReader3 {
    public static void main(String[] args) throws IOException {
        System.getProperties().list(System.out);
        
        
        InputStreamReader isr = new InputStreamReader(new FileInputStream("C:\\Users\\WHD\\Desktop\\2103.txt"),"utf-8");
        int data = -1;
        while(( data = isr.read()) != -1) {
            System.out.println((char)data);
        }
        
        // 关闭资源
        isr.close();
        
    }
}
3.1.1.1 FileReader

FileReader 此类只能按照本地平台默认的编码格式来读取 不能指定编码

package com.qfedu.test2;

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

/**
 *  Reader
 *  InputStreamReader
 *  FileReader 此类只能按照本地平台默认的编码格式来读取 不能指定编码
 *  
 * @author WHD
 *
 */
public class TestFileReader {
    public static void main(String[] args) throws IOException {
        FileReader reader = new FileReader("a.txt");
        int data = -1;
        while((data = reader.read() )!= -1){
            System.out.println((char)data);
        }
        reader.close();
    }
}
package com.qfedu.test2;

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

/**
 *  使用FileReader每次读取一个字符数组
 * @author WHD
 *
 */
public class TestFileReader2 {
    public static void main(String[] args) throws IOException {
        FileReader reader = new FileReader("a.txt");
        char [] chs = new char[5];
        int dataCount = -1;
        while((dataCount = reader.read(chs)) != -1) {
            System.out.println(new String(chs,0,dataCount));
        }
        
        reader.close();
        
    }
}
3.1.2 BufferedReader

带有缓冲区的字符读取流,提供了独有的读取整行的方法readLine()

package com.qfedu.test2;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;

public class TestBufferedReader {
    public static void main(String[] args) throws IOException {
        BufferedReader  br = new BufferedReader(new InputStreamReader(new FileInputStream("a.txt")));
        String line = null;
        while((line = br.readLine()) != null) {
            System.out.println(line);
        }
        // 关闭资源
        br.close();
    }
}

3.2 Writer

字符写入流父类,抽象类,提供了各种write方法

3.2.1 OutputStreamWriter

字符写入流,可以一次写入一个字符,也可以一次写入一个char数组,可以指定写入的编码格式

package com.qfedu.test3;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;

/**
 *  Writer抽象类父类
 *  OutputStreamWriter 子类
 *  write(String str);
 * 
 *  OutputStreamWriter 可以指定写入的编码格式
 * @author WHD
 *
 */
public class TestOutputStreamWriter {
    public static void main(String[] args) throws IOException {
        OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("b.txt",true));
        osw.write(98);
        osw.write("hello world");
        osw.write("世界你好".toCharArray());
        osw.flush(); // 字符流相当于有一个缓冲区 不是直接操作硬盘的
        osw.close();
    }
}
package com.qfedu.test3;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;

/**
 *  Writer抽象类父类
 *  OutputStreamWriter 子类
 *  write(String str);
 * 
 *  OutputStreamWriter 可以指定写入的编码格式
 * @author WHD
 *
 */
public class TestOutputStreamWriter2 {
    public static void main(String[] args) throws IOException {
        OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("c.txt",true),"gbk");
        osw.write(98);
        osw.write("hello world");
        osw.write("世界你好".toCharArray());
        osw.flush(); // 字符流相当于有一个缓冲区 不是直接操作硬盘的
        osw.close();
    }
}
3.2.1.1 FileWriter

FileWriter不能指定编码格式写入

package com.qfedu.test3;

import java.io.FileWriter;
import java.io.IOException;

/**
 *  Writer
 *  OutputStreamWriter
 *  FileWriter不能指定编码格式写入
 * @author WHD
 *
 */
public class TestFileWriter {
    public static void main(String[] args) throws IOException {
        FileWriter fw = new FileWriter("d.txt", true); 
        fw.write("hello world");
        fw.flush();
        fw.close();
    }
}
3.2.2 BufferedWriter

此类提供的有换行的方法 newLine()

package com.qfedu.test3;

import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;

/**
*   Writer
*   BufferedWriter 
*   此类提供的有换行的方法  newLine()
* @author WHD
*
*/
public class TestBufferedWriter {
   public static void main(String[] args) throws IOException {
    BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("e.txt")));
    bw.write("hello world1\n");
    bw.write("hello world2\n");
    bw.newLine();
    bw.write("世界你好");
    bw.flush();
   }
}

4.数据流

4.1 DataInputStream读取二进制文件

4.2 DataOutputStream写入二进制文件

读 DataInputStream

写 DataOutputStream

package com.qfedu.test4;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 *  读取二进制文件
 *  读  DataInputStream
 *  写  DataOutputStream
 * @author WHD
 *
 */
public class TestDataStream {
    public static void main(String[] args) throws IOException {
        FileInputStream fis = new FileInputStream("C:\\Users\\WHD\\Desktop\\zs.jpg");
        DataInputStream dis = new DataInputStream(fis);
        byte [] datas = new byte[fis.available()];
        System.out.println(dis.read(datas));
        // System.out.println(new String(datas,0,datas.length)); 因为图片是二进制文件 所以不要打印
        
        DataOutputStream dos = new DataOutputStream(new FileOutputStream("copyzs.jpg"));
        dos.write(datas);
        
        // 关闭资源 
        
        dos.close();
        dis.close();
        fis.close();
    
    }
}

5.对象流

5.1 序列化和反序列化

序列化:将对象写入到二进制文件中
反序列化:将存有对象的二进制文件读取为对象
注意:可以被序列化的对象所属的类必须实现Serializable接口,此接口是一个空接口,仅仅作为一个标识,表示此接口的实现类可以被序列化。
被transient修饰的属性不能被序列化。

序列化ID
用于判断读取出来的对象 是所属于哪个类的实例 相当于一个唯一表示
可以自动生成默认的1L
也可以随机生成
也可以不写 因为JVM会自动帮我们添加一个

package com.qfedu.test5;

import java.io.Serializable;
/**
 *  Serializable接口没有方法 只相当于一个标识 标识此类的实现类可以被序列化
 *  序列化ID 
 *  用于判断读取出来的对象 是所属于哪个类的实例  相当于一个唯一表示
 *  可以自动生成默认的1L
 *  也可以随机生成 
 *  也可以不写  因为JVM会自动帮我们添加一个
 * @author WHD
 *
 */
public class Student implements Serializable{
    private  static final long serialVersionUID = 1656714578162247302L;
    private int age;
    private String name;
    private transient String address; // 被transient修饰的属性  不能被序列化
    
    public String getAddress() {
        return address;
    }
    public void setAddress(String address) {
        this.address = address;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Student() {
    }
    public Student(int age, String name) {
        this.age = age;
        this.name = name;
    }
    @Override
    public String toString() {
        return "Student [age=" + age + ", name=" + name + ", address=" + address + "]";
    }
}
package com.qfedu.test5;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

/**
 *  ObjectInputStream 读取对象流
 *  ObjectOutputStream 写入对象流
 * @author WHD
 *
 */
public class TestObjectStream {
    public static void main(String[] args) throws FileNotFoundException, IOException, ClassNotFoundException {
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("stu.txt"));
        Student zhaosi = new Student(20,"赵四");
        zhaosi.setAddress("象牙山");
        Student guangkun = new Student(20,"广坤");
        guangkun.setAddress("铁岭的");
        Student dana = new Student(20,"大拿");
        dana.setAddress("东北的");
        oos.writeObject(zhaosi);
        oos.writeObject(guangkun);
        oos.writeObject(dana);
        oos.flush();
        
        
        FileInputStream fis = new FileInputStream("stu.txt");
        ObjectInputStream ois = new ObjectInputStream(fis);
        
        while(fis.available() > 0) {
            Object obj1 = ois.readObject();
            if(obj1 instanceof Student) {
                Student s = (Student) obj1;
                System.out.println(s);
            }
        }
        
        
        
//      Object obj1 = ois.readObject();
//      if(obj1 instanceof Student) {
//          Student s = (Student) obj1;
//          System.out.println(s);
//      }
//      
//      
//      Object obj2 = ois.readObject();
//      if(obj2 instanceof Student) {
//          Student s = (Student) obj2;
//          System.out.println(s);
//      }
//      
//      Object obj3 = ois.readObject();
//      if(obj3 instanceof Student) {
//          Student s = (Student) obj3;
//          System.out.println(s);
//      }
//      
        ois.close();
        oos.close();        
    }
}

NIO
NIO是一种非阻塞的、面向缓存的IO流
I0和NIO的区别
(1)IO是面向流的阻塞I0流,NIO是面向缓存的非阻塞IO流
(2)IO的通道是单向的,NIO的管道是双向的
(3)I0流在输入输出数据的时候,在输入输出数据不可用或者没有时候会把线程挂起,发生阻塞,NIO在输入输出数据的时候,是在输入输出的时候还可以执行其他操作,不会等待,所以不会发生阻塞

上一篇下一篇

猜你喜欢

热点阅读