黑马程序员 十、IO 文件操作(2)

    xiaoxiao2025-09-30  55

    Java帮帮-IT资源分享网   十、IO 文件操作(2) 1、内存操作流 操作内存流的时候(从读取出来,注意一定要把真正的数据用toByteArray或者toCharArray 将数据读出来) 之前的文件操作流是以文件的输入输出为主的,当输出的位置变成了内存,那么就称为内 存操作流。此时要使用内存流完成内存的输入和输出操作。 如果程序运行过程中要产生一些临时文件,可采用虚拟文件方式实现; 直接操作磁盘的文件很耗性能,使用内存流可以提升性能;jdk 里提供了内存流可实现类似于 内存虚拟文件的功能。 ByteArrayInputStream:将内容写到内存中 CharArrayReader ByteArrayOutputStream:将内存中的数据写出 CharArrayWriter ByteArrayInputStream:构造方法: public ByteArrayInputStream(byte[] buf):全部内容 public ByteArrayInputStream(byte[] buf,int offset,int length):指定范围的内容 ByteArrayOutputStream: public ByteArrayOutputStream() 我的总结:内存流操作:先把数据写到内存中去,然后再从内存中读取出来!提升了性能! 例子 //此处用的是内存字节流(写入加输出) package june6D; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; public class ByteArrayDemo7 { public static void main(String[] args) throws IOException { String s = "java is a good language"; ByteArrayOutputStream bos = new ByteArrayOutputStream();//输 出流 bos.write(s.getBytes()); // 已经把信息写到了内存中 byte[] bys = bos.toByteArray();// 得到真正的数据 ByteArrayInputStream bis = new ByteArrayInputStream(bys);// 输入流,需要源。 byte[] b = new byte[1024]; int len; while ((len = bis.read(b)) != -1) { String data = new String(b, 0, len); System.out.println(data); } } } package june6D; import java.io.CharArrayReader; import java.io.CharArrayWriter; public class CharArrayDemo8 { public static void main(String[] args) throws Exception { // 用内存字符流先把数据保存到内存中,然后从内存中取出数据 String s = "河南城建学院"; CharArrayWriter cw = new CharArrayWriter(); cw.write(s);// 数据写到了内存中 char[] ch = cw.toCharArray(); CharArrayReader cr = new CharArrayReader(ch); char[] b = new char[1024]; int len; while ((len = cr.read(b)) != -1) { String data = new String(b, 0, len); System.out.println(data); } } }   2、打印流 (只有两个,PrintWriter 和 PrintStream) 思考:如果现在要想完成一个字符串或者是 boolean 型或者是字符型的数据输出使用 OutputStream 是否方便? 肯定是不方便的,因为 OutputStream 中只能操作字节数据,所以其他的数据类型很难操作, 那么在 Java 的 IO 包中为了解决这种问题增加了两种类:PrintStream、PrintWriter。 打印流有非常好的打印功能,可以打印任何的数据类型。如,整数,小数,字符串等。 观察 PrintStream 类的构造: public PrintStream(File file) throws FileNotFoundException public PrintStream(OutputStream out) 虽然 PrintStream 是 OutputStream 的子类,但是在实例化的时候依然需要一个 OutputStream 的对象。 PrintWriter 和 PrintStream 都属于输出流,分别针对字符和字节。 PrintWriter 和 PrintStream 重载的 print()和 println()用于多种数据类型的输出。 print()里的参数不能为空;println()可以 PrintWriter 和 PrintStream 输出操作不抛出异常 PrintStream 调用 println 方法有自动 flush 功能; Eg: package june6D; import java.io.FileWriter; import java.io.PrintStream; import java.io.PrintWriter; public class PrintDemo9 { public static void main(String[] args) throws Exception { PrintStream ps = new PrintStream("out.txt"); // ps.write(12); ps.println(10086); ps.println(false); // ps.print();针对print而言,不可以出现这样的(无参) ps.println();// 此时就可以 //备注:System.out.println();想当于ps = System.out; ps = System.out; ps.println("您好!");// 控制台操作,注意上一句 // 字符打印流 PrintWriter pr = new PrintWriter("out2.txt"); // PrintWriter(OutputStream out, boolean autoFlush) 通过现有 的 OutputStream,创建新的 PrintWriter。(构造方法) pr = new PrintWriter(new FileWriter("out2.txt"), true);// 自 动刷新,否则的话需要关闭资源! // 与PrintStream不同,若PrintWriter使用了自动刷新方法,那么必须调用 println,print,format这些方法的其中一个才可以实现操作 pr.println("呼哈哈哈哈"); pr.println(false); pr = new PrintWriter(System.out, true);// 打印在控制台上 pr.println(false); pr.println("河南城建学院"); pr.println(376430645); // pr.close();//因为使用了自动刷新。 } }   3、格式化输出 Java5 后,PrintStream 类多了 printf()方法用于格式化输出操作。但是格式化输出的时候必须 指定输出数据的类型: (构造方法) PrintStream format(String fo, Object... args) 使用指定格式字符串和参数将格式化字符串 写入此输出流中。    备注:当然你也可以全部使用“%s”来表示所有的数据类型! 格式: 需要格式 % 占位符 Eg: package july7file; import java.io.FileWriter; import java.io.PrintStream; import java.io.PrintWriter; public class Demo9 { public static void main(String[] args) throws Exception { PrintStream ps = new PrintStream("E:/name.txt"); ps.write("123456".getBytes()); ps.println(false); ps.print(false); PrintWriter pw = new PrintWriter(new FileWriter("E:/name1.txt"),true); pw.println("我们的未来!");//write不可以 pw = new PrintWriter(System.out,true); pw.println("我们的未来!");//打印在控制台上 String name = "刘昭"; int age = 13; char score = 'A'; String format = "姓名=%s,年龄=%d,成绩=%c"; System.out.printf(format,name,age,score); int i = System.in.read();//流的重定向 System.out.println((char)i); } }   4、标准流 标准输入流: System.in 默认表示的是键盘录入 标准输出流: System.out 默认表示的是屏幕输出 Eg: package june6D; import java.io.FileInputStream; import java.io.IOException; import java.io.PrintStream; public class SyetemDemo { public static void main(String[] args) throws IOException { /** * 标准流: 标准输入流: System.in 默认表示的是键盘录入 标准输出流: System.out 默认表示的是屏幕输出 * * 若现在我输出不想打印在屏幕上,怎么办? * 若现在我不想通过键盘来录入数据,有怎么办? * * 流的重定向: static void setOut(PrintStream out) 重新分配“标准” 输出流。 static void * setIn(InputStream in) 重新分配“标准”输入流。 */ System.out.println("123456789");//最普通的打印 System.err.println("123652");// 同 样 是 一 种 输 出 流 , 打 印 出 的 是 123652 /** * static void setOut(PrintStream out) 重新分配“标准”输出流。 */ // 输出流就被重新定义到了文件,而不是屏幕 System.setOut(new PrintStream("68Demo.txt"));// 只有在定义过后 才生效,所以上面的还是会输出到控制台 System.out.println("AAAA"); System.out.println("BBBB");//就输出了在文件里 int i = System.in.read();// 接受从键盘输入的数据,写在最前面(没有 任何重新分配)才有效 System.out.println("i所对应的是:" + (char) i);// 把它转换为字符 型 System.out.println(i); /** * 重新分配,由标准键盘输入变为由文件输入 */ System.setIn(new FileInputStream("copy6.4"));//备注:打印的是 文件copy6.4中的数据,而且打印在文件68Demo.txt中。 byte[] buff = new byte[1024]; int len = 0; while ((len = System.in.read(buff)) != -1) { System.out.println(new String(buff, 0, len));// 此时不会打 印在控制台上,因为上面已经重新定义了由打印到屏幕上转换为打印到文件里 } } }   5、Scanner(简单文本扫描器) Scanner(File source) 构造一个新的 Scanner,它生成的值是从指定文件扫描的。 备注:实现了Iterable接口 package june6D; import java.io.File; import java.io.PrintStream; import java.util.Scanner; public class ScannerDemo18 { public static void main(String[] args) throws Exception { // 参照api Scanner sc = new Scanner(System.in);// 从键盘输入 // int i = System.in.read(); /* 连着进行了三次,没有完成的话不停止运行 System.out.println(sc.next()); System.out.println(sc.next()); * System.out.println(sc.next()); */ System.setOut(new PrintStream("Scanner.txt"));// 流的重定向(打 印到哪里) sc = new Scanner(new File("copy6.4"));// 扫描位置 int line = 1; while (sc.hasNextLine()) {// 是否有下一行 //一行一行的读取,这样的 话格式好看 System.out.println(line + " " + sc.nextLine());// 读取下一 行 line++; } } } 例子: 猜数字游戏: 1. 系统随机生成一个数字[1,100]; 2. 从键盘录入一个数字,[1,100] 3. 判断输入的数字和随机数比较: 随机数 > 输入数:你输入太小了 随机数 < 输入数:输入太大了 随机数 = 输入数: 恭喜哦 思考:先想怎么生成一个随机数;然后怎么在键盘中录入一个随机数,第三步就是比较了; 但是注意的是:需要确保输入的数据为数字,而且有范围的限制! package july7file; import java.util.Random; import java.util.Scanner; public class Demo12 { public static void main(String[] args) { guess(); } public static void guess(){ int i = new Random().nextInt(100)+1; System.out.println(i); System.out.println("请输入随机数来匹配,您有五次机会!"); Scanner sc = new Scanner(System.in);//键盘录入 for (int j = 0; j < 5; j++) { String s = sc.nextLine(); if(!s.matches("\\d+")){ System.out.println("请确认您输入的是数字"); break; } Integer in = new Integer(s); if(in > 100 | in < 0){ System.out.println("请确认您输入的数字在0到100之间!"); } switch (in.compareTo(i)) { case 1: System.out.println("您输入的数字过大!"); System.out.println("请输入:"); break; case -1: System.out.println("您输入的数字过小!"); System.out.println("请输入:"); break; default: System.out.println("恭喜您,您输入的数字正好匹配!"); return; } } } }   6、缓冲流 缓冲流要“套接”在相应的节点流之上,对读写的数据提供了缓冲的功能,提高了读写效率, 同时增加了一些新的方法。 四种缓冲流 BufferedReader(Reader in) BufferedReader(Reader in,int sz)//sz 表示自定义缓冲区大小 BufferedWriter(Writer out) BufferedWriter(Writer out,int sz) BufferedInputStream(InputStream in) BufferedInputStream(InputStream in,int sz) BufferedOutputStream(OutputStream out) BufferedOutputStream(OutputStream out,int sz) BufferedReader 提供 readLine 方法用于读取一行字符串。 BufferedWriter 提供了 newLine 方法用于写入一个行分隔符。等价于//.writer("\r\n"); 对于输出的缓冲流,写出的数据会先在内存中缓冲,使用 flush 方法将会使内存中的数据立 刻写出。 Eg: package june6D; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; //用缓冲流,性能相对高些 public class BufferedInputStreamDemo22 { public static void main(String[] args) throws IOException { /* * BufferedInputStream bis = new BufferedInputStream(new * FileInputStream("68.txt")); BufferedOutputStream bos = new * BufferedOutputStream(new FileOutputStream("buffer.txt")); * * int len = 0; * while((len = bis.read()) != -1){ * bos.write(len); * } * bos.close(); * bis.close(); */ try ( BufferedReader br = new BufferedReader(new FileReader("68.txt")); BufferedWriter bw = new BufferedWriter(new FileWriter( "bufferWriter.txt"))) {//java7新特性,自动关闭资源 String Line = null; while ((Line = br.readLine()) != null) { bw.write(Line); bw.newLine();//此时必须加上换行操作,注意这是个新用法(方法) } } catch (Exception e) { e.printStackTrace(); } } } 我的总结:在后续的学习中,缓冲流用到的会很多,因为效率高!   7、合并流(SequenceInputStream) 需要两个源文件,还有输出的目标文件 SequenceInputStream: 将两个文件的内容合并成一个文件 该类提供的方法: SequenceInputStream(InputStream s1, InputStream s2) :根据两个字节输入流对象来创建合并 流对象。 备注:谁放在前面,谁就先打印出来 Eg: package june6D; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.io.SequenceInputStream; //和并两个文件的合并流 public class SequenceInputStreamDemo24 { public static void main(String[] args) throws IOException { SequenceInputStream si = new SequenceInputStream( new FileInputStream("6.4"), new FileInputStream("hello.java")); OutputStream os = new FileOutputStream("sequence.txt"); int len; byte []b = new byte[1024]; while((len = si.read(b)) != -1){ os.write(b, 0, len); } } } Java帮帮-IT资源分享网
    最新回复(0)