对IO流的简单操作

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

/*
已知文件 source.txt 中的内容如下

    username=root, password=  1234,    id=1, level=   10
    username=adimin, mima= 1234   ,     id=2,    level=  11
    yonghu=  xiaoming   ,dengji=  12 ,password= 1234,id=  3
    yonghu=  xiaofang   ,dengji=  11 ,password= 1235,id=  3

其中,username、yonghu 都表示用户名,password、mima都表示密码,level、dengji都表示等级

- 在桌面上的这个source.txt文件拷贝到项目 file\data.txt 中(注意:方式不限,可以是移动或拷贝!)
- 读取文本中的数据,将每一行的数据封装成模型,存入 List<User> 中
- 去除集合中id重复的数据,只保留重复id的第一个数据
- 计算这些用户的平均等级、最高等级、最低等级

分析:
使用的技术点:
IO流的读写
File的使用
缓冲流
字节流
字符流

高级部分的:
Path
Paths
Files

 */
public class Demo2 {
    public static void main(String[] args) throws IOException {
        //- 在桌面上的这个source.txt文件拷贝到项目 file\data.txt 中(注意:方式不限,可以是移动或拷贝!)
        copyFile3("C:\\Users\\Administrator\\Desktop\\source.txt",
                "H:\\BigData\\SZBDjava_day0805\\src\\moning\\data.txt" );

        //读取文本中的数据,将每一行的数据封装成模型,存入 List<User> 中

        /*
        1.创建模型类
        2.读取数据,放入模型对象
        3.将模型对象放入List集合
        */
        //第一种方法:通过字符流实现数据的读入
        List<User>list=getData1();
        System.out.println(list);
        //第二种方法:
        //第三种方法:

        //- 读取文本中的数据,将每一行的数据封装成模型,存入 List<User> 中
        //- 去除集合中id重复的数据,只保留重复id的第一个数据
        //- 计算这些用户的平均等级、最高等级、最低等级
    }

    //- 在桌面上的这个source.txt文件拷贝到项目 file\data.txt 中(注意:方式不限,可以是移动或拷贝!)
    //第一种:使用renameto方法,只能移动,移动完成,源文件消失
    //注意:要保证目标目录中没有新的文件名.
    public static void copyFile1(String src,String dst){
        //创建文件
        createFile1(dst);

        File srcFile = new File(src);
        File dstFile = new File(dst);

        //移动
        srcFile.renameTo(dstFile) ;
    }
    //第二种:使用IO流实现文件的拷贝
    public static void copyFile2(String src,String dst)  {
        //创建文件
        createFile1(dst);

        //将src中的数据读取到dst中
        //使用最基本的字节流实现
        //创建输入流输出流
        InputStream inputStream = null;
        OutputStream outputStream = null;

        try {
            //将数据从src传入内存
            //创建FileinputStream对象并关联了数据来源路径
            inputStream = new FileInputStream(src);
            //将数据从内存传出到dst
            /*
            注意点:当用流关联路径时,
            1.可以使用绝对路径,也可以使用相对路径
            这里默认识别的是当前工程路径
            举例:
            outputStream = new FileOutputStream("haha.txt");
            识别路径:D:\ideaProgramU\SZBD2102Java_pro_03\haha.txt
            2.如果当前的文件(data.txt)已经存在,会直接覆盖
            如果不存在,自动创建一个叫data.txt的新的文件
            3.一定要保证dst是真实存在的.
            错误示范:直接报异常:FileNotFoundException
            outputStream = new FileOutputStream("r:/haha.txt");
             */

            outputStream = new FileOutputStream(dst);

            //完成读写过程
            /*
            一次读一个字节--read()
            一次读多个字节--read(数组),数组中临时存储的是当前读到的字节
            一次读所有字节--read(数组),一次将所有的字节都放入当前的临时数组
             */
            //使用一次读一个字节
            /*
            read():在读取字节时每次读取的是当前指针指向的字节,读完后,会自动将指针后移一位
            返回值:就是读到的字节,当读到末尾时,返回-1,证明读完了.
             */
//            int num = 0;
//            while ((num = inputStream.read()) != -1){
//                //System.out.print((char) num);
//                //write方法自己会自动进行转化
//                outputStream.write(num);
//            }

            //一次读多个字节--read(数组),数组中临时存储的是当前读到的字节
//            byte[] arr = new byte[5];
//            int num = 0;
//            while ((num = inputStream.read(arr)) != -1){
//                //System.out.print(new String(arr,0,num));
//                outputStream.write(arr,0,num);
//            }

            //一次读取所有--注意:要求数据的量不能太大,<=1kb
            //获取所有字节个数
            int number = inputStream.available();
            byte[] arr = new byte[number];
            inputStream.read(arr);
            outputStream.write(arr);

            //字节流只能识别字节,这里必须先转成字节.
            //outputStream.write("haha".getBytes(StandardCharsets.UTF_8));
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (inputStream != null){
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            if (outputStream != null){
                try {
                    outputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }
    //使用try(){}catch结构可以简化代码,达到自动关闭流的目的.
    public static void copyFile22(String src,String dst)  {
        //创建文件
        createFile1(dst);

        //将src中的数据读取到dst中
        //使用最基本的字节流实现
        //创建输入流输出流
        //InputStream inputStream = null;
        //OutputStream outputStream = null;

        //我们可以通过在try后面添加(),在()中创建流对象,好处:不再需要手动执行close关闭流,这里会自动关闭流
        //注意:必须保证try后面()中的类都是实现了Closeable接口.
        try(InputStream inputStream = new FileInputStream(src);
            OutputStream outputStream  = new FileOutputStream(dst);)
        {
            //将数据从src传入内存
            //创建FileinputStream对象并关联了数据来源路径

            //将数据从内存传出到dst
            /*
            注意点:当用流关联路径时,
            1.可以使用绝对路径,也可以使用相对路径
            这里默认识别的是当前工程路径
            举例:
            outputStream = new FileOutputStream("haha.txt");
            识别路径:D:\ideaProgramU\SZBD2102Java_pro_03\haha.txt
            2.如果当前的文件(data.txt)已经存在,会直接覆盖
            如果不存在,自动创建一个叫data.txt的新的文件
            3.一定要保证dst是真实存在的.
            错误示范:直接报异常:FileNotFoundException
            outputStream = new FileOutputStream("r:/haha.txt");
             */


            //完成读写过程
            /*
            一次读一个字节--read()
            一次读多个字节--read(数组),数组中临时存储的是当前读到的字节
            一次读所有字节--read(数组),一次将所有的字节都放入当前的临时数组
             */
            //使用一次读一个字节
            /*
            read():在读取字节时每次读取的是当前指针指向的字节,读完后,会自动将指针后移一位
            返回值:就是读到的字节,当读到末尾时,返回-1,证明读完了.
             */
            int num = 0;
            while ((num = inputStream.read()) != -1){
                //System.out.print((char) num);
                //write方法自己会自动进行转化
                outputStream.write(num);
            }
        }catch(IOException e){

        }

    }
    //第三种:使用Files(NIO方法)
    public static void copyFile3(String src,String dst){
        //创建文件
        createFile1(dst);

        try {
            Files.copy(Paths.get(src),Paths.get(dst));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    //创建目录
    //第一种:使用File的mkdir,mkdirs,createNewFile
    public static void  createFile1(String dst){
        /*
        createNewFile():只能用于创建文件
        mkdir():只能用于创建单层目录
        mkdirs():用于创建多层目录
         */

        //获取file目录
        int index = dst.lastIndexOf("\\");
        //"D:\\ideaProgramU\\SZBD2102Java_pro_03\\BD2102Java_day0805\\file"
        String str = dst.substring(0,index);

        //创建目录--file
        File file = new File(str);
        file.mkdir();

    }

    //第一种:使用Files提供的createDirectory方法----NIO
    //当使用使用Files提供的createDirectory方法创建目录时,必须保证目录是不存在的,如果已经存在,会报异常:FileAlreadyExistsException
    public static void  createFile2(String dst){
        //获取file目录
        int index = dst.lastIndexOf("\\");
        //"D:\\ideaProgramU\\SZBD2102Java_pro_03\\BD2102Java_day0805\\file"
        String str = dst.substring(0,index);

        //创建目录--file
        //Files.createDirectory()  创建一层目录
        //Files.createDirectories()   创建多层目录
        //createDirectory方法的参数是一个Path类型的,Path是对路径的封装,是NIO中提供的工具类
        //Paths:是对Path进行的再封装
        try {
            Files.createDirectory(Paths.get(str));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    //- 读取文本中的数据,将每一行的数据封装成模型,存入 List<User> 中

    //第一种方法:通过字符流实现数据的读入
    public static List<User> getData1(){

        //创建一个集合存储数据

        List<User> list=new ArrayList<>();

        //创建字符流对象,将数据读入内存
        try {
            Reader reader=new FileReader("H:\\BigData\\SZBDjava_day0805\\src\\moning\\data.txt");
            //开始读取
            //先有一个可变字符串,保存每一行的数据
            StringBuffer stringBuffer=new StringBuffer();
            int num=0;
            while ((num=reader.read())!=-1){
                //在windows中,一班\r\n同时使用
                if(num=='\r'){
                    continue;
                }else if(num=='\n'){
                    //说明当前行读完了
                    list.add(new User(stringBuffer.toString()));
                    //清楚上一次的数据,重新存储数据
                    stringBuffer.delete(0,stringBuffer.length());
                }else {
                    stringBuffer.append((char)num);
                }
            }
            //将最后一行放入lsit中
            list.add(new User(stringBuffer.toString()));
        } catch (IOException e) {
            e.printStackTrace();
        }

        return list;
    }

    //第二种方法:使用scanner
    public static List<User> getData2(){
        List<User> list=new ArrayList<>();
        //使用Scanner。默认可以从键盘接收数据
        //Scanner scanner=new Scanner(System.in);
        //scanner.next();
        //System.in:是一个标准输入流,默认就是从键盘接受数据
        //举例:使用Scanner从文件接受数据
        Reader reader=null;
        try {
            reader=new FileReader("H:\\BigData\\SZBDjava_day0805\\src\\moning\\data.txt");
            Scanner scanner1=new Scanner(reader);
            //next()方法默认结束符是空格
            // String v=scanner1.next();
            //nextLine默认读一行
            String v=scanner1.nextLine();
            list.add(new User(v));
            System.out.println(v);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        return list;
    }

    //第三种方法:
    public static List<User> getData3(){
        List<User> list=new ArrayList<>();

        //创建缓冲流对象---没有读的能力,只能提高效率,所有我们要传入一个普通流
        try(            BufferedReader bufferedReader=new BufferedReader(new FileReader("H:\\BigData\\SZBDjava_day0805\\src\\moning\\data.txt"));
        ) {
            //第一种:一次读一个字符
            //第二种:一次读多个字符
            //第三种:一次读一行---readLine()
            //使用规则:当遇到换行符,停止读取
            //返回值:就是我们当前行的数据---字符串
            //注意点:不会读取换行符
            //注意点:当数据读完时,默认返回null,我们就知道读完了。
            String data=null;
            while ((data=bufferedReader.readLine())!=null){
                list.add(new User(data));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return list;
    }

    //- 去除集合中id重复的数据,只保留重复id的第一个数据
    //这里要使用选择排序
    public static void distinst(List<User> list){
        for (int i = 0; i < list.size()-1; i++) {
            for (int j = i; j < list.size()-1; j++) {
                //如果后面的元素与前面的元素id相同,去掉
                if (list.get(i).getId()==list.get(j+1).getId()){
                    list.remove(j+1);
                    j--;
                }
            }
        }
    }
    //- 计算这些用户的平均等级、最高等级、最低等级
    public  static void cal(List<User>list){
        list.sort((o1,o2)->o1.getLevel()-o2.getLevel());

        //遍历List
        int sum=0;
        for (User user : list) {
            sum+=user.getLevel();
        }
        System.out.println("最低等级:"+list.get(0));
        System.out.println("最高等级"+list.get(list.size()-1));
        System.out.println("评价等级"+sum/list.size());
    }
    //创建模型类
    static class User{
        private String username;
        private String password;
        private int id;
        private  int level;
        public User(){};
        public User(String str){
            //对str进行切割
            //切第一刀 ,
            String[] strings =str.split(",");
            for (String pair : strings) {
                //第二刀 =
                String[] subStr=pair.split("=");
                //将值放入模型对象
                String key=subStr[0].trim();
                String value=subStr[1].trim();
                if(key.equals("username")||key.equals("yonghu")){
                    this.username=value;
                }else if(key.matches("password|mima")){
                    this.password=value;
                }else if(key.matches("id")){
                    this.id=Integer.parseInt(value);
                }else if(key.matches("level|dengji")){
                    this.level=Integer.parseInt(value);

                }
            }
        }
        public User(String username, String password, int id, int level) {
            this.username = username;
            this.password = password;
            this.id = id;
            this.level = level;
        }

        public String getUsername() {
            return username;
        }

        public void setUsername(String username) {
            this.username = username;
        }

        public String getPassword() {
            return password;
        }

        public void setPassword(String password) {
            this.password = password;
        }

        public int getId() {
            return id;
        }

        public void setId(int id) {
            this.id = id;
        }

        public int getLevel() {
            return level;
        }

        public void setLevel(int level) {
            this.level = level;
        }

        @Override
        public String toString() {
            return "User{" +
                    "username='" + username + '\'' +
                    ", password='" + password + '\'' +
                    ", id=" + id +
                    ", level=" + level +
                    '}';
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值