黑马程序员____基础加强____[IO流个人总结](二)
e)-->write(byte[])-->close()
BufferedInputStream
BufferedOutputStream
自定义字节流缓冲区 <==> read & write的特点
计算机中数据以二进制保存,以字节以byte为单位存取。读取时为便于操会将二进制转成十进制
这样问题就随之而来了,字节流的read方法以返回值 -1 来表示到达文件末尾
如果刚好有连续的8个1,直接转成int型就是-1,就意外满足了read 方法-1的控制条件
导致程序提前结束,所以字节流缓冲区的read方法必须避免这种情况的发生生
解决办法:将 byte 转为 int,然后通过二进制"&"运算补0
byte -1 --> int -1
11111111 11111111 11111111 11111111
&00000000 00000000 00000000 11111111 //255
------------------------------------
00000000 00000000 00000000 11111111 //int
这也是为什么读取单个字节时read 方法的返回值为 int 而不是 byte 的原因
---------------------------------------
读取键盘录入
标准的输入输出流: System.in(InputStream) & System.out(PrintStream)
转换流: InputStreamReader
OutputStreamWriter
键盘录入最常见形式:
BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in)); //字符 <--字节
BufferedWriter bufw = new BufferedWriter(new InputStreamReader(System.out));//字符 -->字节
设置源和目的:
System.setIn(new FileInputStream("ReadIn.java")); //源,也可直接将字节流传入转换流
System.setOut(new PrintStream("printStream.txt")); //目的, FileOutputStream 亦可
1)字节流和字符流最大的区别是,字节流可以操作任何数据,字符流只能操作文本数据。
2)字符流在底层调用了字节流的缓冲区,所以需要刷新动作;而字节流在操作时一般不需要刷新
数据在硬盘中是以二进制存储的,以 byte (8位)为单位,字节流的read 和write 操作单位对象是 byte
字符流在底层调用了字节流,专门用于操作字符,其read 和 write 方法操作的单位对象是 char
使用时要区分"源"&"目的",操作对象是否为纯文本 字符:字节
--------------------------------------
IO流中另一个重要的类 "File"
File 类是文件和目录路径名的抽象表示形式。 专门用于对文件进行增删改查的操作
File类的过滤,两个接口
FileFilter 过滤路径
FilenameFilter 过滤文件名
示例: 过滤获取指定文件夹下的 .java文件
File dir = new File("f:\\JAVA\\test");
String[] arr = dir.list(new FilenameFilter(){//匿名内部类
public boolean accept(File dir,String name) {
return name.endsWith(".java"); //String类方法
} });
Java的跨平台分隔符"separator"
"递归": 即函数自身调用自身
使用递归要注意: 1)要有明确的递归结束条件;避免死循环
2)控制调用次数,避免栈内存溢出
3)递归书写简洁,但效率较低,应避免在算法题中使用
应用: 遍历访问指定目录下文件及其子目录中内容,并对其进行操作
-----------------
Properties 类
Properties 是hashtable的子类,具备map集合的特点,里面存储的键值对都是字符串,该集合可以加载进IO流
该类提供了一些对io流进行操作的方法
较为熟悉的应用:
系统运行日志: Properties prop = System.getProperties();
从配置文件中获取数据,以键值对的形式存入集合并进行操作。如限制软件运行次数 time = 5;时停止服务
"打印流" PrintWriter & PrintStream
可以直接操作输入流和文件。
PrintWriter out = new PrintWriter(new FileWriter("...") ,true)
PrintWriter 的print & println 就是常用的输出语句sop,//该方法可以自动刷新,换行
"合并流" SequenceInputStream
对多个输入流进行合并,到同一个输出流
"文件的分割" 即将一个输入流对应到多个输出流, 输出大小以一个缓冲数组为单位
"文件的合并" 即将多个输入流指向同一个输出流
使用 Vector & Enumeration :List数组集合枚举
示例:
Vector
v = new Vector
v.add(new FileInputStream(File))... //添加多个输入流 new SequenceInputStream(v.elements()); //该参数为枚举类型,合并源 定义输出目的...读写操作 使用 Vector+枚举 不够高效,使用 ArrayList+迭代 来代替 而 SequenceInputStream 的构造参数必须为枚举类型 所以就有必要复写 Enumeration 接口中的方法 示例: 定义 ArrayList 和 Iterator 合并: new SequenceInputStream(new Enumeration
(){ public boolean hasMoreElements(){//接口型匿名内部类 return it.hashNext(); } //将迭代结果作为枚举结果,提高效率 public FileInputStream nextElement(){ return it.next(); } }) "序列流" ObjectInputStream & ObjectOutputStream 这两个类必须成对使用 方法: readObject() & writeObject() 为了在下次程序执行时继续使用对象数据,out序列化将对象保存到硬盘,in反序列化从硬盘读取数据 对对象进行序列化(持久化) 与反序列化操作, 被操作的对象所属类需要实现 Serializable "标记接口" 序列化示例: class Person implements Serializable //被操作的对象要实现标记接口 new ObjectOutputStream(new FileOutputStream("obj.txt")).writeObject(person)//对象写入文件 new O