1.File类
1.1目录及路径分隔符
package cn.jxufe.java.chapter09.demo01; import java.io.File; public class Test01FileSeparator { public static void main(String[] args) { // TODO Auto-generated method stub // File类静态成员变量 // 与系统有关的路径分隔符 String separator = File.pathSeparator; System.out.println(separator);// 是一个分号,目录的分割 Linux : // 与系统有关的默认名称分隔符 separator = File.separator; System.out.println(separator);// 向右 目录名称分割 Linux / } }
1.2三种构造方法
package cn.jxufe.java.chapter09.demo01; import java.io.File; public class Test02Constructor { public static void main(String[] args) { // TODO Auto-generated method stub function(); System.out.println(); function_1(); System.out.println(); function_2(); } /* * File(File parent,String child) * 传递路径,传递File类型父路径,字符串子路径 * 好处: 父路径是File类型,父路径可以直接调用File类方法 */ public static void function_2() { File parent = new File("d:"); File file = new File(parent, "eclipse"); System.out.println(file); } /* * File(String parent,String child) * 传递路径,传递字符串父路径,字符串子路径 * 好处: 单独操作父路径和子路径 */ public static void function_1() { File file = new File("d:", "eclipse"); System.out.println(file); } /* * File(String pathname) * 传递路径名: 可以写到文件夹,可以写到一个文件 * c:\abc c:\abc\Demo.java * 将路径封装File类型对象 */ public static void function() { File file = new File("d:\eclipse"); System.out.println(file); } }
1.3创建、删除文件和文件夹
package cn.jxufe.java.chapter09.demo01; import java.io.File; import java.io.IOException; public class Test03DeleteAndCreate { public static void main(String[] args) throws IOException { // TODO Auto-generated method stub function(); function_1(); function_2(); } /* * File类的删除功能 * boolean delete() * 删除的文件或者是文件夹,在File构造方法中给出 * 删除成功返回true,删除失败返回false * 删除方法,不走回收站,直接从硬盘中删除 * 删除有风险,运行需谨慎 */ public static void function_2() { File file = new File("d:\a.txt"); boolean b = file.delete(); System.out.println(b); } /* * File创建文件夹功能 * boolean mkdirs() 创建多层文件夹,也可以创建单层文件夹(推荐使用) * boolean mkdir() 只能创建单层文件夹 * 创建的路径也在File构造方法中给出 * 文件夹已经存在了,不在创建 */ public static void function_1() { File file = new File("d:\abc"); boolean b = file.mkdirs(); System.out.println(b); } /* * File创建文件的功能 * boolean createNewFile() * 创建的文件路径和文件名,在File构造方法中给出 * 文件已经存在了,不在创建 */ public static void function() throws IOException { File file = new File("d:\a.txt"); boolean b = file.createNewFile(); System.out.println(b); } }
1.4获取功能
package cn.jxufe.java.chapter09.demo01; import java.io.File; /* * File类的获取功能 */ public class Test04Get { public static void main(String[] args) { // TODO Auto-generated method stub function(); function_1(); function_2(); function_3(); } /* * File类的获取功能 * String getParent() 返回String对象 * File getParentFile()返回File对象 * 获取父路径 */ public static void function_3() { File file = new File("d:\eclipse\eclipse.exe"); File parent = file.getParentFile(); System.out.println(parent); } /* * File类获取功能 * String getAbsolutePath() 返回String对象 * File getAbsoluteFile() 返回File对象 * 获取绝对路径 * eclipse环境中,写的是一个相对路径,绝对位置工程根目录 */ public static void function_2() { File file = new File("src"); File absolute = file.getAbsoluteFile(); System.out.println(absolute); } /* * File类获取功能 * long length() * 返回路径中表示的文件的字节数 */ public static void function_1() { File file = new File("d:\eclipse\eclipse.exe"); long length = file.length(); System.out.println(length); } /* * File类的获取功能 * String getName() * 返回路径中表示的文件或者文件夹名 * 获取路径中的最后部分的名字 */ public static void function() { File file = new File("d:\eclipse\eclipse.exe"); String name = file.getName(); System.out.println(name); /*String path = file.getPath(); System.out.println(path);*/ // System.out.println(file); } }
1.5判断功能
package cn.jxufe.java.chapter09.demo01; import java.io.File; public class Test05JudgingFunction { public static void main(String[] args) { // TODO Auto-generated method stub function(); function_1(); } /* * File判断功能 * boolean isDirectory() * 判断File构造方法中封装的路径是不是文件夹 * 如果是文件夹,返回true,不是文件返回false * * boolean isFile() * 判断File构造方法中封装的路径是不是文件 */ public static void function_1() { File file = new File("d:\eclipse\eclipse.exe"); if (file.exists()) { boolean b = file.isDirectory(); System.out.println(b); } } /* * File判断功能 * boolean exists() * 判断File构造方法中封装路径是否存在 * 存在返回true,不存在返回false */ public static void function() { File file = new File("src"); // 如果用相对路径,默认的路径为当前项目的工作路径 boolean b = file.exists(); System.out.println(b); } }
1.6list获取功能
package cn.jxufe.java.chapter09.demo01; import java.io.File; public class Test06List { public static void main(String[] args) { // TODO Auto-generated method stub function(); System.out.println(); function_1(); System.out.println(); function_2(); } public static void function_2() { // 获取系统中的所有根目录 File[] fileArr = File.listRoots(); for (File f : fileArr) { System.out.print(f + " "); } System.out.println(); } /* * File类的获取功能 * File[] listFiles() * 获取到,File构造方法中封装的路径中的文件和文件夹名 (遍历一个目录) * 返回的是目录或者文件的全路径 */ public static void function_1() { File file = new File("d:\eclipse"); File[] fileArr = file.listFiles(); for (File f : fileArr) { System.out.print(f + " "); } System.out.println(); } /* * File类的获取功能 * String[] list() * 获取到,File构造方法中封装的路径中的文件和文件夹名 (遍历一个目录) * 返回只有名字 */ public static void function() { File file = new File("c:"); String[] strArr = file.list(); System.out.println(strArr.length); for (String str : strArr) { System.out.print(str+" "); } System.out.println(); } }
1.7文件过滤器
package cn.jxufe.java.chapter09.demo01; import java.io.File; import java.io.FileFilter; public class Test07Filter { public static void main(String[] args) { // TODO Auto-generated method stub File file = new File("c:\demo"); File[] fileArr = file.listFiles(new MyFilter()); for (File f : fileArr) { System.out.println(f); } } } class MyFilter implements FileFilter { public boolean accept(File pathname) { /* * pathname 接受到的也是文件的全路径 * c:\demo\1.txt * 对路径进行判断,如果是java文件,返回true,不是java文件,返回false * 文件的后缀结尾是.java */ // String name = pathname.getName(); return pathname.getName().endsWith(".java"); } }
1.8递归遍历所有文件
package cn.jxufe.java.chapter09.demo01; import java.io.File; public class Test08VisitAllDirectories { public static void main(String[] args) { // TODO Auto-generated method stub File dir = new File("c:\demo"); getAllDir(dir); } /* * 定义方法,实现目录的全遍历 */ public static void getAllDir(File dir) { System.out.println(dir); // 调用方法listFiles()对目录,dir进行遍历 File[] fileArr = dir.listFiles(); for (File f : fileArr) { // 判断变量f表示的路径是不是文件夹 if (f.isDirectory()) { // 是一个目录,就要去遍历这个目录 // 本方法,getAllDir,就是给个目录去遍历 // 继续调用getAllDir,传递他目录 getAllDir(f); } else { System.out.println(f); } } } }
1.9搜索指定目录中的.java文件(含子目录)
需求:打印指定目录即所有子目录中的.java文件的文件路径
要求:编写一个方法用来打印指定目录中的.java文件路径,并进行方法的调用
若指定的目录有子目录,那么把子目录中的.java文件路径也打印出来
步骤:
1. 指定要打印的目录File对象
2. 调用getFileAll()方法,传入要打印的目录File对象
2.1 通过FilenameFilter过滤器获取指定目录中的所有.java类型的File对象
2.2 遍历得到每一个File对象
2.3 判断当前File 对象是否是目录
判断结果为true,说明为目录,通过递归,再次调用步骤2的getFileAll()方法
判断结果为false,说明是文件,打印文件的路径
package cn.jxufe.java.chapter09.demo01; import java.io.File; import java.io.FileFilter; /* * 遍历目录,获取目录下的所有.java文件 * 遍历多级目录,方法递归实现 * 遍历的过程中,使用过滤器 */ public class Test09Filter { public static void main(String[] args) { // TODO Auto-generated method stub getAllJava(new File("c:\demo")); } /* * 定义方法,实现遍历指定目录 * 获取目录中所有的.java文件 */ public static void getAllJava(File dir) { // 调用File对象方法listFiles()获取,加入过滤器 File[] fileArr = dir.listFiles(new MyJavaFilter()); for (File f : fileArr) { // 对f路径,判断是不是文件夹 if (f.isDirectory()) { // 递归进入文件夹遍历 getAllJava(f); } else { System.out.println(f); } } } } class MyJavaFilter implements FileFilter { public boolean accept(File pathname) { // 判断获取的是目录,直接返回true if (pathname.isDirectory()) return true; return pathname.getName().toLowerCase().endsWith(".java");// 包括或缀名为大写的 } }
2.字节流
2.1OutPutStream
/* * 字节输出流 * java.io.OutputStream 所有字节输出流的超类 * 作用: 从Java程序,写出文件 * 字节: 这样流每次只操作文件中的1个字节 * 写任意文件 * * 方法都是写文入的方法 * write(int b) 写入1个字节 * write(byte[] b) 写入字节数组 * write(byte[] b,int,int)写入字节数组,int 开始写入的索引, int 写几个 * close() 方法,关闭流对象,释放与次流相关的资源 * * 流对象,操作文件的时候, 自己不做,依赖操作系统 */
2.2FileOutputStream
package cn.jxufe.java.chapter09.demo02; import java.io.FileOutputStream; import java.io.IOException; /* * FileOutputStream * 写入数据文件,学习父类方法,使用子类对象 * * 子类中的构造方法: 作用:绑定输出的输出目的 * 参数: * File 封装文件 * String 字符串的文件名 * * 流对象使用步骤 * 1. 创建流子类的对象,绑定数据目的 * 2. 调用流对象的方法write写 * 3. close释放资源 * * 流对象的构造方法,可以创建文件,如果文件存在,直接覆盖 */ public class Test01FileOutputStream { public static void main(String[] args) throws IOException { // TODO Auto-generated method stub FileOutputStream fos = new FileOutputStream("d:\aa.txt"); // aa.txt文件中显示的不是100,而是d,ASCII表 // 流对象的方法write写数据 // 写1个字节 fos.write(97); // 写字节数组 byte[] bytes = { 65, 66, 67, 68 }; fos.write(bytes); // 写字节数组的一部分,开始索引,写几个 fos.write(bytes, 1, 2); // 写入字节数组的简便方式 // 写字符串 fos.write("hello".getBytes()); // 关闭资源 fos.close(); } }
2.3文件的续写和换行问题
package cn.jxufe.java.chapter09.demo02; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; /* * FileOutputStream 文件的续写和换行问题 * 续写: FileOutputStream构造方法, 的第二个参数中,加入true * 在文件中,写入换行,符号换行 * 可以写在上一行的末尾, 也可以写在下一行的开头 */ public class Test02FileOutputStream { public static void main(String[] args) throws IOException { // TODO Auto-generated method stub File file = new File("d:\b.txt"); FileOutputStream fos = new FileOutputStream(file, true);// 默认为false fos.write("hello ".getBytes()); fos.write("world".getBytes()); fos.close(); } }
2.4IO中的异常处理
package cn.jxufe.java.chapter09.demo02; import java.io.FileOutputStream; import java.io.IOException; /* * IO流的异常处理 * try catch finally * * 细节: * 1. 保证流对象变量,作用域足够 * 2. catch里面,怎么处理异常 * 输出异常的信息,目的看到哪里出现了问题 * 停下程序,从新尝试 * 3. 如果流对象建立失败了,需要关闭资源吗 * new 对象的时候,失败了,没有占用系统资源 * 释放资源的时候,对流对象判断null * 变量不是null,对象建立成功,需要关闭资源 */ public class Test03IOException { public static void main(String[] args) { // try 外面声明变量,try 里面建立对象 FileOutputStream fos = null; try { fos = new FileOutputStream("d:\a.txt"); fos.write(100); } catch (IOException ex) { System.out.println(ex); throw new RuntimeException("文件写入失败,重试"); } finally { try { if (fos != null) fos.close(); } catch (IOException ex) { throw new RuntimeException("关闭资源失败"); } } } }
2.5InPutStream
/* * 字节输入流 * java.io.InputStream 所有字节输入流的超类 * 作用: 读取任意文件,每次只读取1个字节 * 读取的方法 read * int read() 读取1个字节 * int read(byte[] b) 读取一定量的字节,存储到数组中 */
2.6FileInputStream
、
package cn.jxufe.java.chapter09.demo02; import java.io.FileInputStream; import java.io.IOException; /* * FileInputStream读取文件 * * 构造方法: 为这个流对象绑定数据源 * * 参数: * File 类型对象 * String 对象 * 输入流读取文件的步骤 * 1. 创建字节输入流的子类对象 * 2. 调用读取方法read读取 * 3. 关闭资源 * * read()方法, * read()执行一次,就会自动读取下一个字节 * 返回值,返回的是读取到的字节, 读取到结尾返回-1 */ public class Test04FileInputStream { public static void main(String[] args) throws IOException { // TODO Auto-generated method stub FileInputStream fis = new FileInputStream("d:\a.txt"); // 读取一个字节,调用方法read 返回int // 使用循环方式,读取文件, 循环结束的条件 read()方法返回-1 int len = 0;// 接受read方法的返回值 while ((len = fis.read()) != -1) { System.out.print((char) len); } // 关闭资源 fis.close(); /* * int i = fis.read(); System.out.println(i); i = fis.read(); System.out.println(i); i = fis.read(); System.out.println(i); i = fis.read(); System.out.println(i); */ } }
package cn.jxufe.java.chapter09.demo02; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; /* * FileInputStream读取文件 * 读取方法 int read(byte[] b) 读取字节数组 * 数组作用: 缓冲的作用, 提高效率 * read返回的int,表示什么含义 读取到多少个有效的字节数 */ public class Test05FileInputStream { public static void main(String[] args) throws IOException { // TODO Auto-generated method stub FileInputStream fis = new FileInputStream("d:\a.txt"); // 创建字节数组 byte[] b = new byte[1024]; int len = 0; while ((len = fis.read(b)) != -1) { System.out.print(new String(b, 0, len));// 每次取的字符数组个长度,必须借用len来判断,不然可能会有重复 } fis.close(); } } /* * int len = fis.read(b); System.out.println(new String(b));//ab System.out.println(len);//2 len = fis.read(b); System.out.println(new String(b));//cd System.out.println(len);//2 len = fis.read(b); System.out.println(new String(b));//ed System.out.println(len);//1 len = fis.read(b); System.out.println(new String(b));//ed System.out.println(len);//-1 */
2.7字节流复制文件
package cn.jxufe.java.chapter09.demo02; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; /* * 将数据源 d:\a.txt * 复制到 c:\a.txt 数据目的 * 字节输入流,绑定数据源 * 字节输出流,绑定数据目的 * * 输入,读取1个字节 * 输出,写1个字节 */ public class Test06Copy { public static void main(String[] args) { // TODO Auto-generated method stub // 定义两个流的对象变量 FileInputStream fis = null; FileOutputStream fos = null; try { // 建立两个流的对象,绑定数据源和数据目的 fis = new FileInputStream("d:\a.txt"); fos = new FileOutputStream("e:\a.txt"); // 字节输入流,读取1个字节,输出流写1个字节 int len = 0; while ((len = fis.read()) != -1) { fos.write(len); } } catch (IOException ex) { System.out.println(ex); throw new RuntimeException("文件复制失败"); } finally { try { if (fos != null) fos.close(); } catch (IOException ex) { throw new RuntimeException("释放资源失败"); } finally { try { if (fis != null) fis.close(); } catch (IOException ex) { throw new RuntimeException("释放资源失败"); } } } } }
package cn.jxufe.java.chapter09.demo02; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; /* * 字节流复制文件 * 采用数组缓冲提高效率 * 字节数组 * FileInputStream 读取字节数组 * FileOutputStream 写字节数组 */ public class Test07CopyWithArray { public static void main(String[] args) { // TODO Auto-generated method stub long s = System.currentTimeMillis(); FileInputStream fis = null; FileOutputStream fos = null; try { fis = new FileInputStream("c:\t.zip"); fos = new FileOutputStream("d:\t.zip"); // 定义字节数组,缓冲 byte[] bytes = new byte[1024 * 10]; // 读取数组,写入数组 int len = 0; while ((len = fis.read(bytes)) != -1) { fos.write(bytes, 0, len); } } catch (IOException ex) { System.out.println(ex); throw new RuntimeException("文件复制失败"); } finally { try { if (fos != null) fos.close(); } catch (IOException ex) { throw new RuntimeException("释放资源失败"); } finally { try { if (fis != null) fis.close(); } catch (IOException ex) { throw new RuntimeException("释放资源失败"); } } } long e = System.currentTimeMillis(); System.out.println(e - s); } }
2.8字符输出流FileWriter
局限性:只能写文本文件
package cn.jxufe.java.chapter09.demo02; import java.io.FileWriter; import java.io.IOException; /* * 字符输出流 * java.io.Writer 所有字符输出流的超类 * 写文件,写文本文件 * * 写的方法 write * write(int c) 写1个字符 * write(char[] c)写字符数组 * write(char[] c,int,int)字符数组一部分,开始索引,写几个 * write(String s) 写入字符串 * * Writer类的子类对象 FileWriter * * 构造方法: 写入的数据目的 * File 类型对象 * String 文件名 * * 字符输出流写数据的时候,必须要运行一个功能,刷新功能 * flush() */ public class Test08FileWriter { public static void main(String[] args) throws IOException { // TODO Auto-generated method stub FileWriter fw = new FileWriter("d:\1.txt"); // 写1个字符 fw.write(100); fw.flush(); // 写1个字符数组 char[] c = { 'a', 'b', 'c', 'd', 'e' }; fw.write(c); fw.flush(); // 写字符数组一部分 fw.write(c, 2, 2); fw.flush(); // 写如字符串 fw.write("hello"); fw.flush(); fw.close(); } }
2.9字符输入流FileReader
局限性:只能读取文本文件
package cn.jxufe.java.chapter09.demo02; import java.io.FileReader; import java.io.IOException; /* * 字符输入流读取文本文件,所有字符输入流的超类 * java.io.Reader * 专门读取文本文件 * * 读取的方法 : read() * int read() 读取1个字符 * int read(char[] c) 读取字符数组 * * Reader类是抽象类,找到子类对象 FileReader * * 构造方法: 绑定数据源 * 参数: * File 类型对象 * String文件名 */ public class Test09FileReader { public static void main(String[] args) throws IOException { // TODO Auto-generated method stub FileReader fr = new FileReader("d:\1.txt"); /*int len = 0 ; while((len = fr.read())!=-1){ System.out.print((char)len); }*/ char[] ch = new char[1024]; int len = 0; while ((len = fr.read(ch)) != -1) { System.out.print(new String(ch, 0, len)); } fr.close(); } }
2.10字符流复制文件
package cn.jxufe.java.chapter09.demo02; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; /* * 字符流复制文本文件,必须文本文件 * 字符流查询本机默认的编码表,简体中文GBK * FileReader读取数据源 * FileWriter写入到数据目的 */ public class Test10Copy { public static void main(String[] args) { // TODO Auto-generated method stub FileReader fr = null; FileWriter fw = null; try { fr = new FileReader("d:\1.txt"); fw = new FileWriter("e:\1.txt"); char[] cbuf = new char[1024]; int len = 0; while ((len = fr.read(cbuf)) != -1) { fw.write(cbuf, 0, len); fw.flush(); } } catch (IOException ex) { System.out.println(ex); throw new RuntimeException("复制失败"); } finally { try { if (fw != null) fw.close(); } catch (IOException ex) { throw new RuntimeException("释放资源失败"); } finally { try { if (fr != null) fr.close(); } catch (IOException ex) { throw new RuntimeException("释放资源失败"); } } } } }
3.转换流
3.1OutputStreamWriter类
查阅OutputStreamWriter的API介绍,OutputStreamWriter 是字符流通向字节流的桥梁:可使用指定的字符编码表,将要写入流中的字符编码成字节。它的作用的就是,将字符串按照指定的编码表转成字节,在使用字节流将这些字节写出去。
package cn.jxufe.java.chapter09.demo03; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; /* * 转换流 * java.io.OutputStreamWriter 继承Writer类 * 就是一个字符输出流,写文本文件 * write()字符,字符数组,字符串 * * 字符通向字节的桥梁,将字符流转字节流 * * OutputStreamWriter 使用方式 * 构造方法: * OutputStreamWriter(OuputStream out)接收所有的字节输出流 * 但是: 字节输出流: FileOutputStream * * OutputStreamWriter(OutputStream out, String charsetName) * String charsetName 传递编码表名字 GBK UTF-8 * * OutputStreamWriter 有个子类, FileWriter */ public class Test01OutputStreamWriter { public static void main(String[] args) throws IOException { // TODO Auto-generated method stub writeGBK(); writeUTF(); } /* * 转换流对象OutputStreamWriter写文本 * 采用UTF-8编码表写入 */ public static void writeUTF() throws IOException { FileOutputStream fos = new FileOutputStream("d:\utf.txt"); OutputStreamWriter osw = new OutputStreamWriter(fos, "utf-8");// 编码方式不区分大小写 osw.write("你好我好大家好"); osw.close(); } /* * 转换流对象 OutputStreamWriter写文本 * 文本采用GBK的形式写入 */ public static void writeGBK() throws IOException { FileOutputStream fos = new FileOutputStream("d:\gbk.txt"); OutputStreamWriter osw = new OutputStreamWriter(fos);// 默认为gbk osw.write("你好我好大家好"); osw.close(); } }
3.2InputStreamReader类
查阅InputStreamReader的API介绍,InputStreamReader 是字节流通向字符流的桥梁:它使用指定的字符编码表读取字节并将其解码为字符。它使用的字符集可以由名称指定或显式给定,或者可以接受平台默认的字符集。
package cn.jxufe.java.chapter09.demo03; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStreamReader; /* * 转换流 * java.io.InputStreamReader 继承 Reader * 字符输入流,读取文本文件 * * 字节流向字符的敲了,将字节流转字符流 * * 读取的方法: * read() 读取1个字符,读取字符数组 * * 技巧: OuputStreamWriter写了文件 * InputStreamReader读取文件 * * OuputStreamWriter(OuputStream out)所有字节输出流 * InputStreamReader(InputStream in) 接收所有的字节输入流 * 可以传递的字节输入流: FileInputStream * InputStreamReader(InputStream in,String charsetName) 传递编码表的名字 */ public class Test02InputStreamReader { public static void main(String[] args) throws IOException { readGBK(); readUTF(); } /* * 转换流,InputSteamReader读取文本 * 采用UTF-8编码表,读取文件utf */ public static void readUTF() throws IOException { FileInputStream fis = new FileInputStream("d:\utf.txt"); InputStreamReader isr = new InputStreamReader(fis, "utf-8"); char[] ch = new char[1024]; int len = isr.read(ch); System.out.println(new String(ch, 0, len)); } /* * 转换流,InputSteamReader读取文本 * 采用系统默认编码表,读取GBK文件 */ public static void readGBK() throws IOException { FileInputStream fis = new FileInputStream("d:\gbk.txt"); InputStreamReader isr = new InputStreamReader(fis); char[] ch = new char[1024]; int len = isr.read(ch); System.out.println(new String(ch, 0, len)); } }
3.3转换流和子类区别
发现有如下继承关系:
OutputStreamWriter:
|--FileWriter:
InputStreamReader:
|--FileReader;
父类和子类的功能有什么区别呢?
OutputStreamWriter和InputStreamReader是字符和字节的桥梁:也可以称之为字符转换流。字符转换流原理:字节流+编码表。
FileWriter和FileReader:作为子类,仅作为操作字符文件的便捷类存在。当操作的字符文件,使用的是默认编码表时可以不用父类,而直接用子类就完成操作了,简化了代码。
InputStreamReader isr = new InputStreamReader(new FileInputStream("a.txt"));//默认字符集。
InputStreamReader isr = new InputStreamReader(new FileInputStream("a.txt"),"GBK");//指定GBK字符集。
FileReader fr = new FileReader("a.txt");
这三句代码的功能是一样的,其中第三句最为便捷。
注意:一旦要指定其他编码时,绝对不能用子类,必须使用字符转换流。什么时候用子类呢?
条件:
1、操作的是文件。2、使用默认编码。
总结:
字节--->字符 : 看不懂的--->看的懂的。 需要读。输入流。 InputStreamReader
字符--->字节 : 看的懂的--->看不懂的。 需要写。输出流。 OutputStreamWriter
4.缓冲流
Java中提高了一套缓冲流,它的存在,可提高IO流的读写速度
缓冲流,根据流的分类分类字节缓冲流与字符缓冲流。
4.1字节缓冲流
字节缓冲流根据流的方向,共有2个
- 写入数据到流中,字节缓冲输出流 BufferedOutputStream
- 读取流中的数据,字节缓冲输入流 BufferedInputStream
它们的内部都包含了一个缓冲区,通过缓冲区读写,就可以提高了IO流的读写速度
4.1.1字节缓冲输出流BufferedOutputStream
通过字节缓冲流,进行文件的读写操作 写数据到文件的操作
- 构造方法
- public BufferedOutputStream(OutputStream out)创建一个新的缓冲输出流,以将数据写入指定的底层输出流。
package cn.jxufe.java.chapter09.demo03; import java.io.BufferedOutputStream; import java.io.FileOutputStream; import java.io.IOException; /* * 字节输出流的缓冲流 * java.io.BufferedOuputStream 作用: 提高原有输出流的写入效率 * BufferedOuputStream 继承 OutputStream * 方法,写入 write 字节,字节数组 * * 构造方法: * BufferedOuputStream(OuputStream out) * 可以传递任意的字节输出流, 传递的是哪个字节流,就对哪个字节流提高效率 * * FileOutputSteam */ public class Test03BufferOutputStream { // 创建字节输出流,绑定文件 // FileOutputStream fos = new FileOutputStream("c:\buffer.txt"); // 创建字节输出流缓冲流的对象,构造方法中,传递字节输出流 public static void main(String[] args) throws IOException { // TODO Auto-generated method stub BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("d:\buffer.txt")); bos.write(55); byte[] bytes = "good".getBytes(); bos.write("hello".getBytes()); bos.write(bytes); bos.write(bytes, 1, 3); bos.close(); } }
4.1.2字节缓冲输入流 BufferedInputStream
刚刚我们学习了输出流实现了向文件中写数据的操作,那么,现在我们完成读取文件中数据的操作
- 构造方法
- public BufferedInputStream(InputStream in)
package cn.jxufe.java.chapter09.demo03; import java.io.BufferedInputStream; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; /* * 字节输入流的缓冲流 * java.io.BufferedInputStream * 继承InputStream,标准的字节输入流 * 读取方法 read() 单个字节,字节数组 * * 构造方法: * BufferedInputStream(InputStream in) * 可以传递任意的字节输入流,传递是谁,就提高谁的效率 * 可以传递的字节输入流 FileInputStream */ public class Test04BufferInputStream { public static void main(String[] args) throws IOException { // TODO Auto-generated method stub // 创建字节输入流的缓冲流对象,构造方法中包装字节输入流,包装文件 BufferedInputStream bis = new BufferedInputStream(new FileInputStream("d:\buffer.txt")); byte[] bytes = new byte[10]; int len = 0; while ((len = bis.read(bytes)) != -1) { System.out.print(new String(bytes, 0, len)); } bis.close(); } }
5.几种读取文件方式效率的对比
package cn.jxufe.java.chapter09.demo03; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; /* * 文件复制方式,字节流,一共4个方式 * 1. 字节流读写单个字节 125250 毫秒 * 2. 字节流读写字节数组 193 毫秒 OK * 3. 字节流缓冲区流读写单个字节 1210 毫秒 * 4. 字节流缓冲区流读写字节数组 73 毫秒 OK */ public class Test05CopyContrast { public static void main(String[] args) throws IOException { // TODO Auto-generated method stub long s = System.currentTimeMillis(); copy_4(new File("c:\q.exe"), new File("d:\q.exe")); long e = System.currentTimeMillis(); System.out.println(e - s); } /* * 方法,实现文件复制 * 4. 字节流缓冲区流读写字节数组 */ public static void copy_4(File src, File desc) throws IOException { BufferedInputStream bis = new BufferedInputStream(new FileInputStream(src)); BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(desc)); int len = 0; byte[] bytes = new byte[1024]; while ((len = bis.read(bytes)) != -1) { bos.write(bytes, 0, len); } bos.close(); bis.close(); } /* * 方法,实现文件复制 * 3. 字节流缓冲区流读写单个字节 */ public static void copy_3(File src, File desc) throws IOException { BufferedInputStream bis = new BufferedInputStream(new FileInputStream(src)); BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(desc)); int len = 0; while ((len = bis.read()) != -1) { bos.write(len); } bos.close(); bis.close(); } /* * 方法,实现文件复制 * 2. 字节流读写字节数组 */ public static void copy_2(File src, File desc) throws IOException { FileInputStream fis = new FileInputStream(src); FileOutputStream fos = new FileOutputStream(desc); int len = 0; byte[] bytes = new byte[1024]; while ((len = fis.read(bytes)) != -1) { fos.write(bytes, 0, len); } fos.close(); fis.close(); } /* * 方法,实现文件复制 * 1. 字节流读写单个字节 */ public static void copy_1(File src, File desc) throws IOException { FileInputStream fis = new FileInputStream(src); FileOutputStream fos = new FileOutputStream(desc); int len = 0; while ((len = fis.read()) != -1) { fos.write(len); } fos.close(); fis.close(); } }
6.字符缓冲流
6.1字符缓冲输出流 BufferedWriter
package cn.jxufe.java.chapter09.demo04; import java.io.BufferedWriter; import java.io.FileWriter; import java.io.IOException; /* * 字符输出流缓冲区流 * java.io.BufferedWriter 继承 Writer * 写入方法 write () 单个字符,字符数组,字符串 * * 构造方法: * BufferedWriter(Writer w)传递任意字符输出流 * 传递谁,就高效谁 * 能传递的字符输出流 FileWriter, OutputStreamWriter * * BufferedWriter 具有自己特有的方法 * void newLine() 写换行 * * newLine()文本中换行, 也是文本换行 * 方法具有平台无关性 * Windows * Linux * * newLine()运行结果,和操作系统是相互关系 * JVM: 安装的是Windows版本,newLine()写的就是 * 安装的是Linux版本,newLine()写的就是 */ public class Test01BufferWriter { public static void main(String[] args) throws IOException { // 创建字符输出流,封装文件 FileWriter fw = new FileWriter("d:\buffer.txt"); BufferedWriter bfw = new BufferedWriter(fw); bfw.write("你好"); bfw.newLine(); bfw.flush(); bfw.write("我好好"); bfw.newLine(); bfw.flush(); bfw.write("大家都好"); bfw.flush(); bfw.close(); } }
6.2字符缓冲输入流 BufferedReader
UTF-8的编码方式创建的
package cn.jxufe.java.chapter09.demo04; import java.io.BufferedReader; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStreamReader; /* * 字符输入流缓冲流 * java.io.BufferedReader 继承 Reader * 读取功能 read() 单个字符,字符数组 * 构造方法: * BufferedReader(Reader r) * 可以任意的字符输入流 * FileReader InputStreamReader * * BufferedReader自己的功能 * String readLine() 读取文本行 * * 方法读取到流末尾,返回null * 小特点: * 获取内容的方法一般都有返回值 * int 没有返回的都是负数 * 引用类型 找不到返回null * boolean 找不到返回false * * String s = null * String s ="null" * * readLine()方法返回行的有效字符,没有 */ public class Test02BufferedReader { public static void main(String[] args) throws IOException { // 创建字符输入流缓冲流对象,构造方法传递字符输入流,包装数据源文件 FileInputStream fis = new FileInputStream("d:\a.txt"); InputStreamReader isr = new InputStreamReader(fis, "utf-8"); BufferedReader br = new BufferedReader(isr); // 调用缓冲流的方法 readLine()读取文本行 // 循环读取文本行, 结束条件 readLine()返回null String line = null; int lineNumber = 0; while ((line = br.readLine()) != null) { lineNumber++; System.out.println(lineNumber + " " + line); } br.close(); } /* String linString = br.readLine(); System.out.println(linString); linString = br.readLine(); System.out.println(linString); linString = br.readLine(); System.out.println(linString); linString = br.readLine(); System.out.println(linString);*/ }
7.使用字符缓冲流完成文本文件的复制
package cn.jxufe.java.chapter09.demo04; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; public class Test03Copy { public static void main(String[] args) throws IOException { // TODO Auto-generated method stub BufferedReader bfr = new BufferedReader(new FileReader("d:\a.txt"));// 复制文件的时候不用担心编码问题了 BufferedWriter bfw = new BufferedWriter(new FileWriter("d:\a2.txt")); // 读取文本行, 读一行,写一行,写换行 String line = null; while ((line = bfr.readLine()) != null) { bfw.write(line); bfw.newLine(); bfw.flush(); } bfw.close(); bfr.close(); } }
8.流的操作规律
IO流中对象很多,解决问题(处理设备上的数据时)到底该用哪个对象呢?
把IO流进行了规律的总结(四个明确):
- 明确一:要操作的数据是数据源还是数据目的。
源:InputStream Reader
目的:OutputStream Writer
先根据需求明确要读,还是要写。
- 明确二:要操作的数据是字节还是文本呢?
源:
字节:InputStream
文本:Reader
目的:
字节:OutputStream
文本:Writer
已经明确到了具体的体系上。
- 明确三:明确数据所在的具体设备。
源设备:
硬盘:文件 File开头。
内存:数组,字符串。
键盘:System.in;
网络:Socket
目的设备:
硬盘:文件 File开头。
内存:数组,字符串。
屏幕:System.out
网络:Socket
完全可以明确具体要使用哪个流对象。
- 明确四:是否需要额外功能呢?
额外功能:
转换吗?转换流。InputStreamReader OutputStreamWriter
高效吗?缓冲区对象。BufferedXXX
InputStream
FileInputStream
BufferedInputStream
OuputStream
FileOutputStream
BufferedOuputStream
Writer
OutputStreamWriter
FileWriter
BufferedWriter
Reader
InputStreamReader
FileReader
BufferedReader