23 IO流(3)

23 IO流(3)

引言

早上已经完成IO流的相对应的练习,主要是IO流对电脑文件相对应的操作,FileInputStream和FileOutputStream的练习,接下来继续IO流,但主要会有点变化,接下来的是字符流综合使用

  1. 一篇文章中出现了多少个好字。读取数据,使用了字符流FileReader
  2. 演示FileWriter
  3. 演示转换流,和子类的区别五星
  4. 字符流缓冲区对象的使用
  5. 通过字符流复制文件
  6. 文件后缀名过滤器
  7. 分隔符工具类
  8. 请删除一个带有内容的目录
  9. 将学生对象(姓名,语文分数,数学分数,英语分数,总分)按照总分从高到低排序五星并将姓名和从高到低总分写入文件中
  10. 建立一个java文件清单列表

公共类Student.java

    package cn.itcast.domain;
    
    public class Student implements Comparable<Student>{
    
        private String name;
        private int cn,en,ma;
        private int sum;
        public Student() {
            super();
        }
        public Student(String name, int cn, int en, int ma) {
            super();
            this.name = name;
            this.cn = cn;
            this.en = en;
            this.ma = ma;
            this.sum = cn + en + ma;
    
        }
    
    
    
        @Override
        public int compareTo(Student o) {
            int temp = this.sum - o.sum;
    
            return temp==0?this.name.compareTo(o.name):temp;
        }
        @Override
        public int hashCode() {
            final int prime = 31;
            int result = 1;
            result = prime * result + cn;
            result = prime * result + sum;
            return result;
        }
        @Override
        public boolean equals(Object obj) {
            if (this == obj)
                return true;
            if (obj == null)
                return false;
            if (getClass() != obj.getClass())
                return false;
            Student other = (Student) obj;
            if (cn != other.cn)
                return false;
            if (sum != other.sum)
                return false;
            return true;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public int getCn() {
            return cn;
        }
    
        public void setCn(int cn) {
            this.cn = cn;
        }
        public int getEn() {
            return en;
        }
        public void setEn(int en) {
            this.en = en;
        }
        public int getMa() {
            return ma;
        }
        public void setMa(int ma) {
            this.ma = ma;
        }
        public int getSum() {
            return sum;
        }
        public void setSum(int sum) {
            this.sum = sum;
        }
    
    
    
        @Override
        public String toString() {
            return "Student [name=" + name + ", sum=" + sum + "]";
        }
    
    
    }

一篇文章中出现了多少个好字。读取数据,使用了字符流FileReader

package cn.itcast.io.a.charstream;
    
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.FileReader;
    import java.io.IOException;
    
    public class CharStreamDemo {
    
        /**
         * @param args
         * @throws IOException 
         */
        public static void main(String[] args) throws IOException {
    
            /*
             * 需求1:通过流写一个篇文章,里面有中文。"你好你好"。indexOf('好');
             */
    //        writeCNText();
    
    
            /*
             * 需求2:一篇文章中出现了多少个好字。读取数据。判断好字并计数。
             * 思路:读取一个文本,获取内容判断好字。
             */
    
             readCNText();
    
            /*
             * 解决需求2问题:
             * 使用FileReader。
             * 
             */
             System.out.println("-----------读取字符-------------");
            readCNTextByReader();
    
        }
    
        public static void readCNTextByReader() throws IOException {
    
            //创建一个读取字符文件的读取流对象。FileReader。
            FileReader fr = new FileReader("tempfile\\cn.txt");//这个流的底层使用的是FileInputStream
    
    //        int ch = fr.read();
    //        System.out.println("读取一个字符:"+ch);
    //        int ch1 = fr.read();//一次读取一个中文,读取多个字节查表转成中文。
    //        System.out.println("读取一个字符:"+(char)ch1);
            int ch = 0;
            int count = 0;
            while((ch=fr.read())!=-1){
                if(ch=='好'){
                    count++;
                }
            }
            System.out.println("count="+count);
            fr.close();
        }
    
        public static void readCNText() throws IOException {
            FileInputStream fis = new FileInputStream("tempfile\\cn.txt");
    
            //一次读一个字节。这样对中文是无法判断。怎么解决呢?一个中文默认是两个字节。
            //读取所有的字节,存储起来(字节数组),变成字符串。然后找指定的字符。
    
    //        byte[] buf = new byte[4];
    //        int len = 0;
    //        while((len=fis.read(buf))!=-1){
    //            String str = new String(buf,0,len);
    //            System.out.println(str);
    //        }
    
    //        int ch = 0;
    //        while((ch=fis.read())!=-1){
    //            System.out.println(ch);
    //        }
    
            int ch = fis.read();
            System.out.println("读取一个字节:"+ch);
            int ch1 = fis.read();
            System.out.println("读取一个字节:"+ch1);
            fis.close();
    
        }
    
        public static void writeCNText() throws FileNotFoundException, IOException {
            FileOutputStream fos = new FileOutputStream("tempfile\\cn.txt");
    
            fos.write("你好你好".getBytes());
    
            fos.close();
        }
    
    } 

演示FileWriter

package cn.itcast.io.a.charstream;
    
    import java.io.FileWriter;
    import java.io.IOException;
    
    public class FileWriterDemo {
    
        /**
         * @param args
         * @throws IOException 
         */
        public static void main(String[] args) throws IOException {
            //演示FileWriter 用于操作文件的便捷类。
            FileWriter fw = new FileWriter("tempfile\\fw.txt");
    
            fw.write("你好谢谢再见");//这些文字都要先编码。都写入到了流的缓冲区中。
    
            fw.flush();
    
            fw.close();
    
            /*
             * flush()和close()的区别?
             * 
             * flush():将流中的缓冲区缓冲的数据刷新到目的地中,刷新后,流还可以继续使用。
             * close():关闭资源,但在关闭前会将缓冲区中的数据先刷新到目的地,否则丢失数据,然后在关闭流。流不可以使用。
             * 
             * 如果写入数据多,一定要一边写一边刷新,最后一次可以不刷新,由close完成刷新并关闭。
             * 
             * 
             */
        }
    
    }
    
    
    //public void close(){
    //    flush();
    //} 

演示转换流,和子类的区别五星

package cn.itcast.io.b.transstream;
    
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.FileReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.io.OutputStreamWriter;
    import java.io.UnsupportedEncodingException;
    
    public class TransStreamDemo {
    
        /**
         * @param args
         * @throws IOException 
         * @throws UnsupportedEncodingException 
         */
        public static void main(String[] args) throws Exception {
    
    //        writeCN();
    
            readCN();
            /*
            总结:
            发现继承关系是这样的。
            OutputStreamWriter:
                |--FileWriter:
    
            InputStreamReader:
                |--FileReader;
    
            父类和子类的功能有什么区别呢?
    
            OutputStreamWriter和InputStreamReader是字符和字节的桥梁:也可以称之为字符转换流。
            字符转换流原理:字节流+编码表。
    
            FileWriter和FileReader:作为子类,仅作为操作字符文件的便捷类存在。
            当操作的字符文件,使用的是默认编码表时可以不用父类,而直接用子类就完成操作了,简化了代码。
    
            InputStreamReader isr = new InputStreamReader(new FileInputStream("a.txt"));//默认字符集。
            InputStreamReader isr = new InputStreamReader(new FileInputStream("a.txt"),"GBK");//指定GBK字符集。
            FileReader fr = new FileReader("a.txt");
            这三句代码的功能是一样的,其中第三句最为便捷。
    
            注意:一旦要指定其他编码时,绝对不能用子类,必须使用字符转换流。
            什么时候用子类呢?
            条件:
            1,操作的是文件。
            2,使用默认编码。
    
            字节--->字符 : 看不懂的--->看的懂的。  需要读。输入流。 InputStreamReader
            字符--->字节 : 看的懂的--->看不懂的。  需要写。输出流。 OutputStreamWriter
    
    
            */
        }
    
        public static void readCN() throws IOException {
    
            //创建InputStreamReader对象。
            InputStreamReader isr = new InputStreamReader(new FileInputStream("tempfile\\u8cn.txt"),"UTF-8");
    
            char[] buf = new char[1024];
            int len = isr.read(buf);
            System.out.println(new String(buf,0,len));
            isr.close();
        }
    
        //读取中文。
        public static void readCN_no() throws IOException {
    
            // 使用FileReader没出来,因为文件是UTF-8编码。读取UTF-8字节时,用该指定用UTF-8解码。
            // 说明需要指定码表。那就需要使用InputStreamReader。
            FileReader fr = new FileReader("tempfile\\u8cn.txt");
    //        int ch = (char)fr.read();
    //        System.out.println((char)ch);
            char[] buf = new char[1024];
            int len = fr.read(buf);
            System.out.println(new String(buf,0,len));//浣犲ソ
    
    
            fr.close();
    
        }
    
        public static void writeCN() throws Exception {
            //需求:既然识别中文的码表有两个,GBK UTF-8
            //能不能将中文数据按照utf-8的方式进行文件的存储呢?
            //还能使用FileWriter吗?不能使用了,因为FileWriter中默认的是GBK
            //通过FileWriter的api描述,要指定编码表这些值,需要使用OutputStreamWriter 
            //OutputStreamWriter 是字符流通向字节流的桥梁:可使用指定的 charset 将要写入流中的字符编码成字节。
            //它的作用的就是,将字符串按照指定的编码表转成字节,在使用字节流将这些字节写出去。
    
            OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("tempfile\\u8cn.txt"),"utf-8");
    
            osw.write("你好");//写入缓冲区。
    
            osw.close();
        }
    
    } 

字符流缓冲区对象的使用

package cn.itcast.io.c.charstream.buffercopy;
    
    import java.io.BufferedReader;
    import java.io.BufferedWriter;
    import java.io.FileReader;
    import java.io.FileWriter;
    import java.io.IOException;
    
    public class CharStreamBufferedTest {
    
        /**
         * @param args
         * @throws IOException 
         */
        public static void main(String[] args) throws IOException {
            /*
             * 字符流中是否有提供缓冲区中。
             * 注意:其实自定义数组就可以解决问题缓冲区问题并提高效率。
             * 为什么还要使用流中的缓冲区对象呢?因为缓冲区对象中除了封装数组以外,
             * 还提供了更多的操作缓冲区数据的方法。
             * BufferedReader  BufferedWriter
             * 
             * 讲解字符流缓冲区中的特有方法。
             * 操作字符数据时,有一个文本特有的表形实行 :行(hang)
             * 操作行的方法。
             * BufferedReader:readLine():一次读取一行。
             * BufferedWriter:
             */
    
            copyTextByBuffer();
    //        readText();
    
    //        writeText();
        }
    
        public static void writeText() throws IOException {
            BufferedWriter bufw = new BufferedWriter(new FileWriter("tempfile\\test24_buf.txt"));
    
            for(int x=1; x<=4; x++){
                bufw.write(x+"-itcast");
                bufw.newLine();
                bufw.flush();
            }
            bufw.close();
        }
    
        public static void readText() throws IOException {
    
            BufferedReader bufr = new BufferedReader(new FileReader("Test24.java"));
    
    
            String line = null;
            while((line=bufr.readLine())!=null){
    
                System.out.println(line);
    
            }
    
    //        String line = bufr.readLine();
    //        System.out.println("-"+line+"-");
    //        String line1 = bufr.readLine();
    //        System.out.println("-"+line1+"-");
    
            bufr.close();
    
    
        }
    
        public static void copyTextByBuffer() throws IOException {
    
            BufferedReader bufr = new BufferedReader(new FileReader("Test24.java"));
            BufferedWriter bufw = new BufferedWriter(new FileWriter("tempfile\\test24_bufcopy.txt"));
    
            //循环读写一行数据。
            String line = null;
            while((line=bufr.readLine())!=null){
                bufw.write(line);
                bufw.newLine();
                bufw.flush();
            }
    
            bufw.close();
            bufr.close();
    
        }
    
    } 

通过字符流复制文件

package cn.itcast.io.c.charstream.copy;
    
    import java.io.FileNotFoundException;
    import java.io.FileReader;
    import java.io.FileWriter;
    import java.io.IOException;
    
    public class CopyTextFileTest {
    
        /**
         * @param args
         * @throws IOException 
         */
        public static void main(String[] args) throws IOException {
            /*
             * 练习:复制文本文件。
             * 思路:
             * 1,既然是文本涉及编码表。需要用字符流。
             * 2,操作的是文件。涉及硬盘。
             * 3,有指定码表吗?没有,默认就行。
             * 操作的是文件,使用的 默认码表。使用哪个字符流对象。直接使用字符流操作文件的便捷类。FileReader  FileWriter
             */
            copyTextFile();
        }
    
        public static void copyTextFile() throws IOException {
            //1,明确源和目的。
            FileReader fr = new FileReader("Test24.java");
            FileWriter fw = new FileWriter("tempfile\\test24_copy.txt");
    
            //2,为了提高效率。自定义缓冲区数组。字符数组。
            char[] buf = new char[1024];
    
            int len = 0;
            while((len=fr.read(buf))!=-1){
                fw.write(buf,0,len);
            }
    
    
            //2,循环读写操作。效率低。
    //        int ch = 0;
    //        while((ch=fr.read())!=-1){
    //            fw.write(ch);
    //        }
    
    
            //3,关闭资源。
            fw.close();
            fr.close();
    
        }
    
    } 

文件后缀名过滤器

package cn.itcast.io.test;
    
    import java.io.File;
    import java.io.FileFilter;
    
    public class FileFilterBySuffix implements FileFilter {
    
        private String suffix;
    
        public FileFilterBySuffix(String suffix) {
            super();
            this.suffix = suffix;
        }
    
        @Override
        public boolean accept(File pathname) {
    
            return pathname.getName().endsWith(suffix);
        }
    
    } 

[分隔符工具类]

package cn.itcast.io.test;
    
    /**
     * 为了避免总是调用System.getProperties("系统属性中的指定键");
     * 进行了封装。下次再使用分隔符,直接找个分隔符工具类就哦了。
     * @author Teaching
     *
     */
    public class SeparatorTool {
    
    
        private  SeparatorTool() {
            super();
        }
        public static final String LINE_SEPARATOR = System.getProperty("line.separator");
        public static final String PATH_SEPARATOR = System.getProperty("path.separator");
        public static final String FILE_SEPARATOR = System.getProperty("file.separator");
    
    
    } 

请删除一个带有内容的目录

package cn.itcast.io.test;
    
    import java.io.File;
    
    public class Test2 {
    
        /**
         * @param args
         */
        public static void main(String[] args) {
            // 2,请删除一个带有内容的目录。
            /*
             * 思路: 1,删除一个带有内容的目录原理;必须从里往外删。 2,到底有多级目录不确定,递归。
             */
            File dir = new File("E:\\test");
    
            // System.out.println(dir.delete());
    
            removeDir(dir);
    
        }
    
        /**
         * 删除一个目录。
         */
        public static void removeDir(File dir) {
    
            // 1,列出当前目录下的文件以及文件夹File[]
            File[] files = dir.listFiles();//如果目录是系统级文件夹,java没有访问权限,那么会返回null数组。最好加入判断。
            if (files != null) {
                // if(files.length == 0){
                // dir.delete();
                // return;
                // }
    
                for (File file : files) {
    
                    // 2,对遍历到的file对象判断是否是目录。
                    if (file.isDirectory()) {
                        removeDir(file);
                    } else {
                        System.out.println(file + ":" + file.delete());// 删除文件。用打印语句验证是否删除成功,是否出现了误删操作。
                    }
                }
            }
            System.out.println(dir + ":" + dir.delete());
    
        }
    } 

将学生对象(姓名,语文分数,数学分数,英语分数,总分)按照总分从高到低排序五星并将姓名和从高到低总分写入文件中

package cn.itcast.io.test;
    
    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.util.Collections;
    import java.util.Set;
    import java.util.TreeSet;
    
    import cn.itcast.domain.Student;
    
    public class Test4 {
    
        private static final String LINE_SEPARATOR = System.getProperty("line.separator");
    
        /**
         * @param args
         * @throws IOException 
         */
        public static void main(String[] args) throws IOException {
    //        4,将学生对象(姓名,语文分数,数学分数,英语分数,总分)按照总分从高到低排序,
    //        并将姓名和从高到低总分写入文件中。
            /*
             * 思路:
             * 1,描述学生。
             * 2,既然要按照总分从高到低排序,学生多要存储集合,TreeSet。
             * 3,将信息具体的信息保存到文件中。
             *         操作文件,持久化存储,涉及了IO技术。而且是将数据存储到文件中。所以写入。输出流。
             * 
             */
            Set<Student> set = new TreeSet<Student>(Collections.reverseOrder());
    
            set.add(new Student("李四",20,20,20));
            set.add(new Student("旺财",10,10,20));
            set.add(new Student("小明",60,30,70));
            set.add(new Student("小红",80,90,80));
            set.add(new Student("小强",20,70,20));
    
            File dir = new File("tempfile");
            if(!dir.exists()){
                dir.mkdir();
            }
            File destFile = new File(dir,"student_info.txt");
            write2File(set,destFile);
    
    
    
    
        }
    
        public static void write2File(Set<Student> set, File destFile) throws IOException {
    
            //1, 创建输出流对象和目的文件关联。并创建目的文件。OutputStream操作文件 FileOutputStream。
            FileOutputStream fos = null;
            try{
                fos = new FileOutputStream(destFile);
                //2,遍历集合中的对象数据。将数据写入到指定文件中。
    
                for(Student stu : set){
                    String info = stu.getName()+"\t"+stu.getSum()+LINE_SEPARATOR;
                    //3,将数据写入到文件中。
                    fos.write(info.getBytes());
                }
            }finally{
                if(fos!=null){
    
                    //关闭资源。
                    try {
                        fos.close();
                    } catch (IOException e) {
                        throw new RuntimeException("系统资源关闭失败");
                    }
                }
            }
    
        }
    
    } 

建立一个java文件清单列表

package cn.itcast.io.test;
    
    import java.io.BufferedOutputStream;
    import java.io.File;
    import java.io.FileFilter;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.util.ArrayList;
    import java.util.List;
    
    public class Test5 {
    
        private static final String LINE_SEPARATOR = SeparatorTool.LINE_SEPARATOR;
    
        /**
         * @param args
         * @throws IOException 
         */
        public static void main(String[] args) throws IOException {
    //        5,获取指定目录下所有的.java文件(包含子目录中的),
    //        并将这些java文件的绝路路径写入到一个文件中。
    //        建立一个java文件清单列表。
            /*
             * 思路:
             * 1,一看到包含子目录,必须递归。
             * 2,写数据到文件,输出流。
             * 3,继续分析,发现只要.java ,需要过滤器。
             * 4,满足过滤的条件的文件有可能非常多,先进行存储。
             */
            //被遍历的目录。
            File dir = new File("E:\\Java_Code");
    
            //明确一个过滤器。
            FileFilter filter = new FileFilterBySuffix(".java");
    
    
            //符合过滤器条件的文件有很多,最好先存储起来,然后在进行操作。
            List<File> list = new ArrayList<File>();
            //获取指定文件清单。
            getFileList(dir,filter,list);
    //        System.out.println(list.size());
    
            File destFile = new File(dir,"javalist.txt");
            write2File(list,destFile);
        }
    
        /**
         * 将集合中的数据的绝对路径写入到文件中。
         * @param list
         * @param destFile
         * @throws IOException 
         */
        public static void write2File(List<File> list, File destFile) throws IOException {
            FileOutputStream fos = null;
            BufferedOutputStream bufos = null;
            try{
                fos = new FileOutputStream(destFile);
                bufos = new BufferedOutputStream(fos);
    
                for(File file : list){
                    String info = file.getAbsolutePath()+LINE_SEPARATOR;
                    bufos.write(info.getBytes());
                    bufos.flush();//每写一个绝对路径就刷新一次。
                }
            }finally{
                if(bufos!=null){
                    try {
                        fos.close();
                    } catch (IOException e) {
                        throw new RuntimeException("关闭失败");
                    }
                }
            }
    
        }
    
        /**
         * 根据指定的过滤器在指定目录下获取所有的符合过滤条件的文件,并存储到list集合中。
         * @param dir
         * @param filter
         * @param list
         */
        public static void getFileList(File dir,FileFilter filter,List<File> list) {
    
            File[] files = dir.listFiles();
    
            for(File file : files){
    
                if(file.isDirectory()){
                    getFileList(file,filter,list);
                }else{
                    //如果是文件,传递到过滤器中去过滤。将满足条件存储起来。
                    if(filter.accept(file)){
                        list.add(file);
                    }
                }
            }
    
        }
    
    
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值