重庆—java互联网架构软件工程师学习记录—IO

Java互联网架构软件工程师——第一阶段

java—IO


提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档


前言


提示:以下是本篇文章正文内容,下面案例可供参考

一、IO简介

IO是简称.以程序为准.
i全称是in,是指从磁盘 读取 到程序中的过程
o全称是out,是指从程序中 写出 到磁盘的过程
根据读写数据的类型不同,分为两种流.
字符流:专门用来读写字符文件txt
字节流:可以读写任意类型的文件–推荐

在这里插入图片描述

二、File文件流

2.1 概述

封装一个磁盘路径字符串,对这个路径可以执行一次操作。
可以用来封装文件路径、文件夹路径、不存在的路径。

2.2 创建对象

File(String pathname)
      通过将给定路径名字符串转换为抽象路径名来创建一个新 File 实例。

2.3 常用方法

文件。文件夹属性

length():文件的字节量
exists():是否存在,存在返回true
isFile():是否为文件,是文件返回true
isDirectory():是否为文件夹,是文件夹返回true
getName():获取文件/文件夹名
getParent():获取父文件夹的路径
getAbsolutePath():获取文件的完整路径

创建,删除

createNewFile():新建文件,文件夹不存在会异常,文件已经存在返回false
mkdirs():新建多层不存在的文件夹\a\b\c
mkdir():新建单层不存在的文件夹\a
delete():删除文件,删除空文件夹

文件夹列表

list():返回String[],包含文件名
listFiles():返回File[],包含文件对象

案例
代码如下(示例):


// 测试 file 文件流
public class Test01 {
    public static void main(String[] args)
            throws IOException {
        // 创建对象 --- 指定文件的路径
        File file = new File("D:\\iotest\\1.txt");
        // 调用方法
        System.out.println(file.getName());//获取文件名
        System.out.println(file.length());//获取文件大小
        System.out.println(file.exists());//判断文件是否存在
        System.out.println(file.isFile());//判断是否为文件
        System.out.println(file.isDirectory());//判断是否为文件夹
        System.out.println(file.getParent());//获取父文件夹的路径
        System.out.println(file.getAbsolutePath());//获取文件的完整路径

        //TODO

        file = new File("D:\\iotest\\2.txt");
        System.out.println(file.createNewFile());//创建新文件
        //System.out.println(file.delete());

        file = new File("D:\\iotest\\a");
        System.out.println(file.mkdir());//新建单层文件夹

        file = new File("D:\\iotest\\b\\c\\d");
        System.out.println(file.mkdirs());//新建多层不存在文件夹

        System.out.println(file.delete());//删除空文件夹 文件

        //列出文件夹的资源
        file = new File("D:\\iotest");
        //把文件名列出来
        String[] s= file.list();
        System.out.println(Arrays.toString(s));//[1.txt, 2.txt, a, b]
        //把所有资源列出来,并封装成一个一个的File对象存入File[]
        File[] s2 = file.listFiles();
        System.out.println(Arrays.toString(s2));//[D:\iotest\1.txt, D:\iotest\2.txt, D:\iotest\a, D:\iotest\b]

        //file[]里存的是一个一个的File,如果遍历数组
        //就会得到每个File,就可以用上面各种方法
        File a =  s2[0];
        System.out.println(a.length());
        System.out.println(a.getName());

        //TODO 练习:获取文件里的所有资源
        //创建File,封装指定路径
        File f = new File("D:\\");
        //列出所有资源
        File[] res = f.listFiles();
        //遍历
        for (int i = 0; i <res.length ; i++) {
            //获取每个资源ff
            File ff = res[i];

            if (ff.isFile()){
                //判断,文件就是打印文件名
                System.out.println(ff.getName());
            }else if (ff.isDirectory()){
                //判断,文件夹就是打印文件夹名
                System.out.println(ff.getName());
            }

        }


    }
}

2.4 递归思想

递归–在方法内部调用自己–因为发生了和自己一样的过程

案例:
代码如下(示例):

// 测试 File 工具类 -- 递归
public class Test02 {
    public static void main(String[] args) {
        //TODO 求目录的总大小
        System.out.println("请输入文件夹的路径:");
        String s = new Scanner(System.in).nextLine();
        File f= new File(s);
        long toal = method1(f); //求目录的总大小
        System.out.println("文件的总大小为:"+toal);
    }

    private static long method1(File wj) {
        //求目录的总大小
        File[] f1 = wj.listFiles();
         long Sum1 = 0;
         //遍历数组,获取每个资源f1[i]
        for (int i = 0; i <f1.length ; i++) {
            //判断, 是文件就直接求和
            if (f1[i].isFile()){
                Sum1= Sum1+f1[i].length();
            }else if (f1[i].isDirectory()){
                // 判断,是文件夹
                // 就开始继续列表,继续判断是文件求和
                Sum1=Sum1+method1(f1[i]);
                //递归---在方法内部调用自己
            }
        }
        System.out.println("文件路径为:"+wj.getAbsolutePath()+"\t"+"文件大小为:"+Sum1);

        return Sum1;
    }


}

三、字节流的读取

3.1 概述

字节流读取in:指从 磁盘 读取到 程序的过程

3.2 InputStream抽象类

表示字节输入流的所有类的父类/抽象类。
不能new,只能学习提供共性方法

常用方法:

abstract  int read()
从输入流中读取数据的下一个字节。
int read(byte[] b)
从输入流中读取一定数量的字节,并将其存储在缓冲区数组 b 中。
int read(byte[] b, int off, int len)
将输入流中最多 len 个数据字节读入 byte 数组。
void close()
关闭此输入流并释放与该流关联的所有系统资源。

3.3 FileInputStream抽象子类

子类,通常继承和重写
—从文件系统中的某个文件中获得输入字节

创建对象
FileInputStream(File file)
FileInputStream(String name)
该处使用的url网络请求的数据。

3.4 BufferedInputStream 抽象子类

子类,缓冲能力,有内部缓冲区数组

创建对象:

BufferedInputStream(InputStream in)

3.5 谈谈你对 FileInputStream和 BufferedInputStream 的理解

FileInputStream 普通流,一个字节一个字节的读 — 慢
BufferedInputStream 缓冲流/高级流,一个数组一个数组的读 — 快
效率 : BufferedInputStream > FileInputStream
原因: BufferedInputStream底层维护了一个缓冲数据组byte[] buf,默认容量是8192个字节,8k的容量;一次性把数组里的数据批量的读到程序中,提高了单字节数据的读取效率

3.5 案例

代码如下(示例):

//测试  读取流 : 把磁盘里的数据  读到程序中

// FileInputStream 普通流,一个字节一个字节的读 --- 慢
// BufferedInputStream 缓冲流/高级流,一个数组一个数组的读 --- 快
// 效率 : BufferedInputStream > FileInputStream
// 原因:  BufferedInputStream底层维护了一个缓冲数据组byte[] buf,默认容量是8192个字节,8k的容量
// 一次性把数组里的数据批量的读到程序中,提高了单字节数据的读取效率
//面试问答:--- 谈谈你对 FileInputStream和 BufferedInputStream 的理解
public class Test03 {
    public static void main(String[] args)
            throws IOException {
        method();//普通读取流
        System.out.println("-------------");
        method2();//BufferedInputStream 读取流
    }

    private static void method2()
            throws IOException {

         //创建多态对象测试
        InputStream s =
                new BufferedInputStream(new FileInputStream("D:\\iotest\\2.txt"));
         int x= 0;//定义变量,记录变量的值
         while ((x=s.read())!=-1){
             //打印读到的数据
             System.out.println(x);
         }
         s.close();

    }

    private static void method()
            throws IOException {
        // 1. 创建对象
        // 创建子类对象时,值提供了含参构造
        //FileInputStream(String name)---name 是文件的路径
        InputStream a =
                new FileInputStream("D:\\iotest\\1.txt");
        //FileInputStream(File file)
        InputStream in =
                new FileInputStream(new File("D:\\iotest\\1.txt"));

        //2.正式开始读取数据
             //多态对象,只能调用父类的功能,统一调用标准

        //重复读,读到-1就结束
     /*   int data =a.read();
        System.out.println(data);
        int data1 =a.read();
        System.out.println(data1);
        int data2 =a.read();
        System.out.println(data2);
        //再读,就没有数据了 --- 永远得到 -1
        int data3 =a.read();
        System.out.println(data3);*/
        //优化
        int b =0;
        while ((b=a.read())!=-1){//读到-1的话就结束
            System.out.println(b);

        }
        // 3.释放资源
        a.close();
        //TODO 释放资源后 --- 不能再读
  /*      int data4 =a.read();
        System.out.println(data4);*/

    }
}

四、字节流的写出

4.1 概述

字节流写出out:指 把程序中的数据 写出 到磁盘里

4.2 OutputStream —父类

是一个抽象类,所以共性方法
创建方法:

void close()

      关闭此输出流并释放与此流有关的所有系统资源。

void flush()

      刷新此输出流并强制写出所有缓冲的输出字节。

void write(byte[] b)

      将 b.length 个字节从指定的 byte 数组写入此输出流。

void write(byte[] b, int off, int len)

      将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此输出流。

abstract  void write(int b)

      将指定的字节写入此输出流。

4.3 FileOutputStream 子类

创建对象
FileOutputStream(File file) 
FileOutputStream(String name) 
FileOutputStream(File file, boolean append)
FileOutputStream(String name, boolean append)

4.4 BufferedOutputStream子类

BufferedOutputStream(OutputStream out
创建一个新的缓冲输出流,以将数据写入指定的底层输出流。

4.5 案例

代码如下(示例):

//测试 写出流
//1.FileOutputStream
//2.BufferedOutputStream
// 效率:BufferedOutputStream > FileOutputStream
//原因是:底层维护了一个byte[] buf=8192
//不再是一个一个写出到磁盘了,而是一个数组直接批量写出去.
//提高了单字节写出的效率
public class Test01 {
    public static void main(String[]args)
            throws IOException {

        method();//普通流写出
        method2();//高效流写出

    }

    private static void method2()
            throws IOException {
        //创建多态对象
        OutputStream b =new BufferedOutputStream(new FileOutputStream("D:\\iotest\\2.txt",true));//追加数据
        // 写出数据
        b.write(455);
        // write()的参数可以是byte[],需要把字符串变成byte[]
        b.write("java".getBytes());
        b.close();
    }

    private static void method()
            throws IOException {
        // 1.创建多态对象
        //FileOutputStream(String name) --- 数据覆盖
        //OutputStream a = new FileOutputStream("D:\\iotest\\3.txt");
        //FileOutputStream(String name, boolean append) --- 数据追加
        // 如果第二个参数是true,就是数据追加模式
        OutputStream a = new FileOutputStream("D:\\iotest\\3.txt",true);
        // 2.开始写出
        a.write(101);
        // 为了能写出一串字符串,把String转成byte[]
        a.write("jack".getBytes());
        a.write(101);
        a.write(101);
        a.write(101);
        // 3.释放资源
        a.close();
        // 4.释放资源之后不可以再写入
       // a.write("jack".getBytes());
    }
}

五、综合应用

案例
代码如下(示例):

// 练习 复制文件
public class Test02 {
    public static void main(String[] args)
            throws IOException {


        System.out.println("请输入 源文件 的路径;");
        String x = new Scanner(System.in).nextLine();

        System.out.println("请输入 目标文件 的输入");
        String x1 = new Scanner(System.in).nextLine();

        //调用方法
        copyFile(x, x1);
        System.out.println("文件复制完成!");


    }

    private static void copyFile(String x, String x1)
            throws IOException {
        //读取元文件x,写到目标文件 x1 里
        // 准备写与读
        InputStream in = new BufferedInputStream(new FileInputStream(x));
        OutputStream out = new BufferedOutputStream(new FileOutputStream(x1,true));

        //开始读写
        int a =0;
        while ((a=in.read())!=-1){
            out.write(a);
        }
        //关闭资源
        in.close();
        // 把out里的数据刷新到磁盘里
        // out.flush();刷新
        out.close();
        //面试题:flush 和 close的区别---
        // -flush 只刷新缓冲区,流对象还可以继续使用 ;
        // close 先刷新缓冲区,在释放关闭资源,流对象不可以继续使用

    }
}

六、泛型

6.1 概述

用来约束集合中元素的类型,增强程序的通用性.
通常配合集合使用,标识<>.
泛型是(Generics)是JDK1.5 的一个新特性,其实就是一个『语法糖』,本质上就是编译器为了提供更好的可读性而提供的一种小手段

6.2 泛型声明

泛型可以在接口、方法、返回值上使用:

java.util.List泛型接口/类:

public interface Collection<E> {}

泛型方法的声明:

public <E> void print(E e) {}

在方法返回值前声明了一个表示后面出现的E是泛型,而不是普通的java变量。

6.3 案例

代码如下(示例):

// 测试 泛型的作用
public class Test03 {
    public static void main(String[] args) {
        method();//类型检查
        method2();//增强通用性

    }

    private static void method2() {
        Integer[] a ={1,2,3,4,5,6};
        print(a);
        Double[] b= {1.1,2.2,3.3,4.4,5.5};
        print(b);
        String[] c = {"sbdi","gbfs"};
        print(c);
    }


    //方法的重载现象
    private static <E> void print(E[] a) {
        for (int i = 0; i <a.length ; i++) {
            System.out.println(a[i]);
        }
    }


    //类型检查 +提前报错
    private static void method() {
        // 模拟数组:类型检查+报错位置
        //int[] a={1,2,3,4,5,6};
        // 1.集合里可以添加 元素,类型丰富
        List list =  new ArrayList();
        list.add(10);
        list.add(2.3);
        list.add(true);
        list.add("hello");
        // 2.作用 约束集合里元素的类型
        List<String> list2= new ArrayList();
        list2.add("100");
        //list2.add(200)//没有通过泛型的类型检查
        //3.泛型<??> --?? 不能是基本类型,必须是引用类型
        List<Integer> list3 = new ArrayList();
        // “2”是基本类型 ,约束的必须是包装类型,为什么不报错?
        //自动装箱---把基本类型变成包装类型---new Integer
        list3.add(2);
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值