---------------------- ASP.Net+Android+IO开发S、.Net培训、期待与您交流! ----------------------
PrintWriter打印流
PrintStream与PrintWriter
可以直接操作输入流和文件。
打印流:
该流提供了打印方法,可以将各种数据类型的数据都原样打印。
字节打印流:
PrintStream
构造函数可以接收的参数类型:
1.file对象:File
2.字符串路径:String
3.字节输出流;OutputStream
字符打印流:(使用较多)
PrintWriter
构造函数可以接收的参数类型:
1.file对象:File
2.字符串路径:String
3.字节输出流;OutputStream
4.字符输出流:Writer
/*
PrintWriter
构造函数可以接收的参数类型:
1.file对象:File
2.字符串路径:String
3.字节输出流;OutputStream
4.字符输出流:Writer
*/
import java.io.*;
class PrintStreamDemo{
public static void main(String[] args)throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
//true是自动刷新
PrintWriter pw = new PrintWriter(System.out,true);
//将文件保存到a.txt
//PrintWriter pw = new PrintWriter(newFileWriter("a.txt"),true);
String line = null;
while((line = br.readLine())!=null){
if("over".equals(line)||"OVER".equals(line))
break;
pw.println(line.toUpperCase());
}
pw.close();
br.close();
}
}
SequenceInputStream 序列流
SequenceInputStream 对多个流进行合并。
import java.io.*;
import java.util.*;
class SequenceDemo{
public static void main(String[] args)throws IOException{
Vector<FileInputStream> v = new Vector<FileInputStream>();
v.add(new FileInputStream("1.txt"));
v.add(new FileInputStream("2.txt"));
v.add(new FileInputStream("3.txt"));
//得到Enumeration类型的数据
Enumeration<FileInputStream> en = v.elements();
//传入Enumeration类型参数
SequenceInputStream sis = new SequenceInputStream(en);
BufferedReader br = new BufferedReader(new InputStreamReader(sis));
//建立写入缓冲区并与文件关联
BufferedWriter bw = new BufferedWriter(new FileWriter("4.txt"));
String line = null;
while((line=br.readLine())!=null){
bw.write(line);
bw.newLine();
}
//关闭资源
bw.close();
br.close();
}
}
mp3文件的切割以及切割后的还原。
import java.io.*;
import java.util.*;
class SplitDemo{
public static void main(String[] args)throws IOException{
splitMethod();
mergeMethod();
}
//切割文件的功能
public static void splitMethod()throws IOException{
//建立文件与输入字节流的关联
FileInputStream fis = new FileInputStream("Sagyman.mp3");
FileOutputStream fos = null;
byte[] buf = new byte[1024*1024];
int len = 0;
int count = 1;
//将指定大小的字节写入指定文件。
while((len=fis.read(buf))!=-1){
fos = new FileOutputStream("Sagyman"+(count++)+".part");
fos.write(buf,0,len);
//关闭资源
fos.close();
}
//关闭资源
fis.close();
}
//合并文件的功能
public static void mergeMethod()throws IOException{
//关联文件碎片
ArrayList<FileInputStream> a = new ArrayList<FileInputStream>();
a.add(new FileInputStream("Sagyman1.part"));
a.add(new FileInputStream("Sagyman2.part"));
a.add(new FileInputStream("Sagyman3.part"));
a.add(new FileInputStream("Sagyman4.part"));
//得到Enumeration类型的数据
final Iterator<FileInputStream> it = a.iterator();
Enumeration<FileInputStream> en = new Enumeration<FileInputStream>(){
public boolean hasMoreElements(){
return it.hasNext();
}
public FileInputStream nextElement(){
return it.next();
}
};
//使用SequenceInputStream流,并传入Enumeration参数
SequenceInputStream sis = new SequenceInputStream(en);
FileOutputStream fos = new FileOutputStream("Sgyman1.mp3");
//将字节输入流写入到字节输出流
int len = 0;
byte[] buf = new byte[1024];
while((len=sis.read(buf))!=-1){
fos.write(buf,0,len);
}
fos.close();
sis.close();
}
}
上面的程序执行splitMethod();后
上面的程序执行mergeMethod();后
操作对象
ObjectInputStream与ObjectOutputStream
被操作的对象需要实现Serializable接口(该接口没有任何方法,只是一个标记接口)
若对象要被序列化,必须实现Serializable接口。
1.只有存在与堆内存中的数据才能被序列化
2.private String name ;//堆内存中的属性,可以被序列化
3.transient int age; //虽然在堆内存中,但有transient关键字修饰,无法被序列化
4.static String country = "cn";//静态属性在共享区(方法区也叫静态区),无法被序列化
要实现序列化的类
import java.io.*;
//若对象要被序列化,必须实现Serializable接口。
class Person implements Serializable{
public static final long serialVersionUID = 42L;
//只有存在与堆内存中的数据才能被序列化
private String name ;//堆内存中的属性,可以被序列化
transient 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+":"+age+":"+country;
}
}
序列化操作:
import java.io.*;
class ObjectStreamDemo{
public static void main(String[] args)throws Exception{
readObj();
}
public static void writeObj()throws IOException{
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("person.object"));
//向文件写入一个序列化的对象
oos.writeObject(new Person("zhangsan",12,"en"));
oos.close();
}
public static void readObj()throws Exception{
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("person.object"));
//从文件读一个序列化对象
Person p = (Person)ois.readObject();
System.out.println(p);
ois.close();
}
}
管道流
PipedInputStream和PipedOutputStream
输入输出可以直接进行连接,通过结合线程使用
数据由某个线程从PipedInputStream对象读取,并由其他线程将其写入相应的PipedOutStream中。
不建议使用单线程,这样会出现死锁现象。 管道输入流包含一个缓冲区,可在缓冲区规定的范围内将
读操作和写操作分离开。如果向连接管道输出流提供数据字节的线程不再存在,那么这个管道流已经损坏。
class Read implements Runnable {
private PipedInputStream in;
Read(PipedInputStream in){
this.in = in;
}
public void run(){
try
{
byte[] buf = new byte[1024];
int len = in.read();
String s = new String(buf,0,len);
System.out.println(s);
in.close();
}
catch (Exception e)
{
throw new RuntimeException("管道读取流失败");
}
}
}
class Write implements Runnable {
private PipedOutputStream out;
Write(PipedOutputStream out){
this.out = out;
}
public void run(){
try
{
out.write("piped is come".getBytes());
out.close();
}
catch (Exception e)
{
throw new RuntimeException("管道读取流失败");
}
}
}
RandomAccessFile
该类不算是IO体系中子类。
而是直接继承自object。
但是它是IO包中的成员。因为它具备读和写的功能。
内部封装了一个数组,而且通过指针对数组的元素进行操作。
可以通过getFilePointer获取指针位置,
同时可以通过seek改变指针的位置。
其实完成读写的原理就是内部封装了字节输入流和输出流。
通过构造函数可以看出,该类只能操作文件。
而且操作文件还有模式:只读r,读写rw等。
如果模式为只读r,不会创建文件。会失去读取一个已存在文件,如果该文件不存在,则会出现异常。
如果模式rw,操作的文件不存在,会自动创建;如果文件存在,不会覆盖文件内容。
import java.io.*;
class RandomAccessFileDemo{
public static void main(String[] args)throws IOException{
//readFile();
writeFile();
}
public static void readFile()throws IOException{
RandomAccessFile raf = new RandomAccessFile("raf.txt","r");
byte[] buf = new byte[4];
//将指定内容输入字符数组
raf.read(buf);
String name = new String(buf);
int age = raf.readInt();
System.out.println("name:"+name);
System.out.println("age:"+age);
}
public static void writeFile()throws IOException{
RandomAccessFile raf = new RandomAccessFile("raf.txt","rw");
raf.write("李四".getBytes());
raf.writeInt(97);
raf.write("武大".getBytes());
raf.writeInt(101);
//调整对象中的指针
raf.seek(8*5);
raf.write("本山".getBytes());
raf.writeInt(110);
//跳过指定的字节数
raf.skipBytes(8);
raf.write("笨蛋".getBytes());
raf.writeInt(110);
raf.close();
}
}
数据操作。
操作基本数据类型
DataInputStream与DataOutputStream。参见文档
操作字节数组
ByteArrayInputStream与ByteArrayOutputStream
用于操作字节数组的流对象
ByteArrayInputStream:在构造的时候,需要接收数据源。而且数据源是一个字节数组。
ByteArrayOutputStream:在构造的时候,不用定义数据目的,因为该对象中已经内部封装了可变长度的字节数组,这就是数据目的地。
因为这两个流对象都操作的数组,并没有使用系统资源。所以不用进行close关闭。
在流规律讲解时:
源设备:键盘(System.in)、硬盘(FileStream)、内存(ArrayStream)
目的设备:控制台(System.out)、硬盘(FileStream)、内存(ArrayStream)
用流的思想操作数组。
import java.io.*;
class ByteArrayStream{
public static void main(String[] args){
ByteArrayInputStream bis = new ByteArrayInputStream("ABCDA".getBytes());
ByteArrayOutputStream bos = new ByteArrayOutputStream();
int by = 0;
while((by=bis.read())!=-1){
System.out.println(by);
bos.write(by);
}
System.out.println(bos.size());
System.out.println(bos);
//可设置输出目的。要处理异常。
//bos.writeTo(System.out);
}
}
以下两种实现方式与操作字节数组类似,详细参考文档。
操作字符数组
CharArrayReader与CharArrayWriter
操作字符串
StringReader与StrinWriter
---------------------- ASP.Net+Android+IOS开发、.Net培训、期待与您交流! ----------------------
详情请查看:http://edu.csdn.net