zoukankan      html  css  js  c++  java
  • 2019-05-30 Java学习日记之IO(字符流)&字符流其他内容&递归

    IO(字符流)

     字符流FileReader:

    1、字符流是什么?

    字符流是可以直接读写字符的IO流

    字符流读取字符,就要先读取到字节数据,然后转为字符。如果要写出字符,需要吧字符转为字节再写出

    2、FileReader

    FileReader类的read()方法可以按照字符大小读取

    package com.chario;
    
    import java.io.FileNotFoundException;
    import java.io.FileReader;
    import java.io.IOException;
    
    public class Demo1 {
    
        public static void main(String[] args) throws IOException {
    //        demo1();
            FileReader fr = new FileReader("xxx.txt");
            int c;
            while((c = fr.read()) != -1){                //通过项目默认的码表一次读取一个字符
                System.out.print((char)c);
            }
        }
    
        public static void demo1() throws FileNotFoundException, IOException {
            FileReader fr = new FileReader("xxx.txt");
            int x = fr.read();
            System.out.println(x);
            char c = (char)x;
            System.out.println(c);
            fr.close();
        }
    
    }

    字符流FileWriter:

    FileWriter类的writer()方法可以自动吧字符转为字节写出

    package com.chario;
    
    import java.io.FileWriter;
    import java.io.IOException;
    
    public class Demo2 {
        public static void main(String[] args) throws IOException {
            FileWriter fw = new FileWriter("yyy.txt");
            fw.write("努力,坚持");
            fw.write(99);
            fw.close();
        }
    }

    字符流的拷贝:

    package com.chario;
    
    import java.io.FileReader;
    import java.io.FileWriter;
    import java.io.IOException;
    
    public class Demo3 {
        public static void main(String[] args) throws IOException {
            FileReader fr1 = new FileReader("xxx.txt");
            FileWriter fw1 = new FileWriter("zzz.txt");
            
            int c;
            while ((c = fr1.read()) != -1) {
                fw1.write(c);
            }
             fr1.close();
             fw1.close();        //Writer类中有一个2k的小缓冲区,如果不关流,就会将内容写到缓冲区里,关流会将缓冲区内容刷新,再关闭
        }
    }

    什么情况下使用字符流:

    字符流也可以拷贝文本文件,但不推荐使用。因为读取时会把字节转为字符,写出时还有把字符转回字节。

    程序需要读取一段文本,或者需要写出一段文本的时候可以使用字符流

    读取的时候是按照字符的大小读取的,不会出现半个中文

    写出的时候可以直接将字符串写出,不用转换成字节数组

    字符流是否可以拷贝非纯文本的文件:

    不可以拷贝非纯文本的文件

    因为在读的时候会将字节转换为字符,在转换过程中,可能找不到对应的字符,就会用?代替,

    写出的时候会将字符转换成字节写出去

    如果是?,直接写出,这样写出之后的文件就乱了,不用转换为字节数组

    自定义字符数组的拷贝:

    public static void demo2() throws FileNotFoundException, IOException {
            FileReader fr1 = new FileReader("xxx.txt");
            FileWriter fw1 = new FileWriter("yyy.txt");
            
            char[] arr = new char[1024];
            int len;
            while ((len = fr1.read(arr)) != -1) {    //将文件上的数据读取到字符数组中    
                fw1.write(arr,0,len);                //将字符数组中的数据写到文件上
            }
            
            fr1.close();
            fw1.close();
        }

    带缓冲的字符流:

    BufferedReader的read()方法读取字符时会一次读取若干字符到缓冲区,然后逐个返回给程序,降低读取文件的次数,提高效率

    BufferedWriter()方法写出字符时会先写到缓冲区,缓冲区写满时才会写到文件,降低写文件的次数,提高效率

    public static void demo3() throws FileNotFoundException, IOException {
            BufferedReader bReader = new BufferedReader(new FileReader("xxx.txt"));
            BufferedWriter bWriter = new BufferedWriter(new FileWriter("yyy.txt"));
            
            int c; 
            while ((c = bReader.read()) != -1) {
                bWriter.write(c);
            }
            
            bReader.close();
            bWriter.close();
        }

    readLine()和newLine()方法:

    BufferedReader的readLine()方法可以读取一行字符(不包含换行符号)

    BufferedWriter的newLine()可以输出一个跨平台的换行符号" ";

    package com.chario;
    
    import java.io.BufferedReader;
    import java.io.BufferedWriter;
    import java.io.FileNotFoundException;
    import java.io.FileReader;
    import java.io.FileWriter;
    import java.io.IOException;
    
    public class Demo4 {
        /**
         * 带缓冲区的流中的特殊方法
         * readLine()
         * newLine()
         * 
         * newLine()
    的区别
         * newLine()是跨平台的方法
         * 
    值支持的是windows系统
         * 
         */
        public static void main(String[] args) throws IOException {
    //        demo1();
            BufferedReader bReader = new BufferedReader(new FileReader("zzz.txt"));
            BufferedWriter bWriter = new BufferedWriter(new FileWriter("aaa.txt"));
            
            String line;
            while((line = bReader.readLine()) != null){
                bWriter.write(line);
                //bWriter.newLine();             //写出回车换行符
                bWriter.write("
    ");
            }
            
            bReader.close();
            bWriter.close();
        }
    
        public static void demo1() throws FileNotFoundException, IOException {
            BufferedReader bReader = new BufferedReader(new FileReader("zzz.txt"));
            String line;
            
            while ((line = bReader.readLine()) != null) {
                System.out.println(line);
            }
            bReader.close();
        }
    }

    将文本反转:

    将一个文本文档上的文本反转,第一行和倒数第一行交换,第二行和倒数第二行交换

    package com.chario;
    
    import java.io.BufferedReader;
    import java.io.BufferedWriter;
    import java.io.FileReader;
    import java.io.FileWriter;
    import java.io.IOException;
    import java.util.ArrayList;
    
    public class Test1 {
        /**
         * 需求:将一个文本文档上的文本反转,第一行和倒数第一行交换,第二行和倒数第二行交换
         * 
         * 分析:
         * 1、创建输入输出流对象
         * 2、创建集合对象
         * 3、将读到的数据存储在集合中
         * 4、倒着遍历集合将数据写到文件上
         * 5、关流
         * 
         * 注意事项:流对象尽量晚开早关
         * @throws IOException 
         * 
         */
        public static void main(String[] args) throws IOException {
            //1、创建输入输出流对象
            BufferedReader bReader = new BufferedReader(new FileReader("zzz.txt"));
            
            //2、创建集合对象
            ArrayList<String> list = new ArrayList<>();
            //3、将读到的数据存储在集合中
            String line;
            while((line = bReader.readLine()) != null){
                list.add(line);
            }
            bReader.close();            //关流
            //4、倒着遍历集合将数据写到文件上
            BufferedWriter bWriter = new BufferedWriter(new FileWriter("revzzz.txt"));
            for (int i = list.size() - 1; i >= 0; i--) {
                bWriter.write(list.get(i));
                bWriter.newLine();
            }
            //5、关流
            bWriter.close();
        }
    }

    LineNumberReader:

    LineNumberReader是BufferedReader的子类,具有相同的功能,并且可以统计行号

    调用getLineNumber()方法可以获取当前行号

    调用setLineNumber()方法可以设置当前行号

    package com.chario;
    
    import java.io.FileReader;
    import java.io.IOException;
    import java.io.LineNumberReader;
    
    public class Demo5 {
        public static void main(String[] args) throws IOException {
            LineNumberReader lnr1 = new LineNumberReader(new FileReader("zzz.txt"));
            
            String line;
            lnr1.setLineNumber(100);
            
            while((line = lnr1.readLine()) != null){
                System.out.println(lnr1.getLineNumber() + ":" + line);
            }
            lnr1.close();
        }
    }

    装饰设计模式:

    package com.chario;
    
    public class Demo6 {
        /**
         *装饰设计模式的好处是:
         *耦合性不强,被装饰类的变化与装饰类的变化无关
         */
        public static void main(String[] args) {
            HeiMaStudent heiMaStudent = new HeiMaStudent(new Student());
            heiMaStudent.code();
        }
    
    }
    interface coder{
        public void code();
    }
    class Student implements coder {
        @Override
        public void code() {
            System.out.println("javase");
            System.out.println("javaweb");
        }
    }
    class HeiMaStudent implements coder {
        //1、获取被装饰类的引用
        private Student s;                //获取学生引用
        //2、在构造方法中传入被装饰类的对象
        public HeiMaStudent(Student s) {
            this.s = s;
        }
        //3、对原有的功能进行升级
        @Override
        public void code() {
            s.code();
            System.out.println("ssh");
            System.out.println("数据库");
            System.out.println("大数据");
            System.out.println("...");
        }
    }

    使用指定的码表读写字符:

    FileReader是使用默认码表读取文件,如果需要使用指定码表读取,那么可以使用InputStreamReader(字节流,编码表)

    FileWriter是使用默认码表写出文件,如果需要使用指定码表写出,那么可以使用OutputStreamReader(字节流,编码表)

    package com.chario;
    
    import java.io.BufferedReader;
    import java.io.BufferedWriter;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.FileReader;
    import java.io.FileWriter;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.io.OutputStreamWriter;
    import java.io.UnsupportedEncodingException;
    
    public class Demo7 {
        public static void main(String[] args) throws IOException {
    //        demo1();
    //        demo2();
            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();
            
        }
    
        public static void demo2() throws UnsupportedEncodingException, FileNotFoundException, IOException {
            InputStreamReader isr1 = new InputStreamReader(new FileInputStream("utf-8.txt"),"utf-8");    //指定码表读字符
            OutputStreamWriter osw1 = new OutputStreamWriter(new FileOutputStream("gbk.txt"), "gbk");    //指定码表写字符
            
            int c;
            while((c = isr1.read()) != -1) {
                osw1.write(c);
            }
            
            isr1.close();
            osw1.close();
        }
    
        public static void demo1() throws FileNotFoundException, IOException {
            //用默认的编码表读写,出现乱码
            FileReader fReader = new FileReader("utf-8.txt");
            FileWriter fWriter = new FileWriter("gbk.txt");
            
            int c;
            while((c = fReader.read()) != -1) {
                fWriter.write(c);
            }
            fReader.close();
            fWriter.close();
        }
    }

    获取文本上字符出现的次数:

    获取一个文本上每个字符出现的次数,将结果写在times.txt上

    package com.chario;
    
    import java.io.BufferedReader;
    import java.io.BufferedWriter;
    import java.io.FileNotFoundException;
    import java.io.FileReader;
    import java.io.FileWriter;
    import java.io.IOException;
    import java.util.TreeMap;
    
    public class Test2 {
        /**
         * 需求:获取一个文本上每个字符出现的次数,将结果写在times.txt上
         * 
         * 分析:
         * 1、创建带缓冲区的输入流对象
         * 2、创建双列集合对象TreeMap
         * 3、将读到的字符存储在双列集合中,存储的时候要做判断,如果不包含这个键,就将键和1存储,如果包含这个键,就将该键和值加1存储
         * 4、关闭输入流
         * 5、创建输出流对象
         * 6、遍历集合将集合中的内容写到times.txt中
         * 7、关闭输出流
         * @throws IOException 
         */
        public static void main(String[] args) throws IOException {
            //1、创建带缓冲区的输入流对象
            BufferedReader br = new BufferedReader(new FileReader("zzz.txt"));
            //2、创建双列集合对象TreeMap
            TreeMap<Character, Integer> tm = new TreeMap<>();
            // 3、将读到的字符存储在双列集合中,存储的时候要做判断,如果不包含这个键,就将键和1存储,如果包含这个键,就将该键和值加1存储
            int ch;
            while((ch = br.read()) != -1) {
                char c = (char)ch;        //强制类型转换
                /*if (!tm.containsKey(c)) {
                    tm.put(c, 1);
                }else {
                    tm.put(c, tm.get(c) + 1);
                }*/
                tm.put(c, !tm.containsKey(c) ? 1 : tm.get(c) + 1);
            }
            //4、关闭输入流
            br.close();
            //5、创建输出流对象
            BufferedWriter bw = new BufferedWriter(new FileWriter("times.txt"));
            //6、遍历集合将集合中的内容写到times.txt中
            for (Character key : tm.keySet()) {
                switch (key) {
                case '	':
                    bw.write("\t" + "=" + tm.get(key));
                    break;
                case '
    ':
                    bw.write("\r" + "=" + tm.get(key));
                    break;
                case '
    ':
                    bw.write("\n" + "=" + tm.get(key));
                    break;
                default:
                    bw.write(key + "=" + tm.get(key));        //写出键和值
                    break;
                }
                bw.newLine();
            }
            // 7、关闭输出流
            bw.close();
        }
    
    }

    试用版软件:

    package com.chario;
    
    import java.io.BufferedReader;
    import java.io.FileNotFoundException;
    import java.io.FileReader;
    import java.io.FileWriter;
    import java.io.IOException;
    
    public class Test3 {
        /**
         *需求:模拟试用版软件,试用10次机会
         *
         *分析:
         *1、创建带缓冲区的输入流对象,因为要使用readLine方法,可以保证数据的原样性
         *2、将读到的字符串转换为int数
         *3、对int数进行判断,如果大于0,就将其--写回去,如果不大于0,就提示请购买正版
         *4、在if判断中要将--的结果打印,并将结果通过输出流写到文件
         * @throws IOException 
         */
        public static void main(String[] args) throws IOException {
            //1、创建带缓冲区的输入流对象,因为要使用readLine方法,可以保证数据的原样性
            BufferedReader br = new BufferedReader(new FileReader("config.txt"));
            //2、将读到的字符串转换为int数
            String line = br.readLine();
            int times = Integer.parseInt(line);            //将数字字符串转换成数字
            //3、对int数进行判断,如果大于0,就将其--写回去,如果不大于0,就提示请购买正版
            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();
            
        }
    
    }

    递归

    5的阶乘:

    package com.chario;
    
    public class Demo8 {
        /**
         * 递归的弊端:不能调用次数过多,容易导致栈内存溢出
         * 递归的好处:不用知道循环次数
         * 
         * 构造方法是否可以使用递归调用?
         * 不能
         * 
         * 递归调用是否必须有返回值?
         * 不一定(可以有,也可以没有)
         * 
         */
        public static void main(String[] args) {
            System.out.println(fun(5));
        }
        public static int fun(int num){
            if (num == 1) {
                return 1;
            }else {
                return num * fun(num - 1);
            }
        }
    
    }

    Test:

    需求:从键盘输入接收一个文件夹路径,打印出该文件夹下所有的.java文件名

    package com.chario;
    
    import java.io.File;
    import java.util.Scanner;
    
    public class Test4 {
        /**
         * 需求:从键盘输入接收一个文件夹路径,打印出该文件夹下所有的.java文件名
         * 
         * 分析:
         * 从键盘输入接收一个文件夹路径
         * 1、如果录入的是不存在的,给予提示
         * 2、如果录入的是文件路径,给予提示
         * 3、如果是文件夹路径,直接返回
         * 
         * 打印出该文件夹下所有的.java文件名
         * 1、获取到该文件夹路径下的所有的文件和文件夹,存储在File数组中
         * 2、遍历数组,对每一个文件或文件夹做判断
         * 3、如果是文件,并且后缀是.java的,就打印
         * 4、如果是文件夹,就递归调用
         */
        public static void main(String[] args) {
            File dir = getDir();
            printJavaFile(dir);
        }
        /**
         * 获取键盘录入的文件夹路径
         * 1、返回值类型File
         * 2、不需要有参数
         */
        public static File getDir(){
            Scanner sc = new Scanner(System.in);            //创建键盘录入对象
            System.out.println("请输入一个文件夹路径:");
            while(true){
                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;
                }
            }
        }
        /**
         * 打印出该文件夹下所有的.java文件名
         * 1、返回值类型Void
         * 2、参数列表File dir
         */
        
        public static void printJavaFile(File dir) {
            //1、获取到该文件夹路径下的所有的文件和文件夹,存储在File数组中
            File[] subFiles = dir.listFiles();
            //2、遍历数组,对每一个文件或文件夹做判断
            for (File subFile : subFiles) {
                //3、如果是文件,并且后缀是.java的,就打印
                if (subFile.isFile() && subFile.getName().endsWith(".java")) {
                    System.out.println(subFile);
                //4、如果是文件夹,就递归调用
                }else if (subFile.isDirectory()) {
                    printJavaFile(subFile);
                }
            }
            
            
        }
    }
  • 相关阅读:
    SqL读取XML、解析XML、SqL将XML转换DataTable、SqL将XML转换表
    C#DataTable复制、C#DataTable列复制、C#DataTable字段复制
    Dev、GridControl的模糊查询
    C#两个时间相减
    C# % 和 /
    C#时间、日期 的操作
    linux文件操作
    shell ftp上传下载文件
    POM详细配置
    maven 本地setting.xml配置
  • 原文地址:https://www.cnblogs.com/clqbolg/p/10953060.html
Copyright © 2011-2022 走看看