说明:其实这几个流都不怎么熟悉,一关帮助文档,有的流名字都写不全。
一,打印流PrintWrite
构造函数:
PrintWriter(File file) 使用指定文件创建不具有自动行刷新的新 PrintWriter。 |
PrintWriter(File file, String csn) 创建具有指定文件和字符集且不带自动刷行新的新 PrintWriter。 |
PrintWriter(OutputStream out) 根据现有的 OutputStream 创建不带自动行刷新的新 PrintWriter。 |
PrintWriter(OutputStream out, boolean autoFlush) 通过现有的 OutputStream 创建新的 PrintWriter。当autoFlush为true时,自动刷新。 |
PrintWriter(String fileName) 创建具有指定文件名称且不带自动行刷新的新 PrintWriter。 |
PrintWriter(String fileName, String csn) 创建具有指定文件名称和字符集且不带自动行刷新的新 PrintWriter。 |
PrintWriter(Writer out) 创建不带自动行刷新的新 PrintWriter。 |
PrintWriter(Writer out, boolean autoFlush) 创建新 PrintWriter。当autoFlush为true时,自动刷新。 |
类中支持自动刷新的方法:
println、printf 或 format
示例:
import java.io.*;
public class Test {
public static void main(String[] args) throws IOException{
BufferedReader bufr=new BufferedReader(new InputStreamReader(System.in));
PrintWriter out=new PrintWriter(new FileWriter("asd.txt"),true);
String line=null;
while((line=bufr.readLine())!=null){
out.println(line);//本方法带有换行功能
//out.flush();此时不需要手动刷新
if("over".equals(line))
break;
}
bufr.close();
out.close();
}
}
二,合并流SequenceInputStream
构造函数:
SequenceInputStream(Enumeration<? extends InputStream> e) 通过记住参数来初始化新创建的 SequenceInputStream ,该参数必须是生成运行时类型为 InputStream 对象的Enumeration 型参数。 |
SequenceInputStream(InputStream s1, InputStream s2) 通过记住这两个参数来初始化新创建的 SequenceInputStream (将按顺序读取这两个参数,先读取 s1 ,然后读取 s2 ),以提供从此 SequenceInputStream 读取的字节。 |
示例;
将多个文件中的内容通过合并流合并到一个文件中.
import java.io.*;
import java.util.*;
public class Test {
public static void main(String[] args) throws IOException{
//创建Vector集合
Vector<FileInputStream> v=new Vector<FileInputStream>();
//为集合添加流
v.add(new FileInputStream("111.txt"));
v.add(new FileInputStream("222.txt"));
v.add(new FileInputStream("333.txt"));
//创建集合的迭代
Enumeration<FileInputStream> e=v.elements();
//常见合并流
SequenceInputStream sis=new SequenceInputStream(e);
FileOutputStream fos = new FileOutputStream("444.txt");
byte[] buf = new byte[1024];
int len =0;
while((len=sis.read(buf))!=-1)
{
fos.write(buf,0,len);
}
fos.close();
sis.close();
}
}
扩展:分割文件.
import java.io.*;
public class Test {
public static void main(String[] args) throws IOException{
FileInputStream fis=new FileInputStream("111.jpg");
byte[] buf=new byte[1024*30];
int num=0;
int len;
while((len=fis.read(buf))!=-1){
FileOutputStream fos=new FileOutputStream((num++)+".jpg");
fos.write(buf,0,len);
fos.close();
}
fis.close();
}
}
三,Properties类
常见方法:
----setProperty(String key,String value);
为集合添加键值对;
---getProperty(String key)
获取指定键的值;
---stringPropertyNames()
获取集合中键集;
----load(InputStream inStream)
从输入流中读取属性列表;
----load(Reader reader)
从输入字符流中读取属性列表;
----store(OutputStream out,String comments)
将此 Properties
表中的属性列表(键和元素对)写入输出流。
----store(Writer writer,String comments)
将此 Properties
表中的属性列表(键和元素对)写入输出字符。
import java.io.*;
import java.util.Properties;
public class Test {
public static void main(String[] args) throws IOException{
//创建输入流
FileInputStream fis=new FileInputStream("info.txt");
//创建属性集合
Properties prop=new Properties();
//关联输入流
prop.load(fis);
//设置属性集
prop.setProperty("111", "aaa");
prop.setProperty("222", "bbb");
prop.list(System.out);
//创建输出流
FileOutputStream fos=new FileOutputStream("info.txt");
//属性集关联输出流
prop.store(fos, "test");
fis.close();
fos.close();
}
}
四,对象的序列化
ObjectInputStream构造函数:
ObjectInputStream(InputStream in)
创建从指定 InputStream 读取的 ObjectInputStream。
ObjectOutputStream构造函数:
ObjectOutputStream(OutputStream out)
创建写入指定 OutputStream 的 ObjectOutputStream。
特有方法:
readObject() 用于从流读取对象;
writeObject()用于将对象写入流中;
序列化的实现:
将需要被序列化的类实现Serializable接口,该接口没有需要实现的方法,implements Serializable只是为了标注该对象是可被序列化的。
注:static静态、transient临时
被以上两个修饰符修饰成员不能被序列化,
示例:对象序列化
<span style="font-size:12px;">import java.io.*;
public class Test {
public static void main(String[] args) throws IOException, ClassNotFoundException{
ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("Per.txt"));
oos.writeObject(new Person("aaa",11,"Kr"));
}
}
class Person implements Serializable{
//可以通过自定义UID来标记类
//static final long serialVersionUID = 42L;
private int age;
private String name;
static String country="CN";
Person(String name,int age,String country){
this.name=name;
this.age=age;
this.country=country;
}
public String getName(){
return name;
}
public int getAge(){
return age;
}
public String toString(){
return name+"--"+age+"--"+country;
}
}</span>
示例:反序列化
<span style="font-size:12px;">import java.io.*;
public class Test {
public static void main(String[] args) throws IOException, ClassNotFoundException{
ObjectInputStream ois=new ObjectInputStream(new FileInputStream("Per.txt"));
Person p=(Person)ois.readObject();
System.out.println(p);
}
}</span>
五,管道流
PipedOutputStream:管道输出流。
PipedInputStream:管道输入流。
方法:
连接管道输入流和输出流
connect(PipedOutputStream pos)
connect(PipedInputStream pis)
管道流通常与多线程结合,数据由某个线程从PipedInputStream对象读取,并由其他线程将其写入到相应的PipedOutputStream对象。不建议对这两个对象使用单个线程,因为这样可能造成死锁。
import java.io.*;
public class Test {
public static void main(String[] args) throws IOException, ClassNotFoundException{
PipedInputStream pis=new PipedInputStream();
PipedOutputStream pos=new PipedOutputStream();
//连接管道输出流和输入流
pis.connect(pos);
Read r=new Read(pis);
Write w=new Write(pos);
//创建多线程
Thread t1=new Thread(r);
Thread t2=new Thread(w);
t1.start();
t2.start();
}
}
//将PipedInputStream封装到线程
class Read implements Runnable{
private PipedInputStream pis;
Read(PipedInputStream pis){
this.pis=pis;
}
public void run(){
try {
System.out.println("等待读取数据");
byte[] buf=new byte[1024];
int len;
while((len=pis.read(buf))!=-1){
System.out.println("读取数据完毕");
System.out.println(new String(buf));
}
pis.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
//将PipedOutputStream封装到线程
class Write implements Runnable{
private PipedOutputStream pos;
Write(PipedOutputStream pos){
this.pos=pos;
}
public void run(){
try {
System.out.println("请等待");
Thread.sleep(4000);
String str="hello,java";
pos.write(str.getBytes());
pos.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
六,RandomAccessFile类
该类不算是IO体系中的子类,而是直接继承Object,但它是IO包成员,因为它具备读写功能,内部封装了一个数组,且通过指针对数组的元素进行操作,同时可通过seek改变指针的位置。
该类支持对随机访问文件的读写。自身具备读写方法。随机访问文件的行为类似存储在文件系统中的一个大型byte数组。存在指向该隐含数组的光标或索引,称为文件指针,该文件指针可以通过 getFilePointer 方法读取,并通过 seek 方法设置。
输入操作从文件指针开始读取字节,并随着对字节的读取而前移此文件指针。如果随机访问文件以读取/写入模式创建,则输出操作也可用。
输出操作从文件指针开始写入字节,并随着对字节的写入而前移此文件指针。写入隐含数组的当前末尾之后的输出操作导致该数组扩展。
构造函数;
RandomAccessFile(File file,String mode):
RandomAccessFile(String name,String mode):
创建从中读取和向其中写入(可选)的随机访问文件流;
注:
如果模式为r(只读),则实例化对象时不会创建文件,会去读取一个已经寻在的文件,如果该文件不存在,则会包异常。
如果模式为rw,而构造函数中文件不存在,会走动创建,如果该文件已存在,则不会覆盖。
特有方法;
---getFilePointer();
获取指针位置
---seek(long pos):
设置指针位置
---skipBytes(int s):
指针跳过s个直接位置。如果是为负数,不跳过任何字节,即该方法只会向后跳跃。
public class Test {
public static void main(String[] args) throws IOException, ClassNotFoundException{
RandomAccessFile raf=new RandomAccessFile("77.txt", "rw");
//raf.writeInt(123);
//raf.write("asdfgh".getBytes());
//获取指针位置
long pointer=raf.getFilePointer();
System.out.println("pointer:"+pointer);
//设置指针位置
raf.seek(0);
int num=raf.readInt();
System.out.println("num:"+num);
//跳过2个字节
raf.skipBytes(2);
System.out.println((char)raf.read());
raf.close();
}
}