1.文件输出流 (java IO简介)
/** * java io 标准的输入与输出 * 使用java IO我们可以对外界设备已相同的方式进行 * 读写完成数据交换. * * java IO将"读"与"写"按照方向进行了划分: * 输入:从外界到程序的方向,用于让程序获取外界数据因此输入是"读"数据的操作 * 输出:从程序到外界的方向,用于将数据"写"出的操作. * * java IO以"流"的形式表示读写功能 * java.io.InputStream 输入流,通过输入流我们可以 * 连接上外界设备从而读取该设备数据 * java.io.OutputStream 输出流 * 以上两个流是所有字节输入流与输出流的超类,规定了 * 所有输入流与输出流的基本读写功能. * * java将流分为两大类:节点流与处理流 * * 节点流:又称为"低级流",是真实连接程序与数据源的 * "管道",用于实际搬运数据的流. 读写一定是建立在 * 节点流的基础上进行的. * * 处理流:又称为"高级流",高级流不能独立存在,必须 * 连接在其他流上,目的是当数据流经当前流时对其做 * 某些加工处理,简化我们读写数据时的相应操作. * * 实际使用IO时,我们通常会串联若干的高级流最终连接 * 到低级流上,使得读写数据以流水线式的加工处理完成, * 这个操作称为"流的连接",也是IO的精髓所在 * 文件流 * 文件流是一对低级流,作用是连接到文件上,用于读写 * 文件数据. * java.io.FileOutputStream:文件输出流 * java.io.FileInputStream:文件输入流 */ public class FOSDemo { public static void main(String[] args) throws IOException { /* * 文件流提供的构造方法: * FileOutputStream(File file) * FileOutputStream(String path) * 以上两种创建方式,默认为覆盖写模式,即: * 若指定的文件已经存在,那么会将该文件原有 * 数据全部删除.然后再将新数据写入文件. * * FileOutputStream(File file,boolean append) * FileOutputStream(String path,boolean append) * 以上两种构造器允许再传入一个boolean值类型的 * 参数,如果该值为true时,文件输出流就是追加写模式 * 即:数据中原有数据都保留,新内容会被追加到文件末尾 * 文件流与RAF的区别: * RAF是基于指针的随机读写形式,可以对文件任意 * 位置进行读或写操作,可以做到对文件部分数据 * 覆盖等操作.读写更灵活. * * 文件流是基于java IO的标准读写,而IO是顺序 * 读写模式,即:只能向后写或读数据,不能回退. * * 单从读写灵活度来讲RAF是优于文件流的,但是 * 文件流可以基于java IO的流连接完成一个复杂 * 数据的读写,这是RAF不容易做到的. */ FileOutputStream fos = new FileOutputStream("./fos.txt",true); // String line = "回首,掏~"; // fos.write(line.getBytes("UTF-8")); // fos.write("鬼刀一开看不见~走位~走位~".getBytes("UTF-8")); fos.write("手".getBytes("UTF-8")); System.out.println("写出完毕!"); fos.close(); } }
2.文件输入流
/** * 文件输入流,用于从文件中读取数据 */ public class FISDemo { public static void main(String[] args) throws IOException { FileInputStream fis = new FileInputStream("fos.txt"); byte[] data = new byte[1000]; int len = fis.read(data); String str = new String(data,0,len,"UTF-8"); System.out.println(str); fis.close(); } }
3.文件复制(字节块)
/** * 使用文件流完成文件的复制工作 */ public class CopyDemo { public static void main(String[] args) throws IOException { /* * 1:创建文件输入流读取原文件 * 2:创建文件输出流用于写复制文件 * 3:循环从原文件读取字节写入到复制文件中 * 4:关闭两个流 */ FileInputStream fis = new FileInputStream("movie.mp4"); FileOutputStream fos = new FileOutputStream("movie_cp.mp4"); int len = -1;//记录每次实际读取的字节量 byte[] data = new byte[1024*10]; while((len = fis.read(data))!=-1) { fos.write(data,0,len); } System.out.println("复制完毕!"); fos.close(); fis.close(); } }
4.缓冲流
/** * 缓冲流 * java.io.BufferedOutputStream * java.io.BufferedInputStream * * 缓冲流是一对高级流,在流连接中的作用是提高读写效率 * 使得我们在进行读写操作时用单字节读写也能提高读写的效率. * * 缓冲流之所以可以提高读写效率,是因为缓冲流内部有 * 一个缓冲区(一个字节数组),无论我们使用缓冲流进行 * 何种读写(单字节或块读写)最终都会被缓冲流转换为 * 块读写来提高效率 */ public class CopyDemo2 { public static void main(String[] args) throws IOException { FileInputStream fis = new FileInputStream("music.mp3"); BufferedInputStream bis = new BufferedInputStream(fis); FileOutputStream fos = new FileOutputStream("music_cp2.mp3"); BufferedOutputStream bos = new BufferedOutputStream(fos); int d = -1; while((d = bis.read())!=-1) { bos.write(d); } System.out.println("复制完毕!"); bis.close(); bos.close(); } }
5.缓冲输出流的缓冲区
/** * 缓冲输出流的缓冲区问题 */ public class BOS_flush { public static void main(String[] args) throws IOException { FileOutputStream fos = new FileOutputStream("bos.txt"); BufferedOutputStream bos = new BufferedOutputStream(fos); bos.write("摩擦摩擦~是魔鬼的步伐~".getBytes("UTF-8")); /* * void flush() * flush方法是OutputStream中定义的方法, * 所有的输出流都具有该方法,但是只有缓冲 * 流的该方法有实际意义.其他的流具有该方法 * 的目的是在流连接中传递缓冲操作给缓冲流 * * flush的作用是将缓冲流中已经缓存的数据一次性写出. * 频繁的调用flush方法会提高写出的次数从而 * 降低写出效率,但是能保证数据写出的即时性. */ // bos.flush(); System.out.println("写出完毕!"); bos.close(); } }
6.对象输出流
/** * 对象流 * java.io.ObjectOutputStream * java.io.ObjectInputStream * * 对象流是一对高级流,在流连接中的作用是方便读写 * java对象.(对象与字节的转换由对象流完成) */ public class OOSDemo { public static void main(String[] args) throws IOException { /* * 将一个Person实例写入文件person.obj中 */ String name = "苍老师"; int age = 18; String gender = "女"; String[] otherInfo = {"是一名演员","爱好是写毛笔字","生了一对双胞胎","促进中日文化交流"}; Person p = new Person(name, age, gender, otherInfo); FileOutputStream fos = new FileOutputStream("person.obj"); ObjectOutputStream oos = new ObjectOutputStream(fos); /* * 该方法可能抛出:NotSerializableException * 当写出的对象所属的类没有实现Serializable接口 * 时就会抛出该异常. * * 写入文件后发现该文件的实际数据量比当前对象 * 保存的内容要大,这是因为这组字节除了包含了 * 该对象的数据外还有这个对象的结构信息. */ oos.writeObject(p); System.out.println("写出完毕!"); oos.close(); } }
7.对象输入流
/** * 对象输入流 */ public class OISDemo { public static void main(String[] args) throws IOException, ClassNotFoundException { /* * 将person.obj文件中的对象读取出来 */ FileInputStream fis = new FileInputStream("person.obj"); ObjectInputStream ois = new ObjectInputStream(fis); Person p = (Person)ois.readObject(); System.out.println(p); ois.close(); } }
8.字符输出转换流
/** * 字符流 * java.io.Reader和java.io.Writer * 上述两个类是所有字符流的超类,规定了所有字符流都 * 必须具备的读写字符的相关方法. * * java将流按照读写单位划分为字节流与字符流 * 字符流以char为单位读写数据,但是底层本身还是读写 * 字节,只是字符与字节的转换字符流自行完成. * * 转换流 * java.io.InputStreamReader * java.io.OutputStreamWriter * 转换流是一对字符流,同时他们也是高级流,在实际开发 * 时我们通常不会直接操作这两个流,但是在读写文本数据 * 时,流连接中他们是非常重要的一环.负责衔接其他字符 * 高级流与字节流. */ public class OSWDemo { public static void main(String[] args) throws IOException { FileOutputStream fos = new FileOutputStream("osw.txt"); /* * 转换流在创建时通常会传入第二个参数,这个 * 参数用来指定字符集,这样一来通过当前流写 * 出的文本数据都会按照该字符集转换为字节后 * 写出. */ OutputStreamWriter osw = new OutputStreamWriter(fos,"UTF-8"); osw.write("和我在成都的街头走一走~"); osw.write("直到所有的灯都熄灭了也不停留."); System.out.println("写出完毕!"); osw.close(); } }
9.字符输入转换流
/** * 使用转换流读取文本数据 */ public class ISRDemo { public static void main(String[] args) throws IOException { // RandomAccessFile raf = new RandomAccessFile("osw.txt","r"); // byte[] data = new byte[(int)raf.length()]; // raf.read(data); // String str = new String(data,"UTF-8"); // System.out.println(str); // raf.close(); // FileInputStream fis = new FileInputStream("osw.txt"); // byte[] data = new byte[1000]; // int len = fis.read(data); // String str = new String(data,0,len,"UTF-8"); // System.out.println(str); // fis.close(); FileInputStream fis = new FileInputStream("osw.txt"); InputStreamReader isr = new InputStreamReader(fis,"UTF-8"); // char[] data = new char[100]; // int len = isr.read(data); // String str = new String(data,0,len); // System.out.println(str); int d = -1; while((d = isr.read())!=-1) {//可以一次读一个字符 System.out.print((char)d); } isr.close(); } }
10.缓冲字符输入流
/** * 缓冲字符输入流 * java.io.BufferedReader * 块读文本数据,并且可以按行读取字符串. */ public class BRDemo { public static void main(String[] args) throws IOException { /* * 将当前源代码内容输出到控制台 */ FileInputStream fis = new FileInputStream("./src/io/BRDemo.java"); InputStreamReader isr = new InputStreamReader(fis); BufferedReader br = new BufferedReader(isr); /* * String readLine() * 连续读取若干字符直到读取到换行符 * 为止,将换行符之前的字符组成一个字符 * 串返回.如果返回值为null,表示流读取到末尾了. */ String line = null; while((line = br.readLine())!=null) { System.out.println(line); } br.close(); } }
11.缓冲字符输出流
/** * 缓冲字符流 * java.io.BufferedWriter * java.io.BufferedReader * 缓冲流是块读写文本数据,提高读写效率.并且 * 可以按行读写字符串. * * java.io.PrintWriter具有自动行刷新的缓冲 * 字符输出流,内部总是连接BufferedWriter作为 * 其缓冲加速操作. */ public class PWDemo1 { public static void main(String[] args) throws IOException { /* * 向pw.txt文件中写入字符串 * 该构造方法内部会自动进行流连接操作, * 分别连接缓冲字符流,转换流和文件流. */ PrintWriter pw = new PrintWriter("pw.txt","UTF-8"); pw.println("让我掉下眼泪的,不止昨夜的酒."); pw.println("让我依依不舍的,不止你的温柔."); System.out.println("写出完毕!"); pw.close(); } }
/** * 自行完成流连接使用PW写出文本数据 */ public class PWDemo2 { public static void main(String[] args) throws IOException { FileOutputStream fos = new FileOutputStream("pw2.txt"); OutputStreamWriter osw = new OutputStreamWriter(fos,"UTF-8"); BufferedWriter bw = new BufferedWriter(osw); PrintWriter pw = new PrintWriter(bw); pw.println(""); System.out.println("写出完毕!"); pw.close(); } }
12.IO流图解
13.IO流综合应用
/** * 实现简易记事本工具 * 程序启动后,要求输入文件名,然后对文件写内容. * 将后续在控制台输入的每行字符串都按行写入到 * 该文件中,当单独输入了exit时,程序退出. * * 要求:自行使用流连接创建PW */ public class PWDemo3 { public static void main(String[] args) throws IOException { Scanner scanner = new Scanner(System.in); System.out.println("请输入文件名:"); String fileName = scanner.nextLine(); FileOutputStream fos = new FileOutputStream(fileName); OutputStreamWriter osw = new OutputStreamWriter(fos,"UTF-8"); BufferedWriter bw = new BufferedWriter(osw); /* * 创建PrintWriter时使用的构造方法如 * 过第一个参数是一个流,那么就支持第 * 二个参数,这个参数是一个boolean值, * 该值为true时就打开了自动行刷新功能 * 此时每当调用println方法写出一行字符 * 串都会自动flush. */ PrintWriter pw = new PrintWriter(bw,true); System.out.println("请开始输入内容:"); while(true) { String line = scanner.nextLine(); if("exit".equals(line)) { break; } pw.println(line); } System.out.println("再见!"); pw.close(); } }