• java基础第十五篇之IO流和递归算法


    FileInputStream : 输入流

    int available() : 一次读取所有的字节数

    read() : 将文件上的字节读取到内存的数组中

    FileOutputStream : 输出流

    write(byte[] b) : 将字节数组中的字节数据写到文件上

    缓冲区会在内存中创建一个8192容量的字节数组,内存的运算效率比硬盘要高的多所有只要降低到硬盘的读写次数就会提高效率.

    定义小数组的标准格式:进行读写字节数据,要比缓冲流快一点点,因为定义小数组是操作一个的是一个数组,而缓冲流操作的是两个数组.

    public class Demo3_ArrayCopy {
    public static void main(String[] args) throws IOException {
    //method();
    // method2();

    FileInputStream fis = new FileInputStream("韩雪 - 想起.mp3");
    FileOutputStream fos = new FileOutputStream("Copy.mp3");

    byte[] arr = new byte[1024*8];
    int len;
    while((len = fis.read(arr)) != -1) {
    fos.write(arr,0,len);
    }
    fis.close();
    fis.close();

    }


    close方法:具备刷新的功能,在关闭流之前,就会先刷新一次缓冲区,将缓冲区的字节全都刷新到文件上.
    * flush : 具备刷新的功能,刷完之后还可以继续写.


    * 字节流读取中文的问题:字节流在读中文的时候有可能会读到半个中文,造成乱码.
    * 字节流写中文的问题:字节流直接操作字节,所有写出中文比较将字符串转换成字节数组
    * 写出回车换行write(" ".getBytes());

    //这是1.6版本以及以前的标准处理异常代码
    private static void method() throws FileNotFoundException, IOException {
    //为什么要加null?这里是局部变量,所有必须要赋值.
    FileInputStream fis = null;
    FileOutputStream fos = null;
    try {
    fis = new FileInputStream("xxx.txt");
    fos = new FileOutputStream("yyy.txt");

    int b;
    while((b = fis.read()) != -1) {
    fos.write(b);
    }

    }finally {
    //try finally的嵌套目的是能关一个就尽量关一个
    try {
    if(fis != null) {
    fis.close();
    }
    }finally {

    if(fos != null) {
    fos.close();
    }

    }



    }
    }
    }

    ///这些抽象类具备自动关闭功能,只要实现了AutoCloseable就具备了,自动关闭释放流的功能
    //这是jdk1.7版本的标准异常处理代码
    原理:在try()中创建的流对象必须实现了AutoCloseable这个接口,如果实现了,在try后面的{}(读写代码)执行后就会自动调用流对象的close方法将流关闭释放.
    try (
    //这些抽象类具备自动关闭功能,只要实现了AutoCloseable就具备了,自动关闭释放流的功能
    FileInputStream fis = new FileInputStream("xxx.txt");
    FileOutputStream fos = new FileOutputStream("yyy.txt");
    MyClose mc = new MyClose();

    ){
    int b ;
    while((b = fis.read()) != -1) {
    fos.write(b);
    }

    /*FileInputStream fis = new FileInputStream("xxx.txt");
    FileOutputStream fos = new FileOutputStream("yyy.txt");*/


    }
    /*fis.close();
    fos.close();*/

    }

    /*
    * 图片加密
    * 将写出的字节异或上一个数,这个数就是密钥,解密的时候再次异或就可以了.
    */
    public class Test1 {
    public static void main(String[] args) throws IOException {
    BufferedInputStream bis = new BufferedInputStream(new FileInputStream("2017619-星期一-141543.jpg"));
    BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("Copy.jpg"));

    int b;
    while((b = bis.read()) != -1) {
    //运算符 ^ 异或两次就是他本身,所有这里异或一次,进行加密
    bos.write(b ^ 123);
    }
    bis.close();
    bos.close();


    }

    //解密
    /*BufferedInputStream bis = new BufferedInputStream(new FileInputStream("Copy.jpg"));
    BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("Copy2.jpg"));

    int b;
    while((b = bis.read()) != -1) {
    //运算符 ^ 异或两次就是他本身,所有这里异或一次,进行加密
    bos.write(b ^ 123);
    }
    bis.close();
    bos.close();
    *
    *
    */

    }

    * 在控制台录入文件的路径,将文件拷贝到当前项目下
    *
    * 分析:
    *
    * 1.创建键盘录入对象,定义方法对键盘录入的路径进行判断,如果是文件就返回
    * 2.在主方法中接收该文件
    * 3.读和写该文件
    *
    *
    */
    public class Test2 {
    public static void main(String[] args) throws IOException {
    //获取文件
    File file = getFile();

    BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
    BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file.getName()));

    int b;
    while((b = bis.read()) != -1) {
    bos.write(b);
    }
    bis.close();
    bos.close();

    }

    /*
    * 定义一个方法获取键盘录入的文件路径,并封装成File对象返回
    * 1.返回值类型File
    * 2.参数列表无
    *
    */
    public static File getFile() {
    Scanner sc = new Scanner(System.in);
    //接收键盘录入路径
    //String line = sc.nextLine();
    System.out.println("请输入一个文件的路径");
    while(true) {
    String line = sc.nextLine();
    //封装成File对象,并对其进行判断
    File file = new File(line);
    if(!file.exists()) {
    System.out.println("您录入的文件路径不存在,请重新录入:");
    }else if(file.isDirectory()) {
    System.out.println("请录入的是文件夹路径,请重新录入");
    }else {
    return file;
    }


    }


    }
    }


    /*
    * 键盘录入的数据拷贝到当前项目下的text.txt文件中,键盘录入数据当遇到quit时就退出
    *
    * 分析:
    * 1.创建键盘录入对象
    * 2.创建输出流对象,关联text.txt文件
    * 3.定义无限循环
    * 4.遇到quit退出循环
    * 5.如果不quit,就将内容写出
    * 6.关闭流
    *
    */
    public class Test3 {
    public static void main(String[] args) throws IOException {
    //1.创建键盘录入对象
    Scanner sc = new Scanner(System.in);
    //2.创建输出流对象,关联text.txt文件
    FileOutputStream fos = new FileOutputStream("text.txt");
    System.out.println("请输入数据");
    //3.定义无限循环
    while (true) {
    String lin = sc.nextLine();
    //4.遇到quit退出循环
    if("quit".equals(lin)) {
    break;
    }
    //5.如果不quit,就将内容写出
    //字符串写出鼻血转换成字节数组
    fos.write(lin.getBytes());
    fos.write(" ".getBytes());
    }
    fos.close();


    }
    }
    */
    /*
    * 从键盘录入一个文件夹路径,统计该文件夹大小
    *
    * 从键盘录入一个文件夹路径
    * 1.一个无限循环
    * 2.定义一个无限循环
    * 3.将奖品录入的结果存储并封装成File对象
    * 4.对File对象判断
    * 5.将文件夹路径对象返回
    *
    * 统计该文件夹大小
    * 1.定义一个求和变量
    * 2.获取该文件夹下所有的文件和文件夹ListFiles();
    * 3.遍历数组
    * 4.判断是文件就计算大小并累加
    * 5.判断是文件夹,递归调用
    *
    */
    public class Test1 {
    public static void main(String[] args) {
    /*File dir = getDir();
    System.out.println(getFileLength(dir));*/
    //直接获取文件的大小是0
    File dir = new File("F:\day06");
    System.out.println(dir.length());

    }

    /*
    * 从键盘录入接收一个文件夹路径
    * 1.返回值类型File
    * 2.参数列表无
    *
    */
    public static File getDir() {
    //1.创建键盘录入对象
    Scanner sc = new Scanner(System.in);
    System.out.println("请输入一个文件夹路径:");
    //2.循环
    while(true) {
    //将键盘录入的结果存储并封装成File对象
    String line = sc.nextLine();
    File dir = new File(line);
    //对File对象判断
    if(!dir.exists()) {
    System.out.println("您录入的文件夹路径不存在,请输入一个文件夹路径:");
    }else if(dir.isFile()) {
    System.out.println("您录入的是文件路径,请输入一个文件夹路径:");
    }else {
    //将文件夹路径对象返回
    return dir;
    }
    }


    }


    /*
    * 统计该文件夹大小
    * 1.返回值类型 long
    * 2.参数列表File
    *
    */
    public static long getFileLength(File dir) {
    //1.定义一个求和变量
    long len = 0;
    // 2.获取该文件夹下所有的文件和文件夹ListFiles();
    File[] subFiles = dir.listFiles();
    // 3.遍历数组
    for (File subFile : subFiles) {
    //4.判断是文件就计算大小并累加
    if(subFile.isFile()) {
    len = len + subFile.length();
    // 5.判断是文件夹,递归调用
    }else {
    len = len + getFileLength(subFile);
    }

    }




    return len;
    }

    }
    */

    /*

    /*从键盘接收一个文件夹路径,删除该文件夹
    *
    * 删除该文件夹
    * 分析:
    * 1.获取该文件夹下的所有的文件和文件夹
    * 2.遍历数组
    * 3.判断是文件直接删除
    * 4.如果是文件夹,递归调用
    * 5.循环结束后,把空文件夹删掉
    *
    */
    public class Test2 {
    public static void main(String[] args) {
    //获取文件夹路径
    File dir = Test1.getDir();

    deleteFile(dir);

    }
    /*
    * 删除该文件夹
    * 1.返回值类型void
    * 2.参数列表:File dir
    *
    */
    public static void deleteFile(File dir) {
    // 1.获取该文件夹下的所有的文件和文件夹
    File[] subFiles = dir.listFiles();
    //2.遍历数组
    for (File subFile : subFiles) {
    //3.判断是文件直接删除
    if(subFile.exists()){
    subFile.delete();
    //4.如果是文件夹,递归调用
    }else {
    deleteFile(subFile);
    }
    }
    //5.循环结束后,把空文件夹删掉
    dir.delete();


    }
    }

    /*
    * 从键盘接收两个文件夹路径,把其中一个文件夹中(包含内容)拷贝到另一个文件夹中
    *
    * 分析:
    * 1.在目标文件夹中创建原文件夹
    * 2.获取原文件夹中所有的文件和文件夹,存储在File数组中
    * 3.遍历数组
    * 4.如果是文件就用io流读写
    * 5.如果是文件夹就递归调用
    *
    */
    public class Test3 {
    public static void main(String[] args) throws IOException {
    File src = Test1.getDir();
    File dest = Test1.getDir();
    if(src.equals(dest)) {
    System.out.println("目标文件夹是原文件夹的子文件夹");
    }else {
    copy(src,dest);

    }

    }

    /*把其中一个文件夹中(包含内容)拷贝到另一个文件夹中
    * 1.返回值类型void
    * 2.参数列表:File src,File dest
    *
    */
    public static void copy(File src, File dest) throws IOException {
    //1.在目标文件夹中创建原文件夹
    File newDir = new File(dest, src.getName());
    newDir.mkdir();
    // 2.获取原文件夹中所有的文件和文件夹,存储在File数组中
    File[] subFiles = src.listFiles();
    //3.遍历数组
    for (File subFile : subFiles) {
    if(subFile.isFile()) {
    BufferedInputStream bis = new BufferedInputStream(new FileInputStream(subFile));
    BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(new File(newDir,subFile.getName())));
    int b;
    while((b = bis.read()) != -1) {
    bos.write(b);
    }
    bos.close();
    bis.close();

    }else {
    copy(subFile,newDir);
    }
    }


    }
    UTF-8:用UTF-8编码的Java文件英文字符占一个字节,中文字符占三个字节.

    GBK:用GBK编码的中文占用两个字节,英文占用一个字节.

    在Windows里面的.txt文件中编码的一个字符是占用一个字节,一个中文字占用两个字节(日文的一个日文字也占用两个字节)



    }
    /*
    read() : 一次读取一个字节
    //创建一个文件输入流对象,并关联aaa.txt
    FileInputStream fis = new FileInputStream("aaa.txt");
    //定义变量,记录每次读到的字节
    int b;
    //将每次读到的字节赋值给b并判断是否是-1
    while((b = fis.read() != -1) {
    syso(b);
    }
    fis.close();


    read()方法返回值为什么是int?
    因为字节输入流可以操作任意类型的文件,比如图片音频等,这些文件底层都以二进制形式的存储的,如果每次读取都返回byte,有可能在读到中间的时候遇到11111111
    那么这个11111111是byte类型的-1,我们的程序是遇到-1就会停止不读了,后面的数据就读不到了,所以在读取的时候用int类型接收,如果11111111会在其前面补上
    24个0凑足4个字节,那么byte类型的-1就编程int类型的255了这样可以保证整个数据读完,而结束标记的-1就是int类型

    write() : 一次写出一个字节
    //如果没有bb.txt,会创建一个
    FileOutputStream fos = new FileOutputStream("bb.txt");
    //虽然写出的是一个int数,但是在写出的时候会将前面的24个0去掉,所有写出的一个byte.
    //fos.write(97);
    fos.write(98);
    fos.write(99);
    fos.close();

    缓冲思想:
    字节流一次读写一个数组的速度明显比一次读写一个字节的数据快很多,
    这是加入了数组这样的缓冲区效果,java本身在设计的时候.
    也考虑到了这样的设计思想(装饰设计模式) , 所以提供了字节缓冲区流

    BufferedInputStream
    BufferedInputStream内置了一个缓冲区(数组)
    从BufferedInputStream中读取一个字节时
    BufferedInputStream会一次性从文件中读取8192个,存在缓冲区中,返回给程序一个
    程序再次读取时,就不用找文件了,直接从缓冲区中获取.
    直到缓冲区中所有的都被使用过,才重新从文本中读取8192个.

    BufferedOutputStream
    BufferedOutputStream也内置了一个缓冲区(数组)
    程序向流中写字节时,不会直接写到文件,先写到缓冲区中
    直到缓冲区写满,BufferedOutputStream才会把缓冲区中的数据一次性写到文件里

    拷贝代码:
    //创建文件输入流对象,关联致青春.mp3
    FileInputStream fis = new FileInputStream("知情权.mp3");
    //创建缓冲区对fis修饰
    BufferedInputStream bis = new BufferedInputStream(fis);
    //创建输出流对象,关联copy.MP3
    FileOutputStream fos = new FileOutputStream("copy.mp3");
    //创建缓冲区对fos装饰
    BufferedOutputStream bos = new BufferedOutputStream(fos);

    int b;
    while((b = bis.read() != -1) {
    bos.write;
    }
    //只关装饰后的对象即可
    bis.close();
    bos.close();

    小数组的读写和带Buffered的读取那个更快?
    定义小数组如果是8192个字节大小和Buffered比较的话
    定义小数组会略胜一筹,因为读和写操作的是同一个数组
    而Buffered操作的是两个数组

    flush和close的读取那个更快?
    flush()方法:
    用来刷新缓冲流区的,刷新后可以再次写出
    close()方法:
    用来关闭流程释放资源的,如果是带缓冲区的流对象的close()方法,不但会关闭流,还会再关闭之前刷新缓冲区,关闭后不能再写出.

    * File类:文件和目录路径名的抽象表示形式。
    *
    * 文件:可以保存数据的文件
    * 目录路径名:指的文件夹,可以保存文件的
    *
    * 一个File对象 可以指一个文件 也可以指一个文件夹
    * 构造方法:
    * 1.public File(String filename);
    * 2.public File(String parent,String child)
    * 3.public File(File parent,String child)
    */
    public class FileDemo01 {

    public static void main(String[] args) {
    // TODO Auto-generated method stub
    //1.public File(String filename);
    File f1 = new File("E:\黑马66期\1.txt");
    System.out.println(f1);
    //2.public File(String parent, String child)
    File f2 = new File("E:\黑马66期","1.txt");
    System.out.println(f2);
    //3.public File(File parent, String child)
    File parent = new File("E:\黑马66期");
    File f3 = new File(parent, "1.txt");
    System.out.println(f3);
    }

    }


    * 文件:可以保存数据的文件
    * 目录路径名:指的文件夹,可以保存文件的
    * File类的成员方法:
    * 第一组 获取方法
    *
    * public String getAbsolutePath();//获取绝对路径(以盘符开头的路径);
    *
    * public String getPath();//获取路径,你用构造方法创建File对象时写那个路径
    *
    * public String getName();//获取不带路径的文件名
    *
    * public long length();//获取只能文件字节大小
    *
    *
    *
    */
    public class FileDemo02 {

    public static void main(String[] args) {
    // TODO Auto-generated method stub
    //获取绝对路径
    File f1 = new File("E:\黑马66期\1.txt");
    // File f1 = new File("a.txt");
    // String absolutePath = f1.getAbsolutePath();
    // System.out.println(absolutePath);
    //获取路径
    // String path = f1.getPath();
    // System.out.println(path);
    //获取名字
    // String name = f1.getName();
    // System.out.println(name);
    //获取文件的长度
    // long len = f1.length();
    // System.out.println(len);
    //能不能获取文件夹的长度,不能获取,获取到的是一个不确定的值
    // File f2 = new File("E:\黑马66期\test");
    // long len = f2.length();
    // System.out.println(len);
    }

    }

    * 文件和文件夹的创建删除等
    *
    * 1.public boolean createNewFile();//只能创建文件类型File对象,如果此文件存在 那么创建失败
    *
    * 2.public boolean mkdir();//makeDirectory,创建文件夹类型的File对象
    *
    * 3.public boolean exists();//判断File 对象是否存储在
    *
    * 4.public boolean isDirectory();//判断是否是文件夹
    *
    * 5.public boolean isFile();//判断是否是一个文件
    *
    * 6.public boolean delete();//删除文件和文件夹对象
    *
    7.public boolean endsWith() : 判断
    */
    public class FileDemo03 {

    public static void main(String[] args) throws IOException {
    // TODO Auto-generated method stub
    //1.创建文件
    File f1 = new File("E:\黑马66期\test\a.txt");
    // boolean b = f1.createNewFile();
    // System.out.println(b);
    //2.创建文件夹
    // File f2 = new File("E:\黑马66期\test\a.txt");
    // boolean b = f2.mkdir();
    // System.out.println(b);
    //3.判断File对象是否存在
    // File f3 = new File("E:\黑马66期\test\abcd.txt");
    // System.out.println(f3.exists());
    //4.判断到底是文件还是文件夹
    // System.out.println(f1.isDirectory());
    // System.out.println(f1.isFile());
    //5.删除File对象(可以是文件也可以是文件夹)
    File fd = new File("E:\黑马66期\test\abc.txt");
    System.out.println(fd.delete());

    }

    }


    * File类中另外两个比较重要的方法
    *
    * 1. public String[] list();//列出代表文件夹的File对象中的文件和目录,
    * 如果调用方法的File对象表示的是一个文件,会返回null
    *
    *
    * 2. public File[] listFiles();//列出代表文件夹的File对象中的文件和目录,
    * 如果调用方法的File对象表示的是一个文件,会返回null
    *
    */
    public class FileDemo01 {

    public static void main(String[] args) {
    // TODO Auto-generated method stub
    //1.public String[] list()
    // File fileDir = new File("F:\demo");
    // String[] files = fileDir.list();
    // //遍历这个files数组
    // for (String file : files) {
    // System.out.println(file);
    // }
    //2.File[] listFiles()
    File fileDir = new File("F:\demo\1.txt");
    File[] files = fileDir.listFiles();
    for (File file : files) {
    System.out.println(file.getAbsolutePath());
    }

    }

    }

    listFiles():过滤器

    案例:
    Java.io.File.listFiles(FileFilter filter) 返回抽象路径名数组,表示在目录中此抽象路径名表示,满足指定过滤器的文件和目录。

    声明
    以下是java.io.File.listFiles(FileFilter filter) 方法的声明:

    public File[] listFiles(FileFilter filter) 参数
    filter - File filter

    返回值
    该方法返回抽象路径名数组,表示在目录中此抽象路径名表示,满足指定过滤器的文件和目录。

    异常
    SecurityException -- 如果安全管理器存在并且其SecurityManager.checkRead(java.lang.String) 方法拒绝对文件的读访问

    例子
    下面的例子显示 java.io.File.listFiles(FileFilter filter)方法的用法。

    package com.yiibai;

    import java.io.File;
    import java.io.FileFilter;

    public class FileDemo {
    public static void main(String[] args) {

    File f = null;
    File[] paths;

    try{
    // create new file
    f = new File("c:/test");

    FileFilter filter = new FileFilter() {
    @Override
    public boolean accept(File pathname) {
    return pathname.isFile();
    }
    };

    // returns pathnames for files and directory
    paths = f.listFiles(filter);

    // for each pathname in pathname array
    for(File path:paths)
    {
    // prints file and directory paths
    System.out.println(path);
    }
    }catch(Exception e){
    // if any error occurs
    e.printStackTrace();
    }
    }
    }
    让我们编译和运行上面的程序,这将产生以下结果:

    c: estchild_test.txt
    c: estchild_test.xlsx


    * 递归:是一个算法,只要含有方法这种概念的编程语言都可以使用
    * 就是在一个方法内部,调用了自己
    * StackOverflowError:堆栈溢出错误(内存溢出)
    * 递归:1.不能无限的调用自己,必须有出口
    * 2.必须保证递归调用方法的次数有一定限制
    * 递归在JavaEE开中用的还是比较少的
    * 而且递归有一个致命的缺点:急剧消耗内存(建议:实际开发能不用就不用)
    * 递归的分类:
    * 直接递归: A方法内部调用A方法
    * 间接递归: A方法内部调用B B方法内部调用C .... Z方法内部调用A
    * 递归的练习:
    * 递归的代码演示,计算1-n之间的和,使用递归完成
    * 1.使用递归: a.确定规律(分解式子) b.确定出口
    * 递归的代码演示: 计算第100个斐波那契数列的元素的值
    * a.确定规律(分解式子) b.确定出口
    * 第一百个斐波那契数列的元素的值 f(100) = f(99)+f(98)
    * ...
    * f(1) = 1 f(2) = 1



    * 世界一个著名的算法 汉诺塔算法
    *
    * 求斐波那契数列的前20个数和
    */
    1+1+2+3+5+8+12+20

    public class DiGuiDemo01 {

    public static int getSum1(int a,int b){ //a = 1,b = 1
    if(b > ((b-1)+(b-2)) {
    return sum;
    }
    int temp = b;
    b = a + b ;



    a = temp;

    sum = b + getsum1(a,b);

    return sum ;b + getsum1(a , b);//b = 2,a = 1;b = 3,a = 2;b = 5,
    }

    public static void main(String[] args) {
    // TODO Auto-generated method stub
    // int num = getSum(1000);
    // System.out.println(num);
    long num = getFBNum(30);//1 1 2 3 5 8 13 21 34 55
    System.out.println(num);
    }
    /*
    * 求第100个斐波那契数列的元素的值
    */
    public static long getFBNum(int n){
    if(n==1 || n == 2){
    return 1;
    }
    return getFBNum(n-1)+getFBNum(n-2);
    }


    /*
    * 写一个方法求1-n的和
    * 1+2+...+n=== f(n)
    * 1+2+...n-1 === f(n-1)+n
    * f(n) = f(n-1)+n;
    * f(n-1) = f(n-2)+(n-1)
    * f(n-2) = f(n-3)+n-2..
    * ....
    * f(2) = f(1)+2
    * f(1) = 1
    *
    */
    public static int getSum(int n){
    if(n == 1){
    return 1;
    }
    return getSum(n-1)+n;
    // int sum = 0;
    // for (int i = 1; i < n+1; i++) {
    // sum+=i;
    // }
    // return sum;
    }
    public static void demo01(){
    System.out.println("demo01");
    demo01();
    }



    }

    import java.io.File;

    /*
    * 需求: 给你一个文件夹的File对象
    * 要求列出该文件夹下所有文件(如果包括有文件夹,那么要求也要列出子文件夹下的文件)
    *
    */
    public class FileDiGuiDemo {

    public static void main(String[] args) {
    // TODO Auto-generated method stub
    showFiles(new File("D:\"));
    }
    /*
    * 定义方法:列出一个文件夹的File对象的中的文件
    */
    public static void showFiles(File fileDir){//参数代表一个文件夹的File对象
    if(fileDir==null || fileDir.isFile()){
    System.out.println("我要的是一个文件夹的File,文件的File不行!");
    return;
    }
    File[] files = fileDir.listFiles();
    if(files==null){
    return;
    }
    for (File file : files) {
    if(file.isFile()){
    System.out.println(file);
    }else if(file.isDirectory()){
    //是一个文件夹 那么不管他
    showFiles(file);//调用自己 ,传入一个文件夹
    }
    }
    // File[] files = fileDir.listFiles();
    // System.out.println(files);
    // System.out.println(files.length);

    }

    }


    /*
    * File中的另外一个方法:
    * File[] listFiles(FileFilter filter);//列出当前文件夹下 我们要求的File对象
    *
    *
    */
    public class FilterDemo01 {

    public static void main(String[] args) {
    // TODO Auto-generated method stub
    //1.创建文件夹对象
    File fileDir = new File("F:\demo");
    //2.调用方法
    //2.1先创建一个过滤器的实现类对象
    FileFilter ff = new FileFilter(){

    @Override
    public boolean accept(File pathname) {
    // TODO Auto-generated method stub
    if(pathname.getName().length() <= 6){
    return true;
    }
    return false;
    }

    };

    File[] files = fileDir.listFiles(ff);

    System.out.println(files.length);
    for (File file : files) {
    System.out.println(file);
    }
    }


    }

    /*
    * 策略设计模式:
    * 核心思想:把逻辑和算法分离,提高程序的扩展和灵活性.
    *
    * 核心技术:把方法作为参数传递(传递的一个接口的实现类)
    *
    * 自定义一个工具类 MyCollections 提供一个静态方法sort用来排序数组
    * 自定义一个工具类 MyCollections 提供一个静态方法sort用来字符串数组
    *
    */
    public class CeLveDemo2 {
    public static void main(String[] args) {
    demo01();
    System.out.println();
    demo02();
    }

    public static void demo02() {
    String[] strs = {"java","hello","world","heimama","baiducn","man","idaidaodo"};
    MyCollections.sortString(strs, new CompareStringInterface() {

    @Override
    public boolean compare(String str1, String str2) {
    // TODO Auto-generated method stub
    if(str1.charAt(0)>str2.charAt(0)) {
    return true;
    }
    return false;
    }
    });
    for(String string : strs) {
    System.out.print(string + " ");
    }
    System.out.println();

    }

    /*
    * 排序int 数组
    *
    */
    public static void demo01() {
    int[] num3 = {2,56,3,5674,67,43,35,67890};
    MyCollections.sort(num3, new CompareInterface() {

    @Override
    public boolean compare(int num1, int num2) {
    // TODO Auto-generated method stub
    if(num1 < num2) {
    return true;
    }
    return false;
    }

    });
    for(int num : num3) {
    System.out.print(num + " ");
    }
    }

    }


    public class MyCollections {
    private MyCollections() {}
    public static void sort(int[] nums,CompareInterface ci) {
    //冒泡
    for(int i = 0; i < nums.length -1; i++) {
    for(int j = 0 ; j< nums.length - 1- i; j++) {
    //交换
    int temp = nums[j];
    nums[j] = nums[j+1];
    nums[j+1] = temp;
    }
    }



    }
    /*
    * 字符串排序
    *
    */
    public static void sortString(String[] arr,CompareStringInterface sci) {
    for(int i = 0; i < arr.length-1 ; i++) {
    for(int j = 0; j < arr.length-1-i; j++) {
    //比较 arr[j] arr[j+1]
    if(sci.compare(arr[j], arr[j+1])) {
    String str = arr[j];
    arr[j] = arr[j+1];
    arr[j+1] = str;
    }
    }
    }
    }




    }

    interface CompareInterface {
    public abstract boolean compare(int num1,int num2);
    }

    interface CompareStringInterface {
    public abstract boolean compare(String str1,String str2);
    }

    File file = new File("demo02.txt");

    //文件的大小
    System.out.println(file.getTotalSpace());

    //File对象的路径名
    System.out.println(file.getPath());
    //文件的绝对路径
    System.out.println(file.getAbsolutePath());

    /*
    import java.io.File;
    import java.io.FileFilter;
    import java.io.FilenameFilter;

    public class Test5 {
    public static void main(String[] args) {
    File file = new File("D:\新建文件夹\新建文件夹");
    System.out.println(file);
    /*
    FileFilter ff = new FileFilter() {

    @Override
    public boolean accept(File pathname) {


    //File file = new File(pathname);



    return pathname.isFile() && pathname.getName().endsWith(".txt");


    //return false;
    }

    };


    File[] list = file.listFiles(ff);

    for (File file2 : list) {
    System.out.println(file2);
    }
    */

    /* File[] files = file.listFiles(new FileFilter() {
    //把文件夹下面的所有文件包括文件夹进行判断,如果返回true则添加到File[] files数组中
    @Override
    public boolean accept(File pathname) {//这个File pathname : 表示的是这个是路径的File对象
    // TODO Auto-generated method stub
    //File file = new File(pathname);
    System.out.println(pathname);
    return true;
    }
    });*/
    /*File[] files = file.listFiles(new FilenameFilter() {

    @Override
    public boolean accept(File dir, String name) {
    //File dir :这个是盘符的意思(也就是文件名称以前的东西),name : 这个是文件名称
    // TODO Auto-generated method stub
    File file = new File(dir,name);
    return file.isFile() && file.getName().endsWith(".txt");
    }
    });*/

    File[] files = file.listFiles(new FilenameFilter() {

    @Override
    public boolean accept(File dir, String name) {
    // TODO Auto-generated method stub

    System.out.println(dir);
    System.out.println(name);
    return true;
    }
    });

    /*for (File file2 : files) {
    System.out.println(file2);
    }*/

    }
    }
    */

    /*
    File : renameTo(File file) : 重命名的方法(将原先的File对象的名字修改为一个新的File对象)

    * newLine() 与 的区别
    * newLine()是跨平台的方法
    * 只支持的是windows系统

    标准读写字符流操作

    *将一个文本文档上的文本反转,第一行和倒数第一行交换,第二行和倒数第二行交换
    *
    * 分析:
    * 1.创建输入输出流对象
    * 2.创建集合对象
    * 3.将读到的数据存储在集合中
    * 4.倒着遍历集合将数据写到文件上
    * 5.关流
    *
    * 注意事项:
    * 流对象尽量晚开早关
    *
    */
    public class Tet1 {
    public static void main(String[] args) throws IOException {
    //改写后尽量晚开早关
    //1.创建输入输出流对象
    BufferedReader br = new BufferedReader(new FileReader("xxx.txt"));

    //2.创建集合对象
    ArrayList<String> list = new ArrayList<>();
    //3.将读到的数据存储在集合中
    String line;
    while((line = br.readLine()) != null) {
    list.add(line);
    }
    br.close();
    BufferedWriter bw = new BufferedWriter(new FileWriter("yyy.txt"));
    //4.倒着遍历集合将数据写到文件上
    for(int i = list.size() -1; i >= 0;i--) {
    bw.write(list.get(i));
    bw.newLine();
    }
    //关流

    bw.close();

    }
    }

    public class Demo5_LineNumberReader {
    public static void main(String[] args) throws IOException {
    //多了一个行号:可以添加行号
    LineNumberReader lnr = new LineNumberReader(new FileReader("xxx.txt"));

    String line;
    //添加的行号以101开始的
    lnr.setLineNumber(100);
    while((line = lnr.readLine()) != null) {
    System.out.println(lnr.getLineNumber() + ":" + line);
    }

    lnr.close();
    }
    }

    /*
    * 装饰设计模式:耦合性不强,被装饰的类的变化与装饰类的变化无关
    *
    */
    public class Demo_Wrap {
    public static void main(String[] args) {
    HeiMaStudent hms = new HeiMaStudent(new Student());

    hms.code();

    }
    }

    interface Coder {
    public void code();
    }

    class Student implements Coder {

    @Override
    public void code() {
    // TODO Auto-generated method stub
    System.out.println("javase");
    System.out.println("javaweb");
    }

    }

    class HeiMaStudent implements Coder {
    //获取学生引用(获取学生对象)
    //获取被装饰类的引用
    private Student s;
    //2.在构造方法中传入被装饰类的对象
    public HeiMaStudent(Student s) {
    this.s = s;
    }
    //3.对原有的的功能进行升级
    @Override
    public void code() {
    // TODO Auto-generated method stub
    s.code();
    System.out.println("ssh");
    System.out.println("数据库");
    System.out.println("大数据");
    System.out.println("...");


    }

    }

    public class Demo7_TransTo {
    public static void main(String[] args) throws IOException {
    //method();
    //method1();
    /*
    * BufferedReader -- InputStreamReader(字节流,编码表)字节通向字符的桥梁,通过指定的编码表将字节转换为字符.---FileInputStream -- ut-8txt
    * BufferedWriter -- OutputStreamWriter(字节流,编码表)字符通向字节的桥梁,通过指定的编码表将字符转换为字节 -- FileOutputStream -- gbk.txt
    *
    *
    */

    //更高效的读
    BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("utf-8.txt"), "utf-8"));
    //更高效的写
    BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("gbk.txt"), "gbk"));
    int c;
    while((c = br.read()) != -1) {
    bw.write(c);
    }
    br.close();
    bw.close();



    }

    private static void method1() throws UnsupportedEncodingException, FileNotFoundException, IOException {
    //指定码表读字符
    InputStreamReader isr = new InputStreamReader(new FileInputStream("utf-8.txt"),"uTf-8");
    //指定码表写字符
    OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("gbk.txt"), "gbk");

    int c;
    while((c = isr.read()) != -1) {
    osw.write(c);
    }
    isr.close();
    osw.close();
    }

    private static void method() throws FileNotFoundException, IOException {
    //用默认编码表读写,出现乱码
    FileReader fr = new FileReader("utf-8.txt");
    FileWriter fw = new FileWriter("gbk.txt");
    int c;
    while(( c = fr.read()) != -1) {
    fw.write(c);
    }
    fr.close();
    fw.close();
    }
    }

    /*
    * 当我们下载一个试用软件,没有购买正版的时候,每执行一次就会体系我们换有多少次使用机会用学过的IO流只是,模拟试用版软件
    * 使用10次机会,执行一次就提示一次您换有几次机会,如果次数到了
    *
    * 分析:
    * 1.创建带缓冲的输入流对象,因为要使用readLine方法,可以保证数据的原样性
    * 2.将读到的字符串转换为int数
    * 3.对int数进行判断,如果大于零,就将其--写回去,如果不大于零,就提示请购买正版
    * 4.在if判断中要将--的结果打印,并将结果通过输出流写到文件上
    * 5.
    */
    public class Test2 {
    public static void main(String[] args) throws IOException {
    //1.创建带缓冲的输入流对象,因为要使用readLine方法,可以保证数据的原样性
    BufferedReader br = new BufferedReader(new FileReader("config.txt"));
    //2.将读到的字符串转换为int数
    String line = br.readLine();
    //System.out.println(line);
    //将数字字符串转换为数字
    int times = Integer.parseInt(line);
    //3.对int数进行判断,如果大于零,就将其--写回去,如果不大于零,就提示请购买正版
    if(times > 0) {
    //4.在if判断中要将--的结果打印,并将结果通过输出流写到文件上
    System.out.println("您还有" + times-- + "次机会");
    FileWriter fw = new FileWriter("config.txt");
    fw.write(times + "");
    fw.close();


    }else {
    System.out.println("您的试用次数已到,请购买正版");
    }
    br.close();

    }
    }

    * 递归:方法字节调用自己
    *
    * 递归的弊端:不能调用次数过多,容易导致栈内存溢出
    * 递归的好处:不用知道循环次数
    *
    * 构造方法用不能使用递归调用
    *
    * 递归调用不一定必须有返回值


    * IO流对象: 数据进行读取和写入
    * Input:数据读取
    * Output:数据写出
    *

    Java中IO流分类:
    按照操作数据分类
    字节流:能读所有任意的文件
    字符流:只能读写文本文件,((只要能用文本工具打开而且打开后还能看懂的)(记事本,notepad++等等)这些都是文本文件)
    文本文件有:.txt,.java.html,.css,.其他编程语言的源码
    注意:world,excel,ppt都不是文本文件

    按照数据的流向分类
    输入流:从外界设备 读取数据 到内存;
    输出流:从内存写数据 到外界设备.

    总结:总共有四种流

    1.字符输入流:reader是根类(基类)(抽象类) 方法:read(读一个字符,读一个字符数组)
    FileReader,BufferedReader

    2.字符输出流 :writer是根类(基类)(抽象类) 方法:writer(写一个字符,写一个字符数组(一部分),写一个字符串(一部分)
    FileWriter,BufferedWriter

    3.字节输入流: InputStream(基类)(抽象类) 方法:read(一个字节,读一个字节数组)
    FileInputStream

    4.字节输出流:OutputStream(基类)(抽象类) 方法:writer(写一个字节,写一个字节数组(一部分)
    FileOutputStream

    java中的流命名十分讲究:
    功能+流的基类(FileReader,OutputStream)

    OutputStream:字节输出流根类
    1.public voidwrite(int b) ; 写一个字节

    2.

    * InputStream:字节输入流(读数据)
    * 子类:FileInputStream
    * 1.public int read();//读取一个字节
    *
    * 2.public int read(byte[] bs);//读取一个字节数组
    *
    */
    public class InputStreamDemo01 {

    public static void main(String[] args) throws IOException {
    // TODO Auto-generated method stub
    //1.创建字节输入流对象(多态)
    InputStream is = new FileInputStream("a.txt");
    /*
    * 1.创建了一个字节输入流对象
    * 2.如果文件不存在 那么报错
    * 3.把流指向文件
    */
    //2.一次读取一个字节
    //int b = is.read();//0000 0000 0000 0000 0000 0000 0101 0100
    //System.out.println((char)b);//0000 0000 0101 0100
    //b = is.read();//0000 0000 0000 0000 0000 0000 0101 0100
    //System.out.println((char)b);//0000 0000 0101 0100
    //3.一次读取一个字节数组
    byte[] bs = new byte[4];
    int len = is.read(bs);
    System.out.println(len);
    System.out.println(new String(bs,0,len));

    //再读一次
    len = is.read(bs);
    System.out.println(len);
    System.out.println(new String(bs,0,len));


    }

    }

    * OutputStream:字节输出流根类
    * 子类:FileOutputStream
    * 1.public void write(int b);//写一个字节
    * 2.public void wirte(byte[] bs);//写一个字节数组
    *
    * 3.public void wirte(byte[] bs,int start,int len);//写一个字节数组的一部分
    *
    *
    * 追加问题:
    * 只要创建流的时候;
    * new FileOutputStream("a.txt",true);
    * 换行问题:
    * windows:
    * Linux:
    * Mac Os:
    */
    public class OutputStreamDemo01 {

    public static void main(String[] args) throws IOException {
    // TODO Auto-generated method stub
    //1.创建一个文件的字节输出流(多态的方式)
    OutputStream os = new FileOutputStream("a.txt");
    /*
    * 1.创建了一个字节输出流对象
    * 2.如果文件不存在,创建这个文件对象
    * 3.让这个流指向这个文件
    */
    //2.调用写数据方法 write
    //写一个字节
    // os.write(106);
    // os.write(97);
    // os.write(118);
    // os.write(97);
    //写一个字节数组 ILOVEYOUTIGER
    // byte[] bs = {106,97,118,97,97,97};
    //byte[] bs = "ILoveJavaEE".getBytes();
    //写"中国我爱你"
    // byte[] bs1 = "中国我爱你".getBytes();
    // System.out.println( bs1.length);
    // System.out.println(bs1[0]);
    // System.out.println(bs1[1]);
    // os.write(bs1);
    //写一个字节数组的一部分
    // byte[] bs = "中国我爱你".getBytes();
    // os.write(bs, 0, 6);
    for(int i = 0;i< 10;i++){
    os.write("我爱你中国".getBytes());
    os.write(" ".getBytes());
    }

    //3.关闭流
    os.close();

    }

    }

    /*
    * 字节流复制文件(可以复制任意文件) C:UsersyingpengDesktoppictures3.png
    *
    * 1.源文件 : 3.png---->FileInputStream
    * 2.目标文件: copy.png---->FileOutputStream
    *
    *
    *
    */
    public class CopyFileDemo01 {

    public static void main(String[] args) throws IOException {
    // TODO Auto-generated method stub
    //1.创建流对象(2个,一个读 一个写)
    FileInputStream fis = new FileInputStream("C:\Users\yingpeng\Desktop\pictures\3.png");
    FileOutputStream fos = new FileOutputStream("copy.png");
    //2.一边读取数据 一边写入数据
    //a.一次读取一个字节 写入一个字节
    // int b = fis.read();
    // fos.write(b);
    //标准代码==================
    // int b = 0;
    // while( (b = fis.read())!=-1){
    // fos.write(b);
    // }
    //b.一次读取一个字节数组
    long s = System.currentTimeMillis();
    //标准代码
    byte[] bs = new byte[1024];//保存读取到的数据
    int len = 0;//保存实际读取到的字节数
    while( (len = fis.read(bs))!=-1 ){
    fos.write(bs,0,len);
    }
    //3.释放资源
    fos.close();
    fis.close();

    long e = System.currentTimeMillis();
    System.out.println(e-s);
    }

    }


    * FileReader---->BufferedReader
    * FileWriter---->BufferedWriter
    *
    * FileInputStream---->BufferedInputStream
    * FileOutputStream----->BufferedOutputStream
    *
    * 1.BufferedOutputStream:字节缓冲输出流(写数据)
    * public BufferedOutputStream(OutputStream out)
    * a.public void write(int b);
    * b.public void write(byte[] bs);
    * c.public void wirte(byte[] bs,int start,int len);
    *
    *
    */
    public class BufferedDemo01 {

    public static void main(String[] args) throws IOException {
    // TODO Auto-generated method stub
    //1.创建字节缓冲输出流对象
    BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("b.txt"));
    //2.调用bos的写数据方法
    //写一个字节
    // bos.write(49);
    // bos.write(48);
    // bos.write(48);
    //写一个字节数组
    // byte[] bs = {49,48,48,48};
    // bos.write(bs);
    //写 "helloworld"
    // byte[] bs = "helloworld".getBytes();
    // bos.write(bs);
    byte[] bs = "凤a姐".getBytes();
    System.out.println(bs.length);
    bos.write(bs,2,3);
    //3.关闭流
    bos.close();

    }

    }

    /*
    * BufferedInputStream-->字节缓冲输入流(读数据)
    *
    * 构造:
    * public BufferedInputStream(InputStream in)
    *
    * 练习:使用BufferedInputStream读取一个txt文件打印到控制台
    */
    public class BufferedInputStreamDemo {

    public static void main(String[] args) throws IOException {
    // TODO Auto-generated method stub
    //1.创建字节缓冲输入流对象
    BufferedInputStream bis = new BufferedInputStream(new FileInputStream("ArrayList.java"));
    //a.一次读取一个字节
    // int b = 0;//保存读取到字节
    // while((b = bis.read())!=-1){
    // System.out.print((char)b);
    // }
    //b.一次读取一个字节数组
    int len = 0;//实际读取的个数
    byte[] bs = new byte[1024];
    while((len=bis.read(bs))!=-1){
    System.out.print(new String(bs,0,len));
    }

    //3.关闭
    bis.close();

    }
    public static void demo01() throws IOException{
    //1.创建字节缓冲输入流对象
    BufferedInputStream bis = new BufferedInputStream(new FileInputStream("1.txt"));
    //调用bis的读数据方法
    //a.一次读取一个字节
    // int b = bis.read();
    // System.out.println((char)b);
    //b.一次读取一个字节数组
    // byte[] bs = new byte[2];
    // int len = bis.read(bs);
    // System.out.println(len);
    // System.out.println(new String(bs,0,len));
    //
    // len = bis.read(bs);
    // System.out.println(len);
    // System.out.println(new String(bs,0,len));
    //3.关闭
    bis.close();

    }
    }



    */

    /*
    /*
    * 内存输出流:该输出流可以向内存中写数据,把内存当作一个缓冲区,写出之后
    *
    * FileInputStream读取中文的时候会出现乱码
    *
    * 解决方案:
    * 1.使用字符流
    *
    * InputStream:字节输入流(读数据)
    * 子类:FileInputStream
    * 1.public int read();//读取一个字节
    *
    * 2.public int read(byte[] bs);//读取一个字节数组
    *
    */
    public class InputStreamDemo01 {

    public static void main(String[] args) throws IOException {
    // TODO Auto-generated method stub
    //1.创建字节输入流对象(多态)
    InputStream is = new FileInputStream("a.txt");
    /*
    * 1.创建了一个字节输入流对象
    * 2.如果文件不存在 那么报错
    * 3.把流指向文件
    */
    //2.一次读取一个字节
    //int b = is.read();//0000 0000 0000 0000 0000 0000 0101 0100
    //System.out.println((char)b);//0000 0000 0101 0100
    //b = is.read();//0000 0000 0000 0000 0000 0000 0101 0100
    //System.out.println((char)b);//0000 0000 0101 0100
    //3.一次读取一个字节数组
    byte[] bs = new byte[4];
    int len = is.read(bs);
    System.out.println(len);
    System.out.println(new String(bs,0,len));

    //再读一次
    len = is.read(bs);
    System.out.println(len);
    System.out.println(new String(bs,0,len));


    }

    }



    */
    public class DmeoByteArrayOutputStream {
    public static void main(String[] args) throws IOException {
    //emthod();
    //在内存中创建了可以增长的内存数组
    FileInputStream fis = new FileInputStream("e.txt");
    //ByteArrayOutputStream不用关流
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    int b;
    //将读取到的数据逐个写到内存中
    while ((b = fis.read()) != -1) {
    baos.write(b);
    }
    //
    //将缓冲区的数据全部获取出来,并赋值给arr数组
    //他可以使用指定的编码表转换
    byte[] arr = baos.toByteArray();
    System.out.println(new String(arr));
    //使用的是默认的编码表进行转换输出
    //将缓冲区的内容转换为了字符串,在输出语句中可以省略调用toString()方法
    System.out.println(baos.toString());
    fis.close();


    }

    //使用字符流解决问题中文输入问题
    private static void emthod() throws FileNotFoundException, IOException {
    FileInputStream fis = new FileInputStream("e.txt");
    byte[] arr = new byte[3];
    int len;
    while((len = fis.read(arr)) != -1) {
    System.out.println(new String(arr,0,len));
    }

    fis.close();
    }
    }

    /*

    public class Test {
    public static void main(String[] args) throws IOException {
    //创建流对象(2个,一个读,一个写)
    //一次读取一个字节数组
    FileInputStream fis = new FileInputStream("韩雪 - 想起.mp3");
    FileOutputStream fos = new FileOutputStream("Copy.mp3");
    //标准代码
    //保存读到到的数据
    byte[] bs = new byte[1024];
    //保存实际读取到的字节数
    int len;
    while((len = fis.read(bs)) != -1) {
    fos.write(bs,0,len);
    }
    //3.释放资源
    fos.close();
    fis.close();



    }
    }

    * 复制单级文件夹:
    *
    * 0.创建目标文件夹(如果不存在) F:\test
    *
    * 1.创建一个File对象(代表要复制的源文件夹) E:\demo
    *
    * 2.调用File对象的listFiles方法 获取文件夹中所有的文件对象
    *
    * 3.挨个复制文件对象 到 目标文件夹中
    * 源文件 E:\demo\1.txt---> 目标文件 F:\test\1.txt
    */
    public class CopyDirectoryDemo {

    public static void main(String[] args) throws IOException {
    // TODO Auto-generated method stub
    //0.创建目标文件夹(如果不存在) F:\test
    File fileDest = new File("F:\test");
    if(!fileDest.exists()){
    fileDest.mkdir();
    }
    //1.创建源文件夹的File对象
    File fileSrc = new File("E:\demo");
    //调用fileSrc的listFiles
    File[] files = fileSrc.listFiles();
    for (File file : files) {
    System.out.println(file);//源文件 E:demo1.txt
    File newFile = new File(fileDest,file.getName());//目标文件 F:\test\1.txt
    System.out.println(newFile);
    //复制文件 从file 复制到newFile
    copyFile(file,newFile);
    }
    }

    public static void copyFile(File file, File newFile) throws IOException {
    // TODO Auto-generated method stub
    //复制文件 源文件 file 目标文件 newFile
    BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
    BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(newFile));

    //循环读取文件 写入文件
    int len = 0;
    byte[] bs = new byte[1024];
    while((len= bis.read(bs))!=-1){

    bos.write(bs, 0, len);
    }
    //关闭流
    bis.close();
    bos.close();
    System.out.println("复制文件"+file.getAbsolutePath()+"成功!");
    }

    }


    *
    * 求前n个斐波那契数列的元素之和
    * 1.求第n个斐波那契数列的元素
    * f(n) = f(n-1)+f(n-2)
    * f(2) = 1
    * f(1) = 1
    * 2.求前n个斐波那契数列的元素之和
    * sum(n) = sum(n-1)+ getFBNum(n)
    * sum(1) = 1
    *
    * 留一个题:
    * 求前n个数的和
    * 1 1+2 1+2+3 1+2+3+4 1+2+3+4+5

    第n个数为
    1 3 6 10 15
    *
    */
    public class DiGuiDemo {

    public static int sum(int n) {
    if(n == 1) {
    return 1;
    }
    return n + sum(n-1); //n = 3,(3+2+1)
    }

    public static int getSum(int n) {
    if(n == 1) {
    return 1;
    }
    return sum(n) + getSum(n-1);
    }

    public static void main(String[] args) {
    // TODO Auto-generated method stub
    //测试
    // int num = getFBNum(5);
    // System.out.println(num);
    int sum = getSum(6);//1 1 2 3 5 8
    System.out.println(sum);
    }
    /*
    * 求第n个斐波那契数列的元素
    */
    public static int getFBNum(int n){
    if(n==1){
    return 1;
    }
    if(n==2){
    return 1;
    }
    return getFBNum(n-1)+getFBNum(n-2);
    }

    /*
    *前n个元素之和
    */
    public static int getSum(int n){
    if(n==1){
    return 1;
    }
    //sum(n) = sum(n-1)+ getFBNum(n)
    return getSum(n-1)+getFBNum(n);
    }
    }


    * Properties类:是Map接口的一个实现,具有map接口下的所有功能
    * 没有泛型,Key和Value都是String类型
    * 1.put(String key,String value)---->setProperty(String key,String value)
    * 2.get(String key)---->getProperty(String key);
    * 3.删除方法 还是使用 map接口中的remove方法
    *
    * 4.keySet();//以键找值 ----->Set<String> stringPropertyNames();
    * 5.entrySet();//键值对 只要map中有
    *
    * 持久属性集的用法:
    * public void store(OutputStream out, String comments);
    * 把属性集Properties对象中数据保存到 一个输入流中
    * public void load(InputStream inStream);
    * 从输入流中加载数据
    */
    public class PropertiesDemo {
    public static void main(String[] args) throws IOException {
    // //1.创建一个Properties对象
    // Properties ps = new Properties();
    // //2.添加数据
    // ps.setProperty("zhangsan", "18");
    // ps.setProperty("lisi", "28");
    // ps.setProperty("rose", "38");
    // ps.setProperty("jack", "48");
    // //3.保存数据
    // ps.store(new FileOutputStream("abc.properties"), "");

    //4.从输入流中加载数据
    Properties ps = new Properties();
    System.out.println(ps);
    ps.load(new FileInputStream("abc.properties"));
    System.out.println(ps);

    }
    /*
    * 基本用法
    */
    public static void demo01(){
    //1.创建一个Properties对象
    Properties ps = new Properties();
    //2.添加数据
    ps.setProperty("zhangsan", "18");
    ps.setProperty("lisi", "28");
    ps.setProperty("rose", "38");
    ps.setProperty("jack", "48");
    //System.out.println(ps);
    // String value = ps.getProperty("jack");
    // System.out.println(value);
    //遍历ps集合
    Set<String> namesSet = ps.stringPropertyNames();
    //foreach或者迭代器
    for (String name : namesSet) {
    String value = ps.getProperty(name);
    System.out.println(name+"="+value);
    }
    }
    }

    /*
    * 一个文件夹复制到另外一个盘符下(这个被复制的文件夹里面有还有文件夹,文件夹里面还有文件.)
    * 复制多个文件夹以及内容进行复制
    *
    * 分析:
    * 1.创建新的文件路径(这个是需要复制到的位置)对象,再创建一个路径对象
    * 2.定义方法,这个方法里面判断当前文件夹下面所有的文件,
    * 3.如果是文件用方法进行复制,
    * 4.如果是文件夹就用新的file对象去封装成一个新的盘符路径,再把新的盘符路径和这个循环出来的文件进行递归
    *
    */
    public class Test5 {
    public static void main(String[] args) throws IOException {
    File file = new File("F:\demo");
    File newFile = new File("E:\dmeo2");
    method(file,newFile);
    }
    //用方法进行递归判断寻找文件并创建文件夹
    public static void method(File file,File newFile) throws IOException {
    File[] files = file.listFiles();
    for (File file2 : files) {
    if(file2.isDirectory()) {
    File file3 = new File(newFile,file2.getName());
    file3.mkdirs();
    method(file2,file3);
    }else {
    File file4 = new File(newFile,file2.getName());
    copy(file2,file4);
    }
    }

    }
    //用方法进行文件复制
    private static void copy(File file2, File file4) throws IOException {
    // TODO Auto-generated method stub
    FileInputStream fis = new FileInputStream(file2);
    FileOutputStream fos = new FileOutputStream(file4);
    byte[] b = new byte[1024];
    int i;
    while((i = fis.read(b)) != -1) {
    fos.write(b, 0, i);
    }
    fis.close();
    fos.close();


    }
    }

    UTF-8:字母代表一个字节,汉子代表三个字节

    GBK : 字母是一个字节,汉子是两个字节

    public static void main(String[] args) throws IOException {
    //1.封装源目录:
    File srcDir = new File("D:\单级目录");
    //2.封装目标目录:
    File destDir = new File("E:\");
    //3.判断目标目录下是否包含要复制的目录:
    destDir = new File(destDir,srcDir.getName());//new File("E:\单级目录");
    if(!destDir.exists()){
    destDir.mkdir();//创建目录
    }
    //4.获取源目录下所有子文件的File数组;
    File[] fileArray = srcDir.listFiles();
    if(fileArray!= null){
    //5.遍历数组,获取每个File对象;
    for(File f : fileArray){
    //针对每个File对象创建独立的输入流(字节流)
    FileInputStream in = new FileInputStream(f);
    //并向目标位置创建独立的输出流(字节流)
    FileOutputStream out = new FileOutputStream(new File(destDir,f.getName()));
    //开始复制-->一次复制一个字节数组
    byte[] byteArray = new byte[1024 * 8];
    int len = 0;
    while((len = in.read(byteArray)) != -1){
    out.write(byteArray,0,len);
    }
    out.close();
    in.close();
    }

    }
    System.out.println("复制完毕!");
    }
    <上一题

    public static void main(String[] args) throws Exception {
    //创建源目录
    File file = new File("D:/java");
    //获取文件
    File[] files = file.listFiles();
    //创建输入流对象
    InputStream in = null;
    //创建输出流对象
    OutputStream out = null;
    //记录源文件夹中文件的名称
    String fileName = null;
    // 记录 目标文件夹中文件的名称
    String destName = null;
    //指定目标文件夹
    File f = new File("D:/jad");
    //遍历
    for (File file2 : files) {
    in = new FileInputStream(file2);
    //查看 目标文件夹 是否存在
    if(!f.exists()){
    f.mkdir();
    }
    //获取源文件夹中文件的名称
    fileName = file2.getName();
    destName = fileName;
    //创建复制的文件输出流
    out = new FileOutputStream(new File("D:/jad/"+destName));
    int len = 0;
    byte[] b = new byte[1024];
    //完成复制
    while((len = in.read(b))!= -1){
    out.write(b, 0, len);
    //System.out.println(new String(b,0,len));
    }
    }
    }
    <上一题

    1.删除目录主要用到的知识:File类和递归。
    2.本题的完整代码为:
    public class Test {
    public static void main(String[] args) {
    delete(new File("D:/a"));
    }

    public static void delete(File f) {
    // 判断是否是文件夹
    if (f.isDirectory()) {
    File[] files = f.listFiles();
    for (File file : files) {
    delete(file);
    file.delete();
    }
    }
    // 删除操作
    f.delete();
    }
    }

    public static void main(String[] args) throws Exception {
    //1、明确源文件与目的地
    File sourse = new File("E:1.mp3");
    File order = new File("E:\1_copy.mp3");
    //2、创建两个流对象
    FileOutputStream out = new FileOutputStream(order);
    FileInputStream in = new FileInputStream(sourse);
    //3、循环读,并且将每一次读到的内容都使用输出流输出到目的地
    int len = -1;
    byte[] b = new byte[1024];
    while((len = in.read(b))!=-1){
    //4、说明内容有效,文件还没有结束,可以循环读
    //5、此时向目的地写数组中的内容,要明确有效数据的个数
    out.write(b,0,len);
    }
    //5、循环结束后,就复制完成了,关闭资源
    out.close();
    in.close();
    }

    package cn.baidu04_Test;
    import java.io.BufferedInputStream;
    import java.io.BufferedOutputStream;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    /*
    * 复制文件夹(含子文件夹)
    *
    * 需求: D:\YesDir 文件夹 复制到 当前项目下的 Copy目录中
    *
    * 分析:
    * 数据源 --- D:\YesDir 文件夹
    * 目的地 --- Copy 文件夹
    *
    * 1.找到数据源,看数据源是否存在
    * 指定目的地
    * 2.看是否有目的地文件夹
    * 如果没有目的地文件夹,创建目的地文件夹
    * 3.获取数据源中所有的File对象
    * 4.通过遍历,得到数据源中每一个File对象
    * 5.判断是否为文件夹
    * 是:说明是文件夹, 进入到子文件夹中
    * file -- D:\YesDir\小视频
    * 完成子文件夹的复制
    * a.找到数据源,看数据源是否存在
    * file -- D:\YesDir\小视频
    * b,指定目的地
    * dest -- Copy\小视频
    * 子文件夹名称 = 目的地文件夹 当前要复制的File目录的名称
    * c, 递归,回到步骤2
    *
    * 否:说明是文件,复制文件
    * file -- D:YesDir大话西游.mp3
    * a,指定数据源 file -- D:YesDir大话西游.mp3
    * b,指定目的地 dest -- Copy大话西游.mp3
    * 目的地文件名称 = 目的地文件夹 + 当前要复制的File文件的名称
    * c,读数据源中的数据
    * d,把数据写到目的地
    * e,关闭流
    */
    public class CopyDirs {
    public static void main(String[] args) throws IOException {
    //1.找到数据源,看数据源是否存在
    File srcPath = new File("D:\YesDir");
    //2.目的地
    //File destPath = new File("D:\YesDir\Yes"); --》死循环复制(直到磁盘满,不能删除,得使用递归删除或者使用360强制删除)
    File destPath = new File("Copy");
    //3,开始进行复制文件夹
    copyDir( srcPath, destPath);
    }
    //复制文件夹的方法
    private static void copyDir(File srcPath, File destPath) throws IOException {
    /首先 感叹号 是‘非’的意思,
    f应该是一个对象的实例,这里应该是file对象,
    exists(), 是f那个实例对应的对象的方法 从名字看 是是否存在的意思,
    连起来的意思就是:
    f这个文件对象是不是不存在
    //2.看是否有目的地文件夹,如果没有目的地文件夹,创建目的地文件夹
    if (!destPath.exists()) {
    destPath.mkdir();
    }

    //3.获取数据源中所有的File对象
    File[] files = srcPath.listFiles();

    if (files == null) {
    System.out.println(srcPath);
    //System.out.println("该文件夹是受系统保护的文件夹,它拒绝访问!");
    return ; //这样处理的好处是,保证程序不会出现NullPointerException
    }

    //4.通过遍历,得到数据源中每一个File对象
    for (File file : files) {
    //5.判断是否为文件夹
    if (file.isDirectory()) {
    //是:说明是文件夹, 进入到子文件夹中
    //file -- D:\YesDir\小视频
    //dest -- Copy\小视频
    //子文件夹名称 = 目的地文件夹 当前要复制的File目录的名称
    File dest = new File(destPath, file.getName());
    copyDir(file, dest);//这里写dest为了创建子文件夹

    } else {
    //否:说明是文件,复制文件
    //file -- D:YesDir大话西游.mp3
    //dest -- Copy大话西游.mp3
    //目的地文件名称 = 目的地文件夹 + 当前要复制的File文件的名称
    File dest = new File(destPath, file.getName());
    copyFile(file, dest);//这里的dest是要复制到新的文件名称
    }
    }
    }
    //复制文件
    private static void copyFile(File file, File dest) throws IOException {
    //指定数据源
    BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
    //指定目的地
    BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(dest));
    //读
    byte[] buffer = new byte[1024];
    int len = -1;
    while ( (len = bis.read(buffer)) != -1) {
    //写
    bos.write(buffer, 0, len);
    }
    //关闭流
    bos.close();
    bis.close();
    }
    }

    * 计算机中只能识别是0101010101001
    *
    * 1.老美 想了一个办法 把英文和英文符号----->对应成一个10进制数字------>转成2进制---->电脑
    * A---65 a---97 0---48
    * 2.ASCII码表,把所有的英文和符号 对应了一个十进制(所有其他码表都必须兼容它)
    *
    * 3.GB2312: 把常用中文(6000-7000),一一对应成数字,中文两个字节
    *
    * 4.GBK: 把基本所有的中文(20000多个),一一对应成数字,中文两个字节
    *
    * 5.Unicode(万国码表):在这个码标中,所有的字符 都是两个字节
    * A----65---- 0000 0000 0100 0001
    * 6.UTF-8:(基于Unicode),一个字节能表示的字符,坚决不用两个字节
    * 英文1个字节, 中文(3个字节)
    * 常用的中文码表:GBK(中文2个字节),UFT-8(中文3字节)
    *
    * 流的分类:
    * 根据操作的数据:
    * 字节流
    * 字符流
    * 根据数据的流向;
    * 输入流
    * 输出流
    *
    * java中四大流
    * 字节输入流:InputStream
    * 读取数据read:一个字节,一个字节数组
    *
    * 字节输出流:OutputStream
    * 写出数据write:一个字节,一个字节数组
    *
    * 字符输入流:reader
    * 读取数据(read):一个字符,一个字符数组
    * 字符输出流:writer
    * 写出数据(write):一个字符,一个字符数组,一个字符串
    * java流命名是十分规范,比如:FileReader(字符输入流)
    *
    *
    *
    */
    public class IODemo02 {

    public static void main(String[] args) {
    // TODO Auto-generated method stub

    }

    }

    /*
    * OutputStreamWriter extends Writer (字符输出流)
    * write方法: 一个字符,一个字符数组, 一个字符串
    *
    * OutputStreamWriter 是字符流通向字节流的桥梁,查表(编号)
    *
    * 构造方法:
    * public OutputStreamWriter(OutputStream out, String charsetName);//查指定的码表
    * public OutputStreamWriter(OutputStream out);//默认查GBK码表
    *
    * InputStreamReader extends Reader (字符输入流)
    * 读取方法:一个字符,一个字符数组
    *
    * InputStreamReader 是字节流通向字符流的桥梁:查表(解码)
    *
    * 构造方法:
    * public InputStreamReader(InputStream in, String charsetName);//查指定码表
    * public InputStreamReader(InputStream in);//默认GBK码表
    *
    *
    */
    public class OutputStreamWriterDemo {

    public static void main(String[] args) throws IOException {
    // TODO Auto-generated method stub
    //创建一个流对象
    // InputStreamReader isr = new InputStreamReader(new FileInputStream("gbk.txt"));
    InputStreamReader isr = new InputStreamReader(new FileInputStream("utf8.txt"),"GBK");
    int ch = isr.read();
    System.out.println((char)ch);
    ch = isr.read();
    System.out.println((char)ch);
    ch = isr.read();
    System.out.println((char)ch);
    isr.close();

    }

    public static void demo01() throws IOException{
    // OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("gbk.txt"));
    OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("utf8.txt"),"UTF-8");
    //ows调用写数据方法
    osw.write("你好");
    //关闭
    osw.close();
    }

    }


    /*
    * 序列化流:写对象到字节输出流中,由字节输出流再去写文件
    * ObjectOutputStream
    * 构造:
    * public ObjectOutputStream(OutputStream out);
    *
    *
    * 反序列化流:从字节输入流中读取数据,再解析成对象
    * ObjectInputStream
    * 构造:
    * public ObjectInputStream(InputStream in);
    *
    * 异常:
    *
    * 1.只要写序列化的过程中出现NotSerializableException异常
    * 那么肯定是 该类没有实现java.io.Serializable接口
    * 2.如果出现这个异常InvalidClassException异常:找不到类异常
    * 2.1 在写入对象之后,修改了原来的类,那么读取的时候就会InvalidClassException异常:找不到类异常
    *
    * 2.2该类包含未知数据类型
    * 2.3该类没有可访问的无参数构造方法(写一个标准的类必须有无参构造)
    *
    * 3.关于java.io.Serializable的问题:
    * 3.1一个类实现java.io.Serializable接口,而这接口中没有方法
    * 这个接口就是一个标记,如果有标记可以序列化,如果没有标记不能序列化
    * 3.2java为会这个类提供一个版本号,如果类修改了,那么这个版本号就会改变
    * 就是通过这个版本号来表示类改没改变
    * 4.瞬态关键字: transient
    * 这个关键字可以修饰成员变量,这个成员变量,当序列化的时候会被忽略
    *
    *
    */
    public class SerializableDemo01 {

    public static void main(String[] args) throws Exception {
    // TODO Auto-generated method stub
    //writeObject();
    readObject();
    }
    public static void readObject()throws Exception{
    //创建反序列化流对象
    ObjectInputStream ois = new ObjectInputStream(new FileInputStream("person.txt"));
    //调用ois读对象的方法
    Object obj = ois.readObject();
    //打印对象(obj对象实际上是Person对象)
    System.out.println(obj);
    }

    public static void writeObject()throws IOException {
    ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("person.txt"));
    //调用写对象的方法
    Person p = new Person(10, "小王",10086);
    //java.io.NotSerializableException
    oos.writeObject(p);
    //关闭
    oos.close();
    }

    }


    /*
    * 打印流:
    * PrintWriter:可以打印到File对象,字符串形式的文件名中,字节输出流中,字符输出流中
    * PrintStream:可以打印到File对象,字符串形式的文件名中,字节输出流中
    * 以上两个流的用法完全一样
    * 只有一点区别:打印的目的地有所不同
    *
    */
    public class PrintDemo01 {

    public static void main(String[] args) throws IOException {
    // TODO Auto-generated method stub
    PrintWriter pw = new PrintWriter("aaa.txt");
    pw.print("abc");
    pw.print(true);
    pw.print(12);
    pw.close();
    //我们以前用的
    // System.out实际上就是一个打印流
    }
    }


    /*
    * Properties类:实现了map接口,那么我们可以认为就是一个map集合(HashMap)
    *
    * 1.Properties没有泛型,属性名和属性值,都是String类型
    *
    * 2.它是一个可以持久化的属性集(自带写数据到文件 ,从文件中读取数据)
    *
    * 3.这些持久化的方法都是和流有关系的
    *
    * 特殊的成员方法:
    * 1. setProperty(String key,String value);//类似于map.put(K,V);
    *
    * 2. public String getProperty(String key);//类似于map.get(K);
    *
    * 3. public Set<String> stringPropertyNames();//类似于map.keySet();
    *
    * 持久化相关的方法:
    * 将Properties对象中的数据 保存到文件中
    * store(OutputStream out);
    * store(Writer w);
    *
    * 将文件中的键值对 读取到Properties对象
    * load(InputStream intput);
    * load(Reader r);
    * Properties通常作为配置文件
    *
    *
    */
    public class PropertiesDemo {
    public static void main(String[] args) throws IOException {
    readProperties();
    }
    public static void readProperties() throws IOException{
    Properties ps = new Properties();//就看成一个map集合
    //读取数据
    ps.load(new FileInputStream("abc.properties"));
    System.out.println(ps);
    }

    public static void writeProperties() throws IOException{
    Properties ps = new Properties();//就看成一个map集合
    ps.setProperty("zhangsna", "18");
    ps.setProperty("alilbba", "28");
    ps.setProperty("rose", "38");
    ps.setProperty("jack", "48");
    ps.setProperty("isAutoGengxin", "0");
    //写数据到文件中
    FileOutputStream fos = new FileOutputStream("abc.properties");
    ps.store(fos, "a啊解放路啊fagg");
    fos.close();

    }

    /*
    * 演示基本方法
    */
    public static void demo01(){
    //创建Properties对象
    Properties ps = new Properties();//就看成一个map集合
    ps.setProperty("zhangsna", "18");
    ps.setProperty("alilbba", "28");
    ps.setProperty("rose", "38");
    ps.setProperty("jack", "48");
    //System.out.println(ps);
    Set<String> names = ps.stringPropertyNames();
    Iterator<String> it = names.iterator();
    while(it.hasNext()){
    String name = it.next();
    String value = ps.getProperty(name);
    System.out.println(name+"="+value);
    }
    }
    }

  • 相关阅读:
    BZOJ4569 : [Scoi2016]萌萌哒
    2016浙江省赛过山车记
    BZOJ4546(原) : 三元组
    BZOJ4539 : [Hnoi2016]树
    BZOJ4537 : [Hnoi2016]最小公倍数
    BZOJ4538 : [Hnoi2016]网络
    BZOJ4527 : K-D-Sequence
    BZOJ4504 : K个串
    BZOJ4471 : 随机数生成器Ⅱ
    BZOJ3659 : Which Dreamed It
  • 原文地址:https://www.cnblogs.com/haizai/p/11144355.html
Copyright © 2020-2023  润新知