• Java的递归、IO流


    [递归]

       1、 在函数自身内部,调用函数本身的方式,称为递归。

       2、 注意: 递归包括递进去、归出来两步。
         首先,依次执行【函数调自身语句】上半部分的代码,直到最里层。 {递进去}
         然后,再从最里层开始,依次执行【函数调自身语句】下半部分的代码。 {归出来}
       3、 递归必须通过合适的语句,及时的跳出。 否则,容易造成死循环。

    public static int num=0;//2
        public static void test(){
            System.out.println("这是一个函数");
            num++;
            if(num<=2){
                test();//if()不成立不再调用自己
            }//先执行三次
            System.out.println("hahah");//执行完num大于2,hahah在执行之前的三次
        }
    
    
    //test类
    test();

    结果:

    练习:5的阶乘

    方法1:

    /**
         * 用递归实现5的!
         */
        static int jie=1;
        public static long jiecheng(int n){
            jie*=n;
            n--;
            if(n>=1){
                jiecheng(5);
            }
            return jie;
        }
    
    
    
    //Test类:
    System.out.println(jiecheng(5));

    方法2:

    public static int test(int number){//1
               if(number == 1){
                   return 1;
               }else{
                   return number * test(number - 1);
               }
               
           }
    
    //Test类:
    System.out.println(test(5));

    1、[File类] 

     (1) 作用: 用于对磁盘文件进行操作。 删除、创建等。
     (2) 三种常用的构造函数:
       ① File file1 = new File("F:\test");
       直接传入一个路径,拿到一个文件或者是文件夹。
       ② File file2 = new File("F:\test","test.txt");
         第一个参数传入父路径、 第二个参数传入子路径或者文件。
       ③ File file3 = new File(file1,"test.txt");
      第一个参数传入一个父路径的file对象, 第二个参数传入子路径或者文件。
     (3) 路径的表示:
        文件夹的分隔,可以使用"/"(通常用于Linux系统,Windows也适用)
        也可以使用"\"(通常用于Windows),注意一个需要进行转义。
     (4)方法:

        1.检测文件是否可读。

        System.out.println(file1.canRead());

        2.检测文件是否可写。

        System.out.println(file2.canWrite());

        3. 比较两个对象是否相等。
        System.out.println(file2.equals(file3));
        4. 检测文件是否存在。
        System.out.println(file1.exists());
        5. 取到文件的绝对路径
        System.out.println(file1.getAbsolutePath());
        6. 取到文件名或者文件夹名
             System.out.println(file2.getName());
        7. 取到当前文件或文件夹的父路径
        System.out.println(file1.getParent());
        8. 检测当前文件是否是绝对路径
        System.out.println(file1.isAbsolute());
        9. 检测当前路径是否是目录
        System.out.println(file2.isDirectory());
       10. 检测当前路径是否是文件
        System.out.println(file1.isFile());
       11. 删除文件: 删除成功返回true,删除失败返回false
        如果删除的是文件夹,则只能删除空文件夹,否则删除失败!
        System.out.println(file1.delete());
       12.创建一个新文件。 创建失败返回false

    try {
       System.out.println(file3.createNewFile());
      } catch (IOException e) {
    // TODO Auto-generated catch block
       e.printStackTrace();
    }

      13. 创建一个文件夹。只有当文件夹不存在时,才能创建成功。
      ①mkdir: 只能创建一层目录,如果倒数第二层目录也不存在,将创建失败。
      ② mkdirs: 可以创建多层目录,无论有几层不存在,都可以依次创建。

    System.out.println(file1.mkdir());
    System.out.println(file1.mkdirs());

      14.获得文件所在分区的总大小和可用大小,以字节B为单位。

    System.out.println(file1.getTotalSpace());
    System.out.println(file1.getUsableSpace());

      15.返回当前文件或文件夹的大小。单位B
       System.out.println(file2.length());
       list(): 返回当前目录中的所有文件和文件夹的名字。 返回值类型为String数组
       可以在参数中,传入FilenameFilter接口的实现类对象,表示对列表中的所有文件进行遍历过滤。
       需要重写accept方法,如果保留当前文件return true ,如果不要当前文件,return false

    String[] list = file1.list(new FilenameFilter() {
       // dir: 表示包含当前文件的父路径;
       // name: 表示当前文件名
       public boolean accept(File dir, String name) {
        if(name.endsWith(".txt")){
         return true;
        }else{
         return false;
        }
       }
      });
      for (String item : list) {
       System.out.println(item);
      }

      16..listFiles(): 返回当前目录中所有的文件和文件夹的路径。 返回值类型为File数组。
      同样可以对文件进行过滤:
       ① 与list()一样,使用FilenameFilter进行过滤;
       ② 使用FileFilter接口的实现类,进行过滤。

      File[] files = file1.listFiles(new FileFilter() {
       // pathname 表示当前文件的全路径(包括路径名和文件名)。
       public boolean accept(File pathname) {
        if(pathname.getName().endsWith(".txt")){
         return true;
        }else{
         return false;
        }
       }
      });
      for (File file : files) {
       System.out.println(file.getParent()+"-----"+file.getName());
      }

      17. 重命名一个文件。 要求传入一个新文件名的file对象。
        File file4 = new File("F:\test\test08.txt");
        System.out.println(file1.renameTo(file4));
      18.只读。
        System.out.println(file1.setReadOnly());

      19.最后更新时间。
        System.out.println(file1.setLastModified(new Date().getTime()));

    [Java中的IO流]  

      1、 根据流的方向: 输入流和输出流。   

            根据读取文字的大小: 字节流和字符流。
         (字节流按字节读取,读取中文时容易乱码; 字符流按照字符读取,通常用于读取中文)
         根据读取的方式: 节点流和缓存流。

         fis = new FileInputStream("F:/test.txt");

      2.如果第二个参数省略,或传入false,则表示每次写入时将原文件清空,从文件头部开始写入。
        如果第二个参数传入true,则表示不清空原文件,在文件末尾处追加新内容。

      3.如果第二个参数省略,或传入false,则表示每次写入时将原文件清空,从文件头部开始写入。

       如果第二个参数传入true,则表示不清空原文件,在文件末尾处追加新内容。

      4.按照字节,一个一个字节读取文件。

            int n = -1;
                while ((n = fis.read()) != -1) {
                    sb.append((char)n);
                }
                System.out.println(sb);

      5.将byte数组直接声明为输入流的长度,一次性读出所有文字。

    byte[] bytes = new byte[fis.available()];
    fis.read(bytes);
    sb.append(new String(bytes));
    System.out.println(sb);

      6.一次读取1024个字节。

      byte[] bytes = new byte[1024];
       int n = -1;
      while ((n = fis.read(bytes)) != -1) {
        sb.append(new String(bytes));
       }
       System.out.println(sb);

      7.将字符串转为Byte数组,并通过输出流写入文件。

    fos.write("12345".getBytes());
                System.out.println(sb);

      8.finally 无论上述代码是否会出现异常,都会执行的一段代码; 

         通常用于关闭各种资源。

               
    finally {
    /** * finally 无论上述代码是否会出现异常,都会执行的一段代码; * 通常用于关闭各种资源。 */ try { fis.close(); fos.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }
    }

    2.[BufferedInputStream、BufferedOutputStream] 

         继承自java.io.FilterOutputStream(此类是过滤输出流的所有类的超类)
      1、 作用: 在基本流的基础上进行包装,读取或者写入文件时,将通过缓存进行。
       即,先将内容写入到缓存区,缓存区满以后再进行读取或写入操作。
       可以大大减小文件的操作次数,提高写入效率。
      2、 缓存流的使用:
      在基本流的基础之上,进行包装:
      new BufferedInputStream(new FileInputStream("F:/test.txt"));
      这种写法,我们称之为IO链,IO关闭时只需要关闭最外层流,内层流将自动关闭。
      3、 BufferedOutputStream在关闭前,通常调用bos.flush();
      表示关闭前将缓存进行刷新,将缓存区剩余未满的内容写入文件。
      但是一般.close()方法,自带刷新功能。

    BufferedInputStream bis = null;
            BufferedOutputStream bos = null;
            try {
                bis = new BufferedInputStream(new FileInputStream("F:/test.txt"));
                
                bos =  new BufferedOutputStream(new FileOutputStream("F:/out.txt",false));
                
                StringBuffer sb = new StringBuffer();
                
                int n = -1;
                while ((n = bis.read()) != -1) {
                    sb.append((char)n);
                }
                System.out.println(sb);
                
                bos.write(sb.toString().getBytes());
                
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                /**
                 * finally 无论上述代码是否会出现异常,都会执行的一段代码;
                 * 通常用于关闭各种资源。
                 */
                try {
    //                fis.close();
                    bis.close();
    //                fos.close();
                    
                    /**
                     * 在程序最后,刷新缓存流,将缓存流中未满的内容,写入到文件中。
                     * 调用close()方法,将自动刷新。
                     */
                    bos.flush();
                    bos.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }

    3.[DataOutputStream/DataInputStream]   

      1.采用二进制对文件进行读写操作。
         与基本流相比,可以直接读写Java中的基本数据类型。
         另外,如果操作的文件是一个二进制文件,需要使用DataOutputStream替代FileOutputStream。
         同样,Data系列的流,也有read和write方法,操作与基本相同。
     注意: 使用DataOutputStream写入文件为二进制文件,只能使用DataInputStream进行读取。

    String name = "zhangsan";
            int age = 12;
            double height = 178.5;
            String ads = "山东烟台";
            
            DataOutputStream dos = null;
            DataInputStream dis = null;
            
            try {
                dos = new DataOutputStream(new FileOutputStream("F:\zhangsan.txt"));
                dos.writeUTF(name);
                dos.writeInt(age);
                dos.writeDouble(height);
                dos.writeUTF(ads);
                
                dis = new DataInputStream(new FileInputStream("F:\zhangsan.txt"));
                String uname = dis.readUTF();
                int uage = dis.readInt();
                double uheight = dis.readDouble();
                String uads = dis.readUTF();
                
                System.out.println(uname+"---"+uage+"---"+uheight+"---"+uads);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } finally{
                try {
                    dis.close();
                    dos.flush();
                    dos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            

    4.[ObjectOutputStream/ObjectInputStream] 

      直接继承自:java.io.OutputStream 抽象类
       1、 与基本流相同,可以直接使用read、write方法进行读写。
       2、 与DateInputStream相同,可以对Java基本数据类型进行直接读写: readInt() writeDouble()
       3、 可以只用readObject() 和 writeObject() 直接对对象进行操作。
    [对象的序列化和反序列]
      1、 对象的序列化: 将程序中的对象,持久化的保存在文件中的过程。 ObjectOutputStream
      2、 对象的反序列化: 将文件中保存的对象,重新读取到程序中的过程呢。ObjectInputStream
       如果,要将对象进行序列操作,那么实体类必须实现可序化接口:
       class Person implements Serializable{}
    注意: 当一个实体类,实现可序化接口后,可以添加一个序列化版本号ID。
     (实现序列化接口后,根据警告提示,选择:Adds a generated serial version ID)
      会自动生成一个静态属性:
       private static final long serialVersionUID = -1954048587316264652L;
      添加以后,可以用ID表示序列化和反序列时操作的对象,是同一个对象。
      如果不添加版本ID,当序列化一个对象后,如果实体类属性有增删,再进行反序列化时,会造成错误。
      因为系统认为这已经不是一个类。

    Person zhangsan = new Person("张三", 12, 178.4, "山东烟台杰瑞教育");
            
            ObjectOutputStream oos = null;
            ObjectInputStream ois = null;
            
            try {
                // 对象的序列化
                oos = new ObjectOutputStream(new FileOutputStream("F:/user.txt"));
                oos.writeObject(zhangsan);
                
                // 对象的反序列化
                ois = new ObjectInputStream(new FileInputStream("F:/user.txt"));
                Person p = (Person)ois.readObject();
                System.out.println(p);
                
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            } finally{
                try {
    //                ois.close();
                    oos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            
    class Person implements Serializable{
        
    //    private static final long serialVersionUID = -1954048587316264652L;
        private String name;
        private int age;
        private double height;
        private String ads;
        private double weight;
        
        public Person(String name, int age, double height, String ads) {
            super();
            this.name = name;
            this.age = age;
            this.height = height;
            this.ads = ads;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public int getAge() {
            return age;
        }
        public void setAge(int age) {
            this.age = age;
        }
        public double getHeight() {
            return height;
        }
        public void setHeight(double height) {
            this.height = height;
        }
        public String getAds() {
            return ads;
        }
        public void setAds(String ads) {
            this.ads = ads;
        }
        @Override
        public String toString() {
            return "Person [name=" + name + ", age=" + age + ", height=" + height
                    + ", ads=" + ads + "]";
        }
    }

    5.【字符流】  1. 在处理数据单元时,以一个字符作为单位。而字节流,是以一个字节为单位。
      2.字符流的基类:
       Reader和Writer,这两个类是抽象类。
      FileReader和FileWriter是直接继承自抽象类的两个字符基本流。
      3.FileReader和FileWriter在读写文件的时候,只能使用系统默认的编码模式,无法指定编码。
      如果文件格式与系统默认格式不一致,那使用这俩个方法编写会造成中文乱码。

    FileWriter fw=null;
            FileReader fr=null;
            try {
                 fw=new FileWriter("D:/Test/test01.txt");
                 String s="帅帅:shuaishuai";
                 fw.write(s);//可以直接写字符串
    //             for(int i=0;i<s.length();i++){
    //                 fw.write(s.charAt(i));
    //        }
                 fw.flush();
                 fr=new FileReader("D:/Test/test01.txt");
                 int n=0;
                 StringBuffer sb=new StringBuffer();
                 while((n=fr.read())!=-1){
                     sb.append((char)n);
                     
                 }
                 System.out.println(sb.toString());
            }
                 catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }finally{
                try {
                    fw.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

    6.【InputSteamReader/OutputStreamWriter】 

        1.将字符转为字符串,同时支持自定义读写的编码格式。
      2.常见编码格式:
      ASCII:美国标准信息码
       ISO8859-1:欧洲码
      ANSI编码:可以分为很多种。
       简体中文:
       GB2312
       GBK
       繁体中文:big-5
       Unicode编码:国际标准码,兼容绝大部分国家的编码格式。
       可以分为UTF-6,UTF-8,UTF-16

    InputStreamReader isr=null;
            OutputStreamWriter osw=null;
            try {
                isr= new InputStreamReader(new FileInputStream("D:/Test/test001.txt"),"UTF-8" );
                int n=0;
                StringBuffer sb=new StringBuffer();
                while((n=isr.read())!=-1){
                    sb.append((char)n);
                }
                System.out.println(sb);
                osw=new OutputStreamWriter(new FileOutputStream("D:/Test/test001.txt"),"UTF-8");
                String s="shuai真帅";
                osw.write(s);
                osw.flush();
            } catch (UnsupportedEncodingException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } finally{
                try {
                    isr.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }

    7.【BufferedReader/BufferedWriter】

       原来的字符串s是UTF-8的编码格式。
       使用 s.getBytes("UTF-8") ,表示用UTF-8对字符串进行解码为字节数组。
       s=new String(s.getBytes("UTF-8"),"GBK");
       表示将解码后的字节数组,重新使用GBK的编码,组合成字符串。
       最终:一个UTF-8的字符串,通过解析编码解析成GBK的编码形式。

    BufferedReader br=null;
            BufferedWriter bw=null;
            try{
                br= new BufferedReader(new InputStreamReader(new FileInputStream("D:/Test/test001.txt")));
                int n=0;
                StringBuffer sb=new StringBuffer();
                while((n=br.read())!=-1){
                    sb.append((char)n);
                }
                System.out.println(sb);
                
                bw= new BufferedWriter(new OutputStreamWriter(new FileOutputStream("D:/Test/test001.txt"))); 
                
                    String s=sb.toString()+"hahahaha呵呵呵";
                    s=new String(s.getBytes("UTF-8"),"GBK");
                    
            }catch (UnsupportedEncodingException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
  • 相关阅读:
    jquery.validate使用攻略 5
    jquery.validate使用攻略 4
    ccnet1.5集成tfs中文版的问题
    解决mysql连接异常—com.mysql.jdbc.CommunicationsException: Communications link failure due to underlying exception
    Myeclipse 6.5 增加对 JavaEE 6 的支持
    Python3.7环境配置
    myeclipse 8.6 software and workspace center is currently not available
    入坑cordova
    开启博客之路
    如何在高并发的分布式系统中产生UUID
  • 原文地址:https://www.cnblogs.com/gcywj/p/8906222.html
Copyright © 2020-2023  润新知