File的知识
Java的IO流使用了装饰器设计模式,它将IO流分成底层节点流和上层处理流,其中节点流用于和底层的物理存储节点直接关联——不同的物理节点获取节点流的方式可能存在一定的差异,但程序可以把不同的物理节点流包装成统一的处理流,从而允许程序使用统一的输入、输出代码来读取不同的物理存储节点的资源。
1、访问文件和目录
package io; import java.io.File; import java.io.IOException; public class FileTest { public static void main(String[] args) throws IOException { File f = new File(".");// 以当前路径创建File对象 System.out.println(f.getName()); // 输出一点(.) System.out.println(f.getParent()); System.out.println(f.getAbsoluteFile()); System.out.println(f.getAbsoluteFile().getParent()); File tmpFile = File.createTempFile("aaa", ".txt", f); // 当JVM退出时删除该文件 tmpFile.deleteOnExit(); File newFile = new File(System.currentTimeMillis() + ""); System.out.println("newFile对象是否存在:" + newFile.exists()); newFile.createNewFile(); //列出当前文件下的所有文件和路径 String[] fileList = f.list(); System.out.println("=============当前路径下所有文件和路径如下============="); for (String fileName : fileList) { System.out.println(fileName); } //listRoots()静态方法列出所有的磁盘根路径 File[] roots = File.listRoots(); System.out.println("=============系统所有根路径如下============"); for (File root : roots) { System.out.println(root); } } }
2、文件过滤器
在File类的list方法中可以接收一个FilenameFilter参数,通过该参数可以只列出符合条件的文件。FilenameFilter是一个函数式接口,可以使用lambda表达式创建实现该接口的对象。示例代码如下:
File f = new File("."); String[] list = f.list((dir,name)->name.endsWith(".java") || new File(name).isDirectory()); for (String name : list) { System.out.println(name); }
3、流的分类
输入流和输出流
Java的输入流主要由InputStream和Reader作为基类,输出流主要由OutputStream和Writer作为基类。它们都是抽象基类,无法创建实例。
字节流和字符流
字节流操作的数据单元是8位的字节,而字符流操作的数据单元是16位的字符。
字节流主要由InputStream和OutputStream作为基类,字符流主要由Reader和Writer作为基类。
FileInputStream示例:
package io; import java.io.FileInputStream; import java.io.IOException; public class FileInputStreamTest { public static void main(String[] args) { FileInputStream fis = null; try { fis = new FileInputStream("d:/m.txt"); byte[] bbuf = new byte[1024]; int hasRead = 0; while ((hasRead = fis.read(bbuf)) != -1) { System.out.print(new String(bbuf, 0, hasRead)); } } catch (IOException e) { e.printStackTrace(); } finally { try { fis.close(); } catch (IOException e) { e.printStackTrace(); } } } }
FileReader示例:
package io; import java.io.FileReader; import java.io.IOException; public class FileReaderTest { public static void main(String[] args) { try (FileReader fr = new FileReader("d:/m.txt")) { char[] cbuf = new char[32]; int hasRead = 0; while((hasRead = fr.read(cbuf))>0){ System.out.print(new String(cbuf,0,hasRead)); } } catch (IOException e) { e.printStackTrace(); } } }
FileOutputStream示例:
package io; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; public class FileOutputStreamTest { public static void main(String[] args) { try (FileInputStream fis = new FileInputStream("D:/m.txt"); FileOutputStream fos = new FileOutputStream("D:/newFile.txt")) { byte[] bbuf = new byte[32]; int hasRead = 0; while((hasRead = fis.read(bbuf))>0){ fos.write(bbuf,0,hasRead); } } catch (IOException e) { e.printStackTrace(); } } }
节点流和处理流
按照流的角色分为节点流和处理流。
从特点的IO设备读写数据的流称为节点流,也叫低级流。
处理流则对一个已存在的流进行连接和封装,通过封装后的流来实现数据的读写功能。处理流也被称为高级流。
PrintStream示例:
package io; import java.io.FileOutputStream; import java.io.IOException; import java.io.PrintStream; public class PrintStreamTest { public static void main(String[] args) { try(FileOutputStream fos = new FileOutputStream("d:/m.txt"); PrintStream ps = new PrintStream(fos)){ ps.println("哈哈"); ps.println(new PrintStreamTest()); } catch (IOException e) { e.printStackTrace(); } } }
4、输入输出流体系
转换流
InputStreamReader将字节输入流转换成字符输入流,OutputStreamWriter将字节输出流转换成字符输出流。
InputStreamReader示例:
package io; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; public class KeyinTest { public static void main(String[] args) { try(InputStreamReader isr = new InputStreamReader(System.in); BufferedReader br = new BufferedReader(isr)){ String line = null; while((line = br.readLine())!=null){ if("exit".equals(line)){ System.exit(1); } System.out.println(line); } } catch (IOException e) { e.printStackTrace(); } } }
5、重定向标准输入/输出
在System类里提供了如下三个重定向标准输入/输出的方法。
static void setErr(PrintStream err):重定向标准错误输出流。
static void setIn(InputStream in):重定向标准输入流。
static void setOut(PrintStream out):重定向标准输出流。
如下程序通过重定向标准输出流,将System.out的输出重定向到文件输出,而不是在屏幕上输出。
package io; import java.io.FileOutputStream; import java.io.IOException; import java.io.PrintStream; public class RedirectOut { public static void main(String[] args){ try(PrintStream ps = new PrintStream(new FileOutputStream("out.txt"))){ System.setOut(ps);//将标准输出重定向到ps输出流 System.out.println("明月几时有"); System.out.println(new RedirectOut()); }catch(IOException e){ e.printStackTrace(); } } }
下面程序重定向标准输入,从而可以将System.in重定向到指定文件,而不是键盘输入。
package io; import java.io.FileInputStream; import java.io.IOException; import java.util.Scanner; public class RedirectIn { public static void main(String[] args) { try(FileInputStream fis = new FileInputStream("d:/m.txt")){ System.setIn(fis); Scanner sc = new Scanner(System.in); //只把回车做为分隔符 sc.useDelimiter("\n"); while(sc.hasNext()){ System.out.println("键盘输入的内容是:"+sc.next()); } }catch(IOException e){ e.printStackTrace(); } } }