注意点:
- IO流是对一个文件进行读写的,不是一个文件夹!在使用IO流的时候,不要建立与一个文件夹的连接。
- IO流的四大父类,都是抽象类,都不能进行实例化对象。因此,借助了他们的子类来实现实例化,从而实现对数据的读写操作。
- 一旦流对象实例化完成, 将会建立一个程序与文件之间的连接,这个连接会持有这个而文件,如果这个连接不断,此时这个文件就是一个被使用的状态,此时将会无法对这个文件进行其他的操作,例如删除。
- 一个流对象在使用完成之后,切记切记!一定要进行流对象的关闭!
另外说一下 绝对路径与相对路径的区别,以后会用到
- 绝对路径: 其实就是从磁盘的根目录开始的,一层层往下查找,直到找到这个文件。例如F:\ideaProgram\mypath\hello.java
- 相对路径:其实找到一个参照物,是相对于参照物的路径。例如:src\\iotest\\hello.txt
IO流的案例:
已知文件 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 中
- 去除集合中id重复的数据,只保留重复id的第一个数据
- 计算这些用户的平均等级、最高等级、最低等级 。
示例代码如下:
package morning; 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; /* 此题知识点 : 目前拷贝方法的三个方法 1、字节输入输出流(字符输入输出流也可以) 2、renameto 直接移动 3、 利用NIO2上的 Files的静态方法 copy 将文件中的数据 读取到模型中的三个方法 1、 利用字符流实现(或者字节流实现也可以) 2、通过缓冲流实现 */ public class Demo3 { public static void main(String[] args) { // copyFile1("C:\\Users\\等待\\Desktop\\source.txt", "F:\\ideaProgram\\BigData2021ProThirdDay\\JavaDay3_27\\file\\data.txt"); copyFile2("C:\\Users\\等待\\Desktop\\source.txt", "F:\\ideaProgram\\BigData2021ProThirdDay\\JavaDay3_27\\file\\data.txt"); } //创建file目录 public static void createDocument(String dst){ //createNewFile 只能创建文件 //mkdir 是创建一层目录 只能创建目录 //mkdirs 是创建多层目录,包括一层 只能创建目录 //最后一个、的下标 int index = dst.lastIndexOf("\\"); String sub = dst.substring(0, index); System.out.println(sub); //使用file创建file目录 File file = new File(sub); if (!file.exists()){ file.mkdir(); } } //拷贝方法一:将source文件拷贝到项目的file的data中 public static void copyFile1(String src, String dst) { //先创建file文件夹 createDocument(dst); //创建字节输入流对象并关联文件 InputStream inputStream = null; OutputStream outputStream = null; int num = 0; try { inputStream = new FileInputStream(src); outputStream = new FileOutputStream(dst); while ((num = inputStream.read())!=-1){ outputStream.write(num); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }finally { //因为inputString流对象不一定存在,所以为了执行效率,应该先判空 在关闭 if (inputStream != null){ try { inputStream.close(); } catch (IOException e) { e.printStackTrace(); } } if (outputStream != null){ try { outputStream.close(); } catch (IOException e) { e.printStackTrace(); } } } } //拷贝方法二:利用renameTo //只能移动,移动完成,源文件小消失 public static void copyFile2(String src,String dst){ createDocument(dst); File file1 = new File(src); File file2 = new File(dst); file1.renameTo(file2); } //拷贝方法三,NIO2上的Files里面的方法 public static void copyFile3(String src,String dst){ createDocument(dst); int index = dst.lastIndexOf("\\"); String sub = dst.substring(0, index); System.out.println(sub); //使用file创建file目录 try { Files.createDirectory(Paths.get(sub)); Files.copy(Paths.get(src), Paths.get(dst)); } catch (IOException e) { e.printStackTrace(); } } //2.将内容读取到模型中 //第一种方法:字符流实现 public static List<User1> getData1() throws IOException { List<User1> list = new ArrayList<>(); //创建字符读入流,将数据读入内存 //可以使用相对路径,默认路径是当前工程 Reader reader = null; try { reader = new FileReader("JavaDay3_27\\file\\data.txt"); //用来临时装一行的数据 StringBuffer stringBuffer = new StringBuffer(); //使用一次读取一个字符的方法 int num = 0; while ((num = reader.read()) != -1) { //System.out.println(num); if (num == '\n'){ list.add(new User1(stringBuffer.toString())); System.out.println(stringBuffer.toString()); stringBuffer.delete(0,stringBuffer.length()-1); }else { stringBuffer.append((char) num); } } //将最后一行数据放入list list.add(new User1(stringBuffer.toString())); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } reader.close(); return list; } //第二种方法:通过缓冲流实现 public static List<User1> getData2() throws IOException { /* 缓冲流:缓冲区,可以提高代码读写的效率,但是本身不能读或者写,辅助流工作的. 分类: 字符缓冲流: 字符读入缓冲流--BufferedReader 字符写出缓冲流--BufferedWriter 字节缓冲流: 字节输入缓冲流--BufferedInputStream 字节输出缓冲流--BufferedOutputStream 注意:只有字符缓冲流才有一次读一行的功能,字节缓冲流没有. */ List<User1> list = new ArrayList<>(); //读 Reader reader = new FileReader("JavaDay3_27\\file\\data.txt"); //将reader通过构造方法指给缓冲流 BufferedReader bufferedReader = new BufferedReader(reader); //一次读一个字符 //bufferedReader.read(); //一次读多个字符 //bufferedReader.read(new char[3]); //一次读一行 /* readLine()默认以换行符为一行的结束 注意:readLine读不到换行符 如果所有内容都读完,这个方法会返回null */ String line = null; while ((line = bufferedReader.readLine()) != null){ list.add(new User1(line)); } bufferedReader.close(); return list; } //第二种方法:通过Scanner public static List<User1> getData3() throws FileNotFoundException { List<User1> list = new ArrayList<>(); //System.in 这是一个标准字节输入流,默认从控制台接收数据 //Scanner scanner = new Scanner(new FileInputStream("Day3_27\\file\\data.txt")); Scanner scanner = new Scanner(new File("JavaDay3_27\\file\\data.txt")); //一次读取一行 while (scanner.hasNextLine()){ String line1 = scanner.nextLine(); boolean add = list.add(new User1(line1)); } scanner.close(); return list; } //3.去除集合中id重复的数据,只保留重复id的第一个数据 public static void distinct(List<User1> list){ for (int i = 0; i < list.size()-1; i++) { for (int j = 0; j < list.size()-1-i; j++) { if (list.get(i).getId() == list.get(j+1).getId()){ list.remove(j+1); j--; } } } } //4.计算这些用户的平均等级、最高等级、最低等级 //创建比较器对象,用于比较等级 static class ComWithLevel implements Comparator<User1> { @Override public int compare(User1 o1, User1 o2) { return o1.getLevel()-o2.getLevel(); } } public static void calculatorLevel(List<User1> list){ list.sort(new ComWithLevel()); int sum = 0; for (User1 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()); } } class User1 { private String username; private String password; private int id; private int level; public User1() { } public User1(String line) { String[] strs = line.split(","); for (String str : strs) { String[] pair = str.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("level|dengji")){ this.level = Integer.parseInt(value); }else if (key.matches("id")){ this.id = Integer.parseInt(value); } } } @Override public String toString() { return "User1{" + "username='" + username + '\'' + ", password='" + password + '\'' + ", id=" + id + ", 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; } public User1(String username, String password, int id, int level) { this.username = username; this.password = password; this.id = id; this.level = level; } }