import java.io.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Comparator;
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
模型
字符串切割
集合
去重(比较器)
*/
public class test {
public static void main(String[] args) {
//在桌面上的这个source.txt文件拷贝到项目 file\data.txt 中(注意:方式不限,可以是移动或拷贝!)
/*
copyFile1("C:\\Users\\14249\\Desktop\\source.txt",
"E:\\java\\代码\\0606\\file\\data.txt");
copyFile2("C:\\Users\\14249\\Desktop\\source.txt",
"E:\\java\\代码\\0606\\file\\data1.txt");
copyFile3("C:\\Users\\14249\\Desktop\\source.txt",
"E:\\java\\代码\\0606\\file\\data2.txt");
*/
//读取文本中的数据,将每一行的数据封装成模型,存入 List<User> 中
List<User> list=getData1();
System.out.println(list);
System.out.println("******************************");
//去除集合中id重复的数据,只保留重复id的第一个数据
distinst(list);
System.out.println(list);
//计算这些用户的平均等级、最高等级、最低等级
calulatorLevel( list);
}
//在桌面上的这个source.txt文件拷贝到项目 file\data.txt 中(注意:方式不限,可以是移动或拷贝!)
//scr:C:\Users\14249\Desktop\source.txt
//dst:E:\千峰\java\代码\0606\file\data.txt
//方式一
public static void copyFile1(String src, String dst) {
//先创建dst路径
createFile(dst);
//将src中的数据读取到dst中
//使用最基本的字节流实现功能
//1.创建两个流
InputStream inputStream = null;
OutputStream outputStream = null;
try {
//将数据从src传到内存
inputStream = new FileInputStream(src);
//将数据从内存传到dst
/*
当用流关联路径时
如果当前的文件(data.txt),存在,会直接被覆盖
如果不存在,会自动创建一个新的data.txt
*/
outputStream = new FileOutputStream(dst);
//完成读写过程
/*
一次读一个字节--read()
一次读多个字节--read(数组),数组中临时储存的是当前读到的字节
一次读所有字节--read(数组),一次将所有的字节都放入当前的临时数组
*/
/*
read():在读取字节时每次读取的是当前指针指向的字节,读完后,会自动将指针后移一位
返回值:就是读到的字节,当读到末尾时,返回-1,证明读完了
*/
int num = 0;//用来装读到的内容
//使用一次读一个字节
/*
while ((num=inputStream.read())!=-1){
// System.out.println("num:"+(char)num);
//写--write方法
//有一个临时缓冲区,数据首先写入临时缓冲区
outputStream.write(num);
//刷新--当刷新时,会将缓冲区内容刷到data.txt文件
//outputStream.flush();
}
*/
//一次读多个字节
byte[] arr = new byte[10];
while ((num = inputStream.read(arr)) != -1) {
outputStream.write(arr, 0, num);
}
//一次读多个字节
//注意点:文件的总字节数不能太大
/*
int totalNum= inputStream.available();
//文件中的总字节数
byte[] arr=new byte[totalNum];
num=inputStream.read(arr);
outputStream.write(arr,0,num);
*/
} catch (IOException e) {
e.printStackTrace();
} finally {//必须执行的代码
//关闭
//需要先判断流是否为空--提高代码的效率
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (outputStream != null) {
try {
//在close方法中,有关闭流的功能还有flush的功能
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
//方式二:使用renameto方法,只能移动,移动完成,源文件消失
//注意:要保证目标目录中没有新的文件名
public static void copyFile2(String src, String dst) {
createFile(dst);
//创建src与dst相关的File对象
File srcFile=new File(src);
File dstFile=new File(dst);
//移动
srcFile.renameTo(dstFile);
}
//方式三:使用Files(NIO中)里的方法,进行拷贝
/*
在NIO中提供的类
Path
Paths
*/
public static void copyFile3(String src, String dst){
createFile1(dst);
/**
* src:Path
* dst:Path
*/
try {
Files.copy(Paths.get(src),Paths.get(dst));
} catch (IOException e) {
e.printStackTrace();
}
}
//创建File目录的方法
//使用Files提供的方法
public static void createFile1(String dst) {
/*
1.createNewFile()--只能创建文件
2.mkdir()--只能创建目录,但是只有单层
3.mkdirs()--只能创建目录,可以单层可以多层
*/
//先创建file目录
//1.截取最后一个\
int index = dst.lastIndexOf("\\");
String str = dst.substring(0, index);//str=E:\java\代码\0606\file
//参数是一个Path的对象
try {
Files.createDirectory(Paths.get(str));
} catch (IOException e) {
e.printStackTrace();
}
}
//使用File提供的方法
public static void createFile(String dst) {
/*
1.createNewFile()--只能创建文件
2.mkdir()--只能创建目录,但是只有单层
3.mkdirs()--只能创建目录,可以单层可以多层
*/
//先创建file目录
//1.截取最后一个\
int index = dst.lastIndexOf("\\");
String str = dst.substring(0, index);//str=E:\java\代码\0606\file
//使用File类创建File目录
File file = new File(str);
file.mkdir();
}
//读取文本中的数据,将每一行的数据封装成模型,存入 List<User> 中
//第一种方法:通过字符流实现
public static List<User> getData1(){
List<User> list=new ArrayList<>();
//创建字符读入流,读取数据入内存
Reader reader=null;
try {
//使用的文件的绝对路径
//reader = new FileReader("E:\\java\\代码\\0606\\file\\data.txt");
//使用相对路径,默认可以直接识别当前工程的路径
reader = new FileReader("0606\\file\\data.txt");
//开始读取
//写一个可变字符串用来装临时的一行
StringBuffer stringBuffer=new StringBuffer();
//使用一次读一个字符
int num=0;
while ((num=reader.read())!=-1){
if (num=='\n'){
//说明当前读完了
//将数据切割放入User
list.add(new User(stringBuffer.toString()));
//清除工作
stringBuffer.delete(0,stringBuffer.length());
}else{
//继续读
stringBuffer.append((char)num);
}
}
//将最后一行数据放入list
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对象
//默认从控制台接受数据
//System.in 标准输入流
//Scanner scanner=new Scanner(System.in);
//创建从文件接收数据的Scanner
/*
try {
Scanner scanner1=new Scanner(new FileInputStream("0606\\file\\data.txt"));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
*/
try{
Scanner scanner2 = new Scanner(new File("0606\\file\\data.txt"));
//一行读一行
while(scanner2.hasNextLine()){
String str=scanner2.nextLine();
list.add(new User(str));
}
scanner2.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return list;
}
//第三种方式:通过缓冲流
public static List<User> getData3(){
/*
*/
List<User> list =new ArrayList<>();
//读
try {
BufferedReader bufferedReader= new BufferedReader(new FileReader("0606\\file\\data.txt"));
//一次读一个字符
//一次读多个字符
//一次读一行
/*
*/
String data=null;
while ((data=bufferedReader.readLine())!=null){
list.add(new User(data));
}
bufferedReader.close();
} catch (IOException e) {
e.printStackTrace();
}
return list;
}
//对于模型的类名以及属性的名字都要尽量做到见名知义
static class User{
private String username;
private String password;
private int id;
private int 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;
}
public User(){}
public User(String str){
//切割
//第一刀:,
String[] strings=str.split(",");
for (String string : strings) {
//第二刀:=
String [] pair=string.split("=");
//取出空格
String key=pair[0].trim();
String value=pair[1].trim();
//正则表达式
if (key.matches("username|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;
}
@Override
public String toString() {
return "User{" +
"username='" + username + '\'' +
", password='" + password + '\'' +
", id=" + id +
", level=" + level +
'}';
}
}
//去除集合中id重复的数据,只保留重复id的第一个数据
public static void distinst(List<User> list){
for (int i = 0; i < list.size()-1; i++) {
for (int j = 0; j < list.size()-i-1; j++) {
//如果后面的元素与前面的元素id相同,删除
if (list.get(j).getId()==list.get(j+1).getId()){
list.remove(j+1);
j--;
}
}
}
}
//计算这些用户的平均等级、最高等级、最低等级
//创建比较器-按照等级比较
public static void calulatorLevel(List<User> list){
list.sort(new Comparator<User>() {
@Override
public int compare(User o1, User o2) {
return o1.getLevel()-o2.getLevel();
}
});
int sum=0;
for(User user:list){
sum+=user.getLevel();
}
System.out.println("平均等级:"+sum/list.size());
System.out.println("最大等级:"+list.get(list.size()-1).getLevel());
System.out.println("最大等级:"+list.get(0).getLevel());
}
}