1. 流的分类
java.io
1.1 输入和输出流
File类不能访问文件内容本身,需要使用输入/输出流
输入输出流的方向是相对与内存读写的方向。
1.2 字节流和字符流
- 字节流
- InputSteam
- OutputStream
- 字符流
- Reader
- Writer
- BufferedReader
1.3 节点流和处理流
处理流:
- PrintStream
- FileInputStream
- FileOutputStream
FileOutputStream fos = new FileOutputStream("text.txt");
PrintStream ps = new PrintStream(fos);
ps.println("sdfsdf");
2. 转换流
只有字节流转为字符流。(InputStreamReader, OutputStreamWriter)
InputStreamReader reader = new InputStreamReader(System.in);
BufferedReader br = new BufferedReader(reader);//再次包装
String line = br.readLine();
3. 推回输入流
4. 重定向标准输入/输出
System.setErr(PrintStream err);
System.setIn(InputStream in);
System.setOut(PrintStream out);
5. java虚拟机读写其他进程的数据
InputStream p.getErrorStream();
InputStream p.getInputStream();
Outputstream p.getOutputStream();
Process p = Runtime.getRuntime().exec("javac");
BufferedReader br = new BufferedReader(new InputStreamReader(p.getErrorStream()));
String buff = null;
while((buff = br.readLine()) != null){
System.out.println(buff);
}
Scanner sc = new Scanner(System.in);//用于获取标准输入
6. RandomAccessFile:
只能读写文件,不能读写其他IO节点。可以任意改变指针的位置。当向文件的中间部分插入内容时,会覆盖从指针开始的内容,所以需要先保存从指针到末尾的内。
操作文件记录指针的方法:
- long getFilePointer();
- void seek(long pos);
读写方法
- read()
- write()
RandomAccessFile raf = new RandomAccessFile("AA.java", "r");
raf.seek(300);//指针移到300字节处
7. 对象序列化
类必须实现Serializable和Externalizable接口之一。通常每个javabean都实现Serializable接口。
7.1 使用对象流序列化
ObjectOutputStream、ObjectInputStream
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("object.txt"));
Person per = new Person("name",age);
oos.writeObject(per); ObjectInputStream ois = new ObjectInputStream(new FileInputStream("object.txt"));
Person p = (Person)ois.readObject();
反序列化读取的是java对象的数据,而不是java类,因此反序列化恢复java对象时,必须提供java对象所属的class文件。
反序列化机制无须通过构造器来初始化对象。
一个对象重复序列化时,只有第一次将对象转为字节序列并输出,后续的序列化,都是获得序列化编号。并且,在第一次序列化之后,对象的属性的更改,不会被序列化。
7.2 自定义序列化:
private transient int age;
在序列化之前,先调用writeReplace()再调用writeObject()方法。
反序列化,系统先调用readObject(),再调用readResolve()。后者的返回值,会取代前者的返回结果。后者常常用于序列化单例类和枚举。
对象的类名、实例变量(包括基本类型、数组、对其他对象的引用)都会被序列化;方法、类变量、transient实例变量都不会被序列化。
7.3 Externalizable实现序列化
8. NIO
8.1 Buffer
- CharBuffer
- ByteBuffer
- ShortBuffer
- IntBuffer
- LongBuffer
- FloatBuffer
- DoubleBuffer
Charbuffer和ByteBuffer最常用。
0≤mark≤position≤limit≤capacity
allocate(int count)
flip()
clear()
CharBuffer buff = CharBuffer.allocate(8);
System.out.println("capacity:" + buff.capacity());
System.out.println("limit:" + buff.limit());
System.out.println("position:" + buff.position()); System.out.println("\nput begin:");
buff.put('a');
System.out.println("position = " + buff.position());
buff.put('b');
System.out.println("position = " + buff.position());
buff.put('c');
System.out.println("position = " + buff.position()); System.out.println("\nflip begin:");
buff.flip();
System.out.println("limit=" + buff.limit());
System.out.println("position=" + buff.position()); System.out.println("\nread begin:");
System.out.println(buff.get());
System.out.println("position = " + buff.position());
System.out.println(buff.get());
System.out.println("position = " + buff.position());
System.out.println(buff.get());
System.out.println("position = " + buff.position()); System.out.println("\nclear begin:");
buff.clear();
System.out.println("limit=" + buff.limit());
System.out.println("position=" + buff.position());
8.2 Chanel
程序不能直接访问Channel中的数据,包括读取、写入都不行。只能与buffer交互。
- FileChannel
- DatagramChannel
- Pipe.SinkChannel
- Pipe.SourceChannel
所有的channel都通过节点流的getChannel()方法来返回对象。
channel的方法:
- map()
- read()
- write()
8.3 Charset
public class CharsetTest {
public static void main(String[] args) throws CharacterCodingException{
Charset cn = Charset.forName("GBK");
CharsetEncoder encoder = cn.newEncoder();
CharsetDecoder decoder = cn.newDecoder();
CharBuffer cbuff = CharBuffer.allocate(8);
cbuff.put("孙");
cbuff.put("悟");
cbuff.put("空");
cbuff.flip();
ByteBuffer bbuff = encoder.encode(cbuff);
for(int i=0;i<bbuff.capacity();i++){
System.out.println(bbuff.get(i)+"");
}
System.out.println("\n"+decoder.decode(bbuff));
}
}
8.4 文件锁
- lock()
- tryLock()