Java基础之递归、 字符集、字节流

递归的形式

递归:方法在方法中又调用了自己。

递归:
直接递归:自己的方法调用自己。
间接递归:自己的方法调用别的方法,别的方法又调用自己。
小结:
递归是自己调用自己。
递归如果控制的不恰当,会形成递归的死循环,从而导致栈内存溢出错误!!
递归应该防止进入递归的死循环!

递归的核心算法思想和执行流程(重点。拓展)

已知:f(x) = f(x - 1) + 1  (恒等式)
已知:f(1) = 1
求:  f(10) = ?

计算流程:
     f(10) = f(9) +  1
     f(9)  = f(8) +  1
     f(8)  = f(7) +  1
     f(7)  = f(6) +  1
     f(6)  = f(5) +  1
     f(5)  = f(4) +  1
     f(4)  = f(3) +  1
     f(3)  = f(2) +  1
     f(2)  = f(1) +  1
     f(1)  = 1

递归的三要素(理论):
1.递归的终结点: f(1) = 1
2.递归的公式:f(x) = f(x - 1) + 1
3.递归的方向:必须走向终结点

拓展:递归的核心思想-公式转换

已知: f(x) = f(x + 1) + 2
      f(1) = 1
求:   f(10) = ?

公式转换:
f(n-1) = f(n-1+1)+2
f(n-1) = f(n)+2
f(n) = f(n-1)- 2 ;

目标:

字符集/编码集

 字符集:各个国家为自己国家的字符取的一套编号规则。
 计算机的底层是不能直接存储字符的。
 计算机的底层只能存储二进制。010101
 二进制就是可以转成10进制的。10进制就是整数编号。
 101 = 1*2^0 + 0*2^1 + 1*2^2 = 5

 结论:计算机的底层可以存储编号。

 1B = 8b   计算机中的最小单位是字节B.

 美国人:
     8个开关一组就可以编码字符。 1个字节。
     2^8 = 256
     一个字节存储一个字符完全够用了。

     a  97
     b  98

     A  65
     B  66

     0  48
     1  49
     这套编码是ASCII编码。

     英文和数字在底层存储的时候都是采用1个字节存储的。

 中国人:
     中国人的字符很多:9万左右字符。
     中国人一般采用2个字节编码一个中文字符。
     这套编码叫:GBK编码。
     它也必须兼容ASCII编码表。
     ....

 美国人:
     我来收集全球所有的字符,统一编号。这套编码叫 Unicode编码(万国码)
     UTF-8就是变种形式。
     UTF-8一个中文一般占3个字节。
     它也必须兼容ASCII编码表。

 小结:
     英文和数字在任何编码集中都是一样的,都占1个字节。
     GBK编码中,1个中文字符一般占2个字节。
     UTF-8编码中,1个中文字符一般占3个字节。
     技术人员都应该使用UTF-8编码!

     编码前与编码后的编码集必须一致才不会乱码!!

     GBK   我爱你[oo oo oo]     GBK     不会乱码!
     GBK   我爱你[oo oo oo]     UTF-8   会乱码!

     英文和数字在任何编码集中可以通用,不会乱码!!

IO流

目标:IO流读写数据。

IO输入输出流:输入/输出流。
Input:输入。
Output:输出。

引入:
    File类只能操作文件对象本身,不能读写文件对象的内容。
    读写数据内容,应该使用IO流。

IO流是一个水流模型:IO理解成水管,把数据理解成水流。

IO流的分类:
    按照流的方向分为:输入流,输出流。
       (1)输出流:以内存为基准,把内存中的数据写出到磁盘文件或者网络介质中去的流称为输出流。
               输出流的作用:写数据到文件,或者写数据发送给别人。

       (2)输入流:以内存为基准,把磁盘文件中的数据或者网络中的数据读入到内存中去的流称为输入流。
               输入流的作用:读取数据到内存。

    按照流的内容分为: 字节流,字符流。
       (1)字节流:流中的数据的最小单位是一个一个的字节,这个流就是字节流。
       (2)字符流:流中的数据的最小单位是一个一个的字符,这个流就是字符流。(针对于文本内容)


所以流大体分为四大类:
    字节输入流:以内存为基准,把磁盘文件中的数据或者网络中的数据以一个一个的字节的形式读入到内存中去的流称为字节输入流。
    字节输出流:以内存为基准,把内存中的数据以一个一个的字节写出到磁盘文件或者网络介质中去的流称为字节输出流。
    字符输入流:以内存为基准,把磁盘文件中的数据或者网络中的数据以一个一个的字符的形式读入到内存中去的流称为字符输入流。
    字符输出流:以内存为基准,把内存中的数据以一个一个的字符写出到磁盘文件或者网络介质中去的流称为字符输出流。
小结:
    IO流是读写传输数据的,IO流有很多种,每种流有自己的功能特点。

字节输入流的使用

IO流的体系:
字节流 字符流
字节输入流 字节输出流 字符输入流 字符输出流
InputStream OutputStream Reader Writer (抽象类)
FileInputStream FileOutputStream FileReader FileWriter (子类实现类)

a.FileInputStream文件字节输入流。
    -- 作用:以内存为基准,把磁盘文件中的数据按照字节的形式读入到内存中的流。
            简单来说,就是按照字节读取文件数据到内存。
    -- 构造器:
       1.public FileInputStream(File path):创建一个字节输入流管道与源文件对象接通。
       2.public FileInputStream(String pathName):创建一个字节输入流管道与文件路径对接。
    -- 方法:
       1.public int read():每次读取一个字节返回!读取完毕会返回-1。

    小结:
        一个一个字节读取英文和数字没有问题。
        但是一旦读取中文输出无法避免乱码,因为会截断中文的字节。
        一个一个字节的读取数据,性能也较差,所以禁止使用此方案!

拓展:解决字节输入流读取中文内容输出乱码的问题。

引入:
一个一个字节读取中文输出
一个一个字节数组读取中文输出均无法避免乱码。
如何实现读取可以避免乱码呢?
1.定义一个字节数组与文件的大小刚刚一样大,然后一桶水读取全部字节数据再输出!
小结:
定义一个字节数组与文件的大小刚刚一样大,然后一桶水读取全部字节数据再输出!
可以避免中文读取输出乱码,但是如果读取的文件过大,会出现内存溢出!!

字节流并不适合读取文本文件内容输出,读写文件内容建议使用字符流。

        // 0.定位文件对象
        File f = new File("Day09Demo/src/dlei03.txt");
        // 1.定义一个字节输入流通向源文件路径,简化写法!
        InputStream is = new FileInputStream(f);

        // 2.定义一个字节数组与文件的大小刚刚一样大
//        System.out.println("文件大小:"+f.length());
//        byte[] buffer = new byte[(int) f.length()];
//        int len = is.read(buffer);
//        System.out.println("读取了:"+len);
//        String rs = new String(buffer);
//        System.out.println(rs);

        byte[] buffer = is.readAllBytes();
        String rs = new String(buffer);
        System.out.println(rs);

字节输出流的使用

IO流的体系:
        字节流                                   字符流
字节输入流           字节输出流               字符输入流       字符输出流
InputStream         OutputStream           Reader         Writer     (抽象类)
FileInputStream     FileOutputStream       FileReader     FileWriter (实现类)

a.FileOutputStream文件字节输出流
    -- 作用:以内存为基准,把内存中的数据,按照字节的形式写出到磁盘文件中去。
             简单来说,把内存数据按照字节写出到磁盘文件中去。
    -- 构造器:
public FileOutputStream(File file):创建一个字节输出流管道通向目标文件对象。
        public FileOutputStream(String file):创建一个字节输出流管道通向目标文件路径。
        public FileOutputStream(File file , boolean append):创建一个追加数据的字节输出

流管道通向目标文件对象。
public FileOutputStream(String file , boolean append):创建一个追加数据的字节输出流管道通向目标文件路径。
– 方法:

   public void write(int a):写一个字节出去 。
   public void write(byte[] buffer):写一个字节数组出去。
   public void write(byte[] buffer , int pos , int len):写一个字节数组的一部分出去。参数一,字节数组;参数二:起始字节索引位置,参数三:写多少个字节数出去。
小结:
    字节输出流只能写字节出去。
    字节输出流默认是覆盖数据管道。
    换行用: os.write("\r\n".getBytes());
    关闭和刷新:刷新流可以继续使用,关闭包含刷新数据但是流就不能使用了!
覆盖数据管道: 
OutputStream os = new FileOutputStream("Day09Demo/out05");
追加数据的管道:
OutputStream os = new FileOutputStream("Day09Demo/out05" , true);
参数二代表了此管道是追加数据的管道,不会覆盖之前的数据!

字节流做文件复制。

字节流复制的思想:
    字节是计算机中一切文件的组成,所以
    字节流适合做一切文件的复制。
    复制是把源文件的全部字节一字不漏的转移到目标文件,只要文件前后的格式一样,绝对不会有问题。

需求:
    原文件:D:\itcast\图片资源\meinv.jpg
    目标文件:D:\itcast\meimei.jpg
分析步骤:
    (1)创建一个字节输入流管道与源文件接通。
    (2)创建一个字节输出流与目标文件接通。
    (3)创建一个字节数组作为桶
    (4)从字节输入流管道中读取数据,写出到字节输出流管道即可。
    (5)关闭资源!

*/

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值