------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
上一遍文章中分别说完了字符流和字节流的常见读写方式。
这次我们来说说IO中的其他流。
1、转换流InputStreamReader和OutputStreamWriter
转换流顾名思义就是把字节流转换成字符流再进行操作。可指定编码表。
例:将输入的信息转成大写打印到屏幕上。
class Demo
{
public static void main(String[] args) throws IOException
{
//获取键盘录入对象。
// InputStream in=System.in;
//将字节流对象转成字符流对象,要使用转换流,InputStreamReader
// InputStreamReader isr=new InputStreamReader(in);
//为了提高效率,将字符串进行缓冲区技术高校操作。使用BufferedReader
// BufferedReader bufr=new BufferedReader(isr);
//键盘录入的最常见写法
BufferedReader bufr=new BufferedReader(new InputStreamReader(System.in));
// OutputStream out=System.out;
// OutputStreamWriter osw=new OutputStreamWriter(out);
// BufferedWriter bufw=new BufferedWriter(osw);<pre name="code" class="java">
BufferedWriter bufw=new BufferedWriter(new OutputStreamWriter(System.out));String line=null;while((line=bufr.readLine())!=null){if("over".equals(line))break;bufw.write(line.toUpperCase());bufw.newLine();bufw.flush();}bufr.close();bufw.close();}}
打印流:该流提供了打印方法,可以将各种数据类型的数据都原样打印。
字节打印流:PrintStream
构造函数可以接受的参数类型:
1.file对象。File
2.字符串路径。String
3.字节输出流。OutputStream
字符打印流:PrintWriter
构造函数可以接受的参数类型:
1.file对象。File
2.字符串路径。String
3.字节输出流。OutputStream
4.字符输出流。Writer。
例:将输入的信息打印到文件中。
class Demo
{
public static void main(String[] args) throws IOException
{
BufferedReader bufr=new BufferedReader(new InputStreamReader(System.in));
PrintWriter out=new PrintWriter(new FileWriter("a.txt"),true);
String line=null;
while((line=bufr.readLine())!=null)
{
if("over".equals(line))
break;
out.println(line.toUpperCase());
// out.flush();
}
out.close();
bufr.close();
}
}
3、合并流SequenceInputStream
将多个流中合并成为一个流。
例:将3个文件中的内容打印到一个文件中。
class Demo
{
public static void main(String[] args) throws IOException
{
Vector<FileInputStream> v=new Vector();
v.add(new FileInputStream("1.txt"));
v.add(new FileInputStream("2.txt"));
v.add(new FileInputStream("3.txt"));
Enumeration<FileInputStream> en=v.elements();
SequenceInputStream sis =new SequenceInputStream(en);
FileOutputStream fos=new FileOutputStream("4.txt");
byte[] buf=new byte[1024];
int len=0;
while((len=sis.read(buf))!=-1)
{
fos.write(buf,0,len);
}
fos.close();
sis.close();
}
}
4、对象流ObjectInputStream和ObjectOutputStream
需要被对象流操作的对象必须实现Serializable接口。
只有这样才可以被序列化。
类中的静态成员和被transient修饰的成员不可以被序列化。
当对象被存储到文件中之后,不应对类进行修改,如果修改,可能会导致无法读取对象。
class Demo
{
public static void main(String[] args) throws Exception
{
readObj();
// writeObj();
}
public static void readObj() throws Exception
{
ObjectInputStream ois=new ObjectInputStream(new FileInputStream("obj.txt"));
Person p=(Person) ois.readObject();
System.out.println(p);
}
public static void writeObj() throws IOException
{
ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("obj.txt"));
oos.writeObject(new Person("lisi",39,"kr"));
oos.close();
}
}
class Person implements Serializable//标记接口,可序列化
{
static final long serialVersionUID =42L;
private String name;
transient private int age;//transient关键字,不被序列化
static String country="cn";//静态不能序列化
Person(String name, int age,String country)
{
this.name = name;
this.age = age;
this.country=country;
}
public String toString()
{
return "name=" + name + ", age=" + age+ ", country=" + country;
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public int getAge()
{
return age;
}
public void setAge(int age)
{
this.age = age;
}
}
5、管道流PipedInputStream和PipedOutputStream
如果要形成管道就要把输入流和输出流连接上,因此管道流往往成双出现。
class Demo
{
public static void main(String[] args) throws IOException
{
PipedInputStream in=new PipedInputStream();
PipedOutputStream out=new PipedOutputStream();
in.connect(out);
Read r=new Read(in);
Write w=new Write(out);
new Thread(r).start();
new Thread(w).start();
}
}
class Read implements Runnable
{
private PipedInputStream in;
Read(PipedInputStream in)
{
this.in=in;
}
public void run()
{
try
{
byte[] buf=new byte[1024];
int len=0;
System.out.println("读取前,没有数据。");
while((len=in.read(buf))!=-1)
{
System.out.println("读到数据。");
System.out.println(new String(buf,0,len));
}
in.close();
}
catch(IOException e)
{
throw new RuntimeException("管道读取流失败");
}
}
}
class Write implements Runnable
{
private PipedOutputStream out;
Write(PipedOutputStream out)
{
this.out=out;
}
public void run()
{
try
{
System.out.println("写入前,等待6秒。");
Thread.sleep(6000);
out.write("piped lai le".getBytes());
out.close();
}
catch(Exception e)
{
throw new RuntimeException("管道输出流失败");
}
}
}
6、RandomAccessFile
它与其他流不同,它直接继承自Object,不属于IO体系中的子类。并且它可以一个人完成读写操作。
它的内部封装了一个数组,而且通过指针队数组的元素进行操作。
可以通过getFilePointer获取指针位置,同时可以通过seek改变指针的位置。
class Demo
{
public static void main(String[] args) throws IOException
{
// WriterFile();
// readFile();
WriterFile_2();
}
public static void readFile() throws IOException
{
RandomAccessFile raf=new RandomAccessFile("ran.txt","r");
//调整对象中指针。
// raf.seek(8*1);
//跳过指定的字节数
raf.skipBytes(8);
byte[] buf =new byte[4];
raf.read(buf);
String s=new String(buf);
int age=raf.readInt();
System.out.println(s+"::"+age);
raf.close();
}
public static void WriterFile_2() throws IOException
{
RandomAccessFile raf=new RandomAccessFile("ran.txt","rw");
raf.seek(8*0);
raf.write("周期".getBytes());
raf.writeInt(103);
raf.close();
}
public static void WriterFile() throws IOException
{
RandomAccessFile raf=new RandomAccessFile("ran.txt","rw");
raf.write("李四".getBytes());
raf.writeInt(97);
raf.write("王五".getBytes());
raf.writeInt(99);
raf.close();
}
}
7、DataInputStream与DataOutputStream
DataInputStream与DataOutputStream是用于操作基本数据类型的流对象
class Demo
{
public static void main(String[] args) throws IOException
{
// WriterData();
// readData();
// writeUTFDemo();
readUTFDemo();
}
public static void readUTFDemo() throws IOException
{
DataInputStream dis=new DataInputStream(new FileInputStream("utf.txt"));
String s=dis.readUTF();
System.out.println(s);
dis.close();
}
public static void readData() throws IOException
{
DataInputStream dis=new DataInputStream(new FileInputStream("data.txt"));
int num=dis.readInt();
boolean b=dis.readBoolean();
double d=dis.readDouble();
System.out.println(num);
System.out.println(b);
System.out.println(d);
}
public static void writeUTFDemo() throws IOException
{
DataOutputStream dos=new DataOutputStream(new FileOutputStream("utf.txt"));
dos.writeUTF("您好");
dos.close();
}
public static void WriterData() throws IOException
{
DataOutputStream dos=new DataOutputStream(new FileOutputStream("data.txt"));
dos.writeInt(234);
dos.writeBoolean(true);
dos.writeDouble(9887.543);
dos.close();
}
}
8、ByteArrayInputStream和ByteArrayOutputStream
用于操作字节数组的流对象。
ByteArrayInputStream:在构造的时候,需要接受数据源,而且数据源是一个字节数组。
ByteArrayOutputStream:在构造的时候,不用定义数据目的,因为该对象中已经内部封装了一个可变长度的字节数组。
因为着两个流对象都操作的是数组,并没有使用系统资源,所以,不用进行close关闭。
class Demo
{
public static void main(String[] args)
{
//数据源
ByteArrayInputStream bis=new ByteArrayInputStream("abcdefg".getBytes());
//数据目的
ByteArrayOutputStream bos=new ByteArrayOutputStream();
int by=0;
while((by=bis.read())!=-1)
{
bos.write(by);
}
System.out.println(bos.size());
System.out.println(bos.toString());
// bos.writeTo(new FileOutputStream("array.txt"));
}
}