1.概述
IO操作主要是对文件的读写操作,java中提供了file类、以及各种流进行IO。
2.File类
2.1 构造函数
文件和目录可以通过file封装成对象
在java中一个文件就是一个对象,访问一个文件就是访问一个对象
File封装的不是一个真正的文件,仅仅是一个路径名,可以存在也可以不存在,不存在也不会报错,要通过具体的操作将路径的内容转换成具体存在的。
File(String pathname) 参数为路径名,创建file实例 File(String parent,String child) 从父路径名和子路径名创建新的file实例 File(File parent,String child) 从父抽象路径名和子路径名创建 File f1=new File("D:\\study\\java.txt"); File f2=new File("D:\\study","java.txt"); File f3=new File("D:\\study"); File f4=new File(f3,"java.txt");
2.2 常见的API
一些主要的创建文件、创建目录,得到文件下的目录名称list,判断是否是目录isDirectory等等
/*** * 测试file类型常见的API * createNewFile()创建一个文件 * mkdir()创建文件夹 * mkdirs()创建多级文件夹 * * java.txt * D:\study * D:\study\java.txt * getName()得到文件名 * getParent()得到上级目录 * getAbsolutePath()得到绝对路径 * String[] list=f2.list() list生成当前目录下的所有文件名返回一个string类型的数组 * public String[] list(FilenameFilter filter) * 还是返回当前目录下的文件,但是有选择的返回可以通过过滤器filter过滤---只接受filter指定的 */ private static void testFileApi() throws IOException { File f1=new File("D:\\study\\java.txt"); System.out.println(f1.createNewFile()); System.out.println(f1.getName()); System.out.println(f1.getParent()); System.out.println(f1.getAbsolutePath()); File f2=new File("D:\\study"); String[] list=f2.list(); for (String s : list) { System.out.println(s); } TxtFilter txtFilter=new TxtFilter(".txt"); String[] listFilter=f2.list(txtFilter); if(listFilter!=null){ System.out.println(listFilter.length); for (int i = 0; i < listFilter.length; i++) { System.out.println(listFilter[i]); // 结果为java.txt } } // File f2=new File("D:\\study\\java\\java.txt"); // System.out.println(f2.mkdir()); // File f3=new File("D:\\study\\java1\\html\\java.txt"); // System.out.println(f3.mkdirs()); }
2.3 递归遍历文件夹
//使用递归遍历文件夹及子文件夹中文件 public static void filesDirs(File file){ //File对象是文件或文件夹的路径,第一层判断路径是否为空 if(file!=null){ //第二层路径不为空,判断是文件夹还是文件 if(file.isDirectory()){ //进入这里说明为文件夹,此时需要获得当前文件夹下所有文件,包括目录 File[] files=file.listFiles();//注意:这里只能用listFiles(),不能使用list() //files下的所有内容,可能是文件夹,也可能是文件,那么需要一个个去判断是文件还是文件夹,这个判断过程就是这里封装的方法 //因此可以调用自己来判断,实现递归 for (File flies2:files) { filesDirs(flies2); } }else{ System.out.println("文件名字"+file); } }else{ System.out.println("文件不存在"); } }
3. 流
3.1 概述
文件的读写都是靠数据流进行传输,主要有字节流、字符流、还有特殊操作流;
字节流:主要是文件通过btye传输,就是一个一个字节传输(所有的文件类型都通用)
字符流:主要是文件通过字符传输,主要是文本类型的才可以通过字节传输
3.2 字节流
主要是运用字节缓冲流-----(只是提供一个缓冲区,字节的写入操作还是有字节输出流进行操作)
因为字节缓冲流快
InputStream 字节输入流的所有类的超类
OutputStream 字节输出流的所有类的超类
子类名的特点:都是以其父类名作为子类名的后缀 e.gFileOutputStream(文件输出流---写入文件)
字节缓冲流:
BufferedInputStream
创建一个内部缓冲区数组,当从中读取字节时,内部缓冲区根据需要从所包括的输入流中重新填充
BufferedOutputStream
应用程序向底层输出流写入字节,不必为写入的每个字节导致底层系统的调用
private static void copyVideo() throws IOException { BufferedOutputStream bufferedOutputStream=new BufferedOutputStream(new FileOutputStream("D:\\study\\1_1.mp4")); BufferedInputStream bufferedInputStream=new BufferedInputStream(new FileInputStream("D:\\study\\1.mp4")); byte[] bys=new byte[1024]; int len; while((len=bufferedInputStream.read(bys))!=-1){ bufferedOutputStream.write(bys,0,len); } bufferedInputStream.close(); bufferedOutputStream.close(); } private static void BufferedStreamTest() throws IOException { /*** * 写数据 */ // FileOutputStream fileOutputStream=new FileOutputStream("D:\\study\\java1.txt"); // BufferedOutputStream bufferedOutputStream=new BufferedOutputStream(fileOutputStream); // bufferedOutputStream.write("hello\r\n".getBytes()); // bufferedOutputStream.close(); // fileOutputStream.close(); /*** * 读数据 */ FileInputStream fileInputStream=new FileInputStream("D:\\study\\java1.txt"); BufferedInputStream bufferedInputStream=new BufferedInputStream(fileInputStream); int bys; while((bys=bufferedInputStream.read())!=-1){ System.out.println((char) bys); } bufferedInputStream.close(); fileInputStream.close(); } /*** * 复制图片:一次读一个字节数组byte数组的数据 * 先读再写 * @throws IOException */ private static void copyImage() throws IOException { FileInputStream fileInputStream=new FileInputStream("D:\\study\\2.jpg"); FileOutputStream fileOutputStream=new FileOutputStream("D:\\study\\2_1.jpg"); byte[] bys=new byte[1024]; int len; //将读取的数据放到bys数组中 //通过len来判断是否读取结束 while((len=fileInputStream.read(bys))!=-1){ fileOutputStream.write(bys,0,len); } fileInputStream.close(); fileOutputStream.close(); } /*** * 复制文件主要是一个一个字节读取 * 复制文件: * 1.读取文件中的内容 * 2.再写入文件 */ private static void copyFile() throws IOException { FileInputStream fileInputStream=new FileInputStream("D:\\study\\java.txt"); FileOutputStream fileOutputStream=new FileOutputStream("D:\\study\\java1.txt"); int by; while((by=fileInputStream.read())!=-1){ fileOutputStream.write(by); } fileInputStream.close(); fileOutputStream.close(); } /*** * 字节流读数据 */ private static void fileStreamReadTest() throws IOException { FileInputStream fileInputStream=new FileInputStream("D:\\study\\java.txt"); int by; while((by=fileInputStream.read())!=-1){ System.out.println(by); } fileInputStream.close(); } /*** * 字节流写数据out */ private static void fileStreamOutTest() throws IOException { //append为true表示追加写入 FileOutputStream fileOutputStream=new FileOutputStream("D:\\study\\java.txt",true); fileOutputStream.write(97); byte[] bys={97,98,99}; fileOutputStream.write(bys); fileOutputStream.close(); }
3.3 字符流
同理,也是主要用字符缓冲流
汉字存储:
GBK编码:占用2个字节
UTF-8编码:占用3个字节
如果按照字节流进行访问:一个字节就输出一个那一个汉字会出现乱码
字节流操作中文不方便,所以提供字符流
字符流=字节流+编码
*** * 字符缓冲流的读写操作 * @throws IOException */ private static void bufferedTest() throws IOException { BufferedWriter bufferedWriter=new BufferedWriter(new FileWriter("D:\\study\\java.txt")); bufferedWriter.write("中国yyds"); bufferedWriter.close(); BufferedReader bufferedReader=new BufferedReader(new FileReader("D:\\study\\java.txt")); char[] chs=new char[1024]; int len; while((len=bufferedReader.read(chs))!=-1){ System.out.println(new String(chs,0,len)); } } /**8 * 写入和读出 */ private static void writeTest() throws IOException { // OutputStreamWriter outputStreamWriter=new OutputStreamWriter(new FileOutputStream("D:\\study\\java.txt")); // outputStreamWriter.write("adn中国"); // outputStreamWriter.close(); InputStreamReader inputStreamReader=new InputStreamReader(new FileInputStream("D:\\study\\java.txt")); //一次读一个字符数据 // int ch; // while((ch=inputStreamReader.read())!=-1){ // System.out.println((char)ch); // } //一次读一个字符数组 char[] chs=new char[1024]; int ch; while((ch=inputStreamReader.read(chs))!=-1){ System.out.println(new String(chs,0,ch)); } inputStreamReader.close(); } }
4. 一些文件的操作
4.1 文件与集合
/*** * 将文件中的数据写入到集合中 */ private static void DocumentToList() throws IOException { List<String> list=new ArrayList<>(); BufferedReader bufferedReader=new BufferedReader(new FileReader("D:\\study\\java.txt")); char[] chs=new char[1024]; int len; while((len=bufferedReader.read(chs))!=-1){ // System.out.println(new String(chs,0,len)); list.add(new String(chs,0,len)); } for (String s : list) { System.out.println(s); } } /*** * 将聚合中的数据写入文件中 */ private static void listToDocument() throws IOException { List<String> list=new ArrayList<>(); for(int i=0;i<20;i++){ list.add("hello"+i); } System.out.println(list.size()); BufferedWriter bufferedWriter=new BufferedWriter(new FileWriter("D:\\study\\java.txt")); /*** * 直接写入 */ // for (String s : list) { // bufferedWriter.write(s); // bufferedWriter.newLine(); // } /*** * 4个数据为一行 */ for(int i=0;i<list.size();i++){ bufferedWriter.write(list.get(i)); bufferedWriter.write(","); if(i%4==3 && i!=0){ bufferedWriter.newLine(); } } bufferedWriter.close(); }
4.2 点名器
/*** * 点名器 * 文件中存储学生的姓名进行随机点名 * 思路: * 1.读取学生的姓名放在list中 * 2.按random随机输出list中的对象 */ private static void RandomRoll() throws IOException { List<String> list=new ArrayList<>(); BufferedReader bufferedReader=new BufferedReader(new FileReader("D:\\study\\java.txt")); String line; while((line=bufferedReader.readLine())!=null){ // System.out.println(new String(chs,0,len)); list.add(line); } Random random=new Random(); int index=random.nextInt(list.size()); System.out.println(list.get(index)); }
4.3 利用treeSet实现数据的排序输出
/*** * 利用treeSet存储数据 * treeSet可以排序 * 需求: * 学生:姓名,语文,数学,英语,按总分大输出到文件中 * 思路: * 利用treeSet存储数据进行排序之后写入文件中 */ private static void treeSetToFile() throws IOException { //1.创建treeSet对象 TreeSet<Student> studentTreeSet=new TreeSet<>(new Comparator<Student>() { @Override public int compare(Student s1, Student s2) { int num=s1.getSum()-s2.getSum(); int num2= num==0? s1.getChinese()-s2.getChinese() :num; int num3= num2==0? s1.getMath()-s2.getMath() :num2; int num4= num3==0? s1.getEnglish()-s2.getEnglish() :num3; return num4; } }); //2,输入数据 Student s1=new Student("我1",90,80,88); Student s2=new Student("我2",70,81,90); Student s3=new Student("我3",88,82,99); Student s4=new Student("我4",70,85,70); Student s5=new Student("我5",99,80,60); studentTreeSet.add(s1); studentTreeSet.add(s2); studentTreeSet.add(s3); studentTreeSet.add(s4); studentTreeSet.add(s5); for (Student student : studentTreeSet) { System.out.println(student.getName()); } BufferedWriter bufferedWriter=new BufferedWriter(new FileWriter("D:\\study\\java.txt")); for (Student student : studentTreeSet) { StringBuilder stringBuilder=new StringBuilder(); stringBuilder.append(student.getName()).append(",") .append(student.getChinese()).append(",") .append(student.getMath()).append(",") .append(student.getEnglish()).append(",") .append(student.getSum()).append(","); bufferedWriter.write(stringBuilder.toString()); bufferedWriter.newLine(); bufferedWriter.flush(); } bufferedWriter.close(); }