Java——泛型和Io流

  • Post author:
  • Post category:java



目录

1.泛型

2.File对象

3.IO流

4. 字节输入和输出流

5. 缓存流

6. 对象流


1泛型


1.1什么是泛型

1. 泛型就是限制我们得数据类型。

2.为什么使用泛型?
我们原来在定义集合时,是如下得定义方式:
        List list=new ArrayList();//该集合没有使用泛型
        list.add("java01");
        list.add("java02");
        String str= (String) list.get(0);//获取元素 需要进行强制类型转换
        System.out.println(str);
获取元素时,不方便对元素进行相应得其他操作。     


1.2如何使用泛型

public static void main(String[] args) {
        List<String> list=new ArrayList<>();//这里就限制了集合中每个元素得类型。
        list.add("java01");
        list.add("hello"); //因为集合中只能添加String类型
        list.add("world"); //因为集合中只能添加String类型

        String s = list.get(0); //在获取元素时 默认就是相应得数据类型 而无需在进行转换

        //<K,V>:K:表示键得泛型  V:表示值得泛型
        HashMap<String,Integer> map=new HashMap<>();
        map.put("name",15);
        map.put("age",25);

        Set<String> keys = map.keySet();
    }

1.3 我们自己能否定义泛型类

肯定可以!
public  class 类名<标识,标识....> {
     标识  变量名;
     
     public 标识 方法名(){
        
     }
     
     public void 方法名(标识 参数名){
     
     
     }
     .........

}


定义坐标类:

public class Test4 {
    public static void main(String[] args) {
        //在创建泛型类对象时没有指定相应得泛型类型。则默认为Object类型
        Point p1=new Point();
        p1.setX(15);
        p1.setX("北纬50度");

        //这里得泛型必须都是对象类型
        Point<Integer> p2=new Point<Integer>() ;
        p2.setX(25);
        p2.setY(65);
        Integer x = p2.getX();
        Integer y = p2.getY();
        p2.show();

        Point<String> p3=new Point<>();
    }
}
class Point<T>{
    private T x;
    private T y;

    public void show(){
        System.out.println("x坐标为:"+x+";y坐标为:"+y);
    }

    public T getX() {
        return x;
    }

    public void setX(T x) {
        this.x = x;
    }

    public T getY() {
        return y;
    }

    public void setY(T y) {
        this.y = y;
    }
}

2. File对象


——————————————————————————————————————————

2.1 file得介绍

File 类 就是当前系统中 文件或者文件夹的抽象表示

通俗的讲  就是 使用File对象 来操作我们电脑系统中的文件或者文件夹

学习File类 其实就是学习 如果通过file对象 对系统中的文件/文件夹进行增删改查

2.2 创建File对象

 public static void main(String[] args) {
        //创建一个File对象 并指定文件得路径  \转移字符串
        File file01 = new File("D:\\AAA\\aaa.txt");
        /*
           \\目录层级  在window系统下层级分割符为\  但是在linux和mac系统上分割符为 /
           我们得java代码是一种跨平台得语言。 我们得开发在window  但是我们项目得部署在linux.
           我们使我们得代码能在任意系统下来用。 我们有两种解决办法
           (1)第一种 因为window 兼容 / 和 \
         */
        File file02 = new File("D:/AAA/bbb.txt");
        // 第二种 File.separator根据当前代码所在得系统自动获取相应得分割符 
        System.out.println(File.separator); // \因为我们当前在window下
        File file03 = new File("D:"+File.separator+"AAA"+File.separator+"ccc.txt");


    }

2.3 增加操作

public static void main(String[] args) throws IOException, InterruptedException {
        //创建File对象
        File file1=new File("E:/AAA/aaa.txt");
        file1.createNewFile();//创建相应的文件
        File file2=new File("E://AAA/bbb");
        file2.mkdir();//创建目录 make directory 单层目录
        File file3=new File("E:/AAA/ccc/fff");
        file3.mkdirs();//创建多层目录
        File file4=new File("E:/AAA/eee");
        file4.createNewFile();



    }

2.4 删除

  public static void main(String[] args) throws InterruptedException {
        File file01 = new File("D:/AAA/a.txt");
        file01.delete();//删除文件

        File file02 = new File("D:/AAA/eee");
        file02.deleteOnExit(); // 当程序退出后 删除

//        Thread.sleep(5000); //休眠10秒

        File file03 = new File("D://AAA/bbb");
        file03.delete();//删除空目录
        
    }

2.5 修改

 public static void main(String[] args) throws IOException {
        File file1=new File("E:/AAA/t.txt");
        file1.createNewFile();
        //file1.setReadable(false);//设置文件的权限为不能读
        //file1.setWritable(false);//设置文件不能写
        //file1.setReadOnly();//设置只读的权限
        file1.renameTo(new File("E:/AAA/d.txt"));//重命名

    }

2.6 查询

 public static void main(String[] args) {
        File file=new File("E:/AAA/ccc/fff/a.txt");

        String name = file.getName(); //得到文件得名称
        System.out.println("name======"+name);
        String parent = file.getParent(); //得到父级路径得名称
        System.out.println("parent===="+parent);
        String path = file.getPath(); //得到文件得路径名称
        System.out.println("path======"+path);

        boolean f1 = file.isFile(); //判断该文件对象是否为文件类型
        System.out.println("f1========="+f1);
        boolean f2 = file.isDirectory(); //判断该文件对象是否为目录类型
        System.out.println("f2========="+f2);


        File file2 = new File("E:/AAA");
        String[] list = file2.list(); //列出AAA目录下所有子文件得名称
        System.out.println(Arrays.toString(list));

        File[] files = file2.listFiles(); //列出AAA目录下所有文件对象
        for(File f:files){
            System.out.println(f.toString());
        }


    }


经典题目: 用的方法的递归调用。

显示指定目录下的所有文件。D:/AAA下所有的文件.
public static void main(String[] args) {
          showAllFiles("D:/AAA");
    }
    public static void showAllFiles(String path){
         //使用传入的路径构建文件对象
        File file=new File(path);
        //判断文件是否存在 或者文件是否为目录.
        if(!file.exists() || !file.isDirectory()){
             return;
        }
        //列出该目录下所有的文件对象。
        File[] files = file.listFiles();
        //遍历数组
        for(File f:files){
             if(f.isDirectory()){
                 System.out.println(f.getPath()+"   <Dir>");
                 showAllFiles(f.getPath());//继续调用本方法
             }else{
                 System.out.println(f.getPath()+" ");
             }
        }

    }

3. IO流

1. IO 表示有两个单词的缩写。

I: Input 输入   O: Output 输出

2. IO的作用:就是对文件中的内容进行操作。

输入: 读操作(读取文件的内容)   输出: 写操作(往文件中写内容)

3. IO流的分类:

(1)根据流的方向:

—输入流: 程序可以从中读取数据的流。

—输出流: 程序能向其中写入数据的流。

(2)根据流的单位:

—字节流: 以字节为单位传输数据的流

—字符流: 以字符为单位传输数据的流

(3)根据功能

—节点流: 直接和文件进行交互

—处理流: 不是直接作用在文件上。

四个基本的流: 其他的流都是在这四个流的基础上进行扩展的

字节输入流

字节输出流

字符输入流

字符输出流

3.1 Writer字符输出流

它是所有字符输出流的跟类。—FileWriter类

public static void main(String[] args) throws Exception{
        Writer writer = new FileWriter("E:/AAA/g.txt");
        String str="hello 今天要开演唱会";
        writer.write(str);

        writer.flush(); //刷新流
        writer.close(); //关闭流资源
    }


上面每次往文件中写内容时 就会把原来的内容覆盖了。 如何追加内容

public static void main(String[] args) throws Exception{
        //字符输出流 ---指定对哪个文件(路径)进行写操作
        //true:表示允许追加内容到文件中
        Writer  writer=new FileWriter("E:/AAA/g.txt",true);

        String str="Hello 刘德华 今天请来了";
        writer.write(str);

        writer.flush(); //刷新流
        writer.close(); //关闭流资源
    }

3.2 Reader字符输入流

它是所有字符输入流的根类  它的实现类有很多,我们使用FileReader实现类

public static void main(String[] args) throws Exception{
        //创建字符输入流对象 作用:就是读取g.txt里的内容
        Reader reader =new FileReader("E:/AAA/g.txt");
        int count=0;//表示读取字符的个数
       char[] cs=new char[10];//每次读取到元素存入该数组中
        while( (count=reader.read(cs)) !=-1 ){
            String str=new String(cs,0,count);
            System.out.print(str);
        }
         //但是这种效率会很慢 因为每次只读取一个字符。
        // 那么我们可以一次读取多个字符 并存入一个字符数组中
        /*char[] cs =new char[2];
        int x=reader.read(cs);
        System.out.println(x);
        System.out.println(cs);
        String s=new String(cs,0,x);//把字符数组转换为字符串。
       System.out.println(s);
       x=reader.read(cs);
       System.out.println(x);
       System.out.println(cs);
       x=reader.read(cs);
       System.out.println(x);
       System.out.println(cs);*/
    }

完成文件内容的复制。

要求: D:/AAA/d.txt 复制到 C:/AAA/d.txt.

 /*
     完成文件内容的复制功能
     */
    @Test
    public void test02() throws Exception{
         //1.创建一个字符输入流
        FileReader fr=new FileReader("D:/AAA/d.txt");

        //2.创建一个字符输出流
        FileWriter fw=new FileWriter("C:/AAA/f.txt");

        int c=0;//读取到字符的个数
        char[] cs=new char[10];//每次读取的内容放入该数组中

        while( (c=fr.read(cs)) !=-1 ){
            fw.write(cs,0,c);
            fw.flush(); //刷新
        }

        fw.close();
        fr.close();
    }

4. 字节流


——————————————————————————————————————————

4.1 字节输出流–OutputStream

它可以对任意文件进行操作,对文件进行输出操作。以字节为单位。 它是所有字节输出流的父类,FileOutputStream

 //测试字节输出流
    @Test
    public void testOutStream() throws Exception{
        OutputStream os=new FileOutputStream("D:/AAA/g.txt");
        String str="abcd";
        //把字符串转换为字节数组.
        byte[]bytes=str.getBytes();
        os.write(bytes);
        os.flush();
        os.close();
    }

4.2 字节输入流—InputStream

它可以对任意文件进行读操作 ,以字节为单位,它是所有字节输入流的父类,子类有FileInputStream

 //一次一次的读取
    @Test
    public void testInputStream() throws Exception{
            InputStream  is=new FileInputStream("D:/AAA/g.txt");

            byte [] bytes=new byte[3];
            int c=is.read(bytes); //一次读取三个字节 并把读取的内容放入字节数组中  返回读取到字节的个数
            System.out.println(bytes+"=============>个数:"+c);

             c=is.read(bytes); //一次读取三个字节 并把读取的内容放入字节数组中  返回读取到字节的个数
             System.out.println(bytes+"=============>个数:"+c);

        c=is.read(bytes); //一次读取三个字节 并把读取的内容放入字节数组中  返回读取到字节的个数
        System.out.println(bytes+"=============>个数:"+c);

    }
    //如果文件中内容非常大  使用循环来读取
    @Test
    public void testInputStream2() throws  Exception{
        InputStream  is=new FileInputStream("D:/AAA/g.txt");
        byte [] bytes=new byte[300];
        int c=0; //读取到的个数
        while( (c=is.read(bytes))!=-1 ){
            //把byte数组转换为字符串
            String str=new String(bytes,0,c);
            System.out.println(str);
        }

        is.close();
    }

使用字节输入和输出流完成文件的复制功能:

   @Test
    public void testinputStream()throws Exception{
        //1.创建字节输入流 视频
        InputStream is=new FileInputStream("E:/AAA/a3.jpg");
        //2.字节输出流
        OutputStream fos=new FileOutputStream("D:/AAA/a3.jpg");
        byte [] bytes=new byte[10];
        int c=0;
        while ((c= is.read(bytes))!=-1){
            fos.write(bytes,0,c);
        }
        is.close();
        fos.close();

    }

5. 缓存流

缓存流是在基础流[InputStream OutputStream Reader Writer]之上 添加了一个缓存池功能.

BufferInutStream  BufferOutputStream BufferReader  BufferWriter 提高IO的效率,降低IO的次数。

//缓存流
    @Test
    public void TestBuffer() throws Exception{
        OutputStream out=new FileOutputStream("D:/AAA/g.txt");
        BufferedOutputStream  bos=new BufferedOutputStream(out);//缓存流要作用再基础流上
        String str="abcdefhijglmn";
        byte[] bytes = str.getBytes();
        bos.write(bytes);  //因为你写的内容 暂时放入缓存池中  并没有直接放入文件中。 所以文件中没有你的内容。
        //bos.flush();//刷新缓存池---把池子中的内容输入到文件上
        bos.close(); //关闭----先刷新缓冲池 再关闭流资源
    }

6. 对象流–对java对象进行IO操作

为什么需要对象流

我们现在操作IO流的时候 都是将字符串读写操作 可不可以将java对象在文件中进行读写呢? 可以的 Student st=new Student();对象

将java对象进行读写操作 意义在于持久化信息  例如: 游戏存档。

//  因为运行的时候 所有的数据都是在运行内存中的   持久化 将运行内存的数据 保存到硬盘上    存档(写)  读档(读)

 @Test //存档:----序列化:
    public void testObjectStream() throws Exception{
        OutputStream out=new FileOutputStream("D:/AAA/a.txt");
        //对象输出流
        ObjectOutputStream oos=new ObjectOutputStream(out);

        //使用对象输出流调用输出方法 输出的类对象 该类必须实现Serializable 序列化接口
        Role r=new Role("吕布","7级",1,"弑父");
        oos.writeObject(r);
        oos.close();
    }
    //测试 读档: ----反序列化:
    @Test
    public void testObjectStream2()throws Exception{
        InputStream input=new FileInputStream("D:/AAA/a.txt");
        ObjectInputStream ois=new ObjectInputStream(input);
        Object o = ois.readObject();

        System.out.println(o);
        ois.close();
    }

1. 序列化: 把内存中的java对象存储到磁盘[网盘]的过程。

—java对象所属的类必须实现序列化接口.implements Serializable

2. 反序列化: 把磁盘中的内容读取到java对象内存中的过程。


总结:

1.  通过字符流完成文件的复制—->它只能复制文本文件

2.  字节流:—字节输入流和字节输出流。

3.  字节流 我们也可以完成文件的复制功能—它可以复制任意类型的文件.

4.  缓存流—>它基本流的基础上 添加了一个缓存池

5.  对象流: ObjectInputStream  ObjectOutputStream

序列化:

反序列化:



版权声明:本文为qq_55682798原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。