今天只是想简单的把常用的IO流简单的总结一下。IO流有一个概念叫通道,何为通道呢,通道就是连接程序与数据源的管道。数据源(可以为硬盘,内存,文件,数据库,网络连接,IO设备,其他程序等),在此管道中传输的是二进制流,也就是01。那么我们以内存为标准,流可以分为输入流和输出流,输入流就是二进制流(00011)流向内存,输出流就是二进制流流向数据源。 那么按读入字节的大小,我们分为字节流与字符流。字节流就是我们每次读出或者写入的以字节为单位,而字符流,我们读出或者写入的单位以字符为单位。
首先以流的输入输出方向为单位分为输入流输出流。在从输入流中读取数据时,我们一般会选择一个合理的缓存容量,比如我们读取的是一副图片,如果把图片分割,那么我们就可以边读i边显示,一般我们把数组的容量定义为
1024字节。
1.输入流的根类按字节来分为InputStream,其常用的子类为文件字节输出流(FileInputStream)。那么我们看看它的一些简单应用:
源代码:
/***
* 功能:测试FileInputStream的常用用法
* FileInputStream 节点流
* 文件字节输入流
* ***/ /** 文件读取的方式一***/
File file=new File("D:/io/1.txt");
try {
FileInputStream fis=new FileInputStream(file);
int b;
//每次返回读取到的一个字节值(流中的8位二进制数),然后将二进制
//转换为int 类型 如果读到文件末尾,返回-1.
while((b= fis.read())!=-1){
System.out.print((char)b);
}
//一般要手动的添加流的关闭,这样可以节约系统的资源。
fis.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
/**文件读取的方式二
方法二的方式一般比方法一的效率高,因为每次读取的字节数多,这样水流就
****/
File file=new File("D:/io/1.txt");
try {
//创建FileInputStream对象,负责和某个文件建立管道(建立流连接)
FileInputStream fis=new FileInputStream(file);
byte []b=new byte[5];
int len=0; //实际一次读取的字节数
String temp;
//将读取的字节放入字节数组
while((len=fis.read(b))!=-1)
{
temp=new String(b,0,len);
System.out.print(temp);
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
2.输出流的根类按字节来分为OutputStream,其常用的子类为文件字节输出流(FileOutputStream)。那么我们看看它的一些简单应用:
/**方法一*/
File file=new File("D:/io/1.txt");
String temp="aaabbbcccddda";
byte[] b=temp.getBytes();
try {
FileOutputStream fos=new FileOutputStream(file);
int off=0;
while(true){
fos.write(b, off, 3);
off+=3;
if(off>b.length-3){
fos.write( b, off, b.length-off);
break;
}
} } catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
3.输入流的根类按字符分为划分为:字符输入流和字符输出流。所谓的字符流就是在流的通道中我们读取的是以字符为单位,数字,字母等占一个字节,汉字占两个字节,因此我们在读字符流实质是读取的也是字节流,但是他们是在字节流的基础上封装了。
/***方法一*/
try {
File file=new File("D:/1.txt");
FileReader read=new FileReader(file);
int ch;
while((ch=read.read())!=-1){ //一次读取的字符数值。
System.out.print((char)ch);
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
/**方法二***/
try {
File file=new File("D:/1.txt");
FileReader read=new FileReader(file);
char ch[]=new char[6];
int len=0; //返回的为读取的字符数
while((len=read.read(ch))!=-1){
System.out.println(len+String.valueOf(ch,0,len));
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//字符输出流
/**功能:实现文件的拷贝
* 1.将1.txt中的文件内容拷贝到
* 2.txt文件中
* ***/
public class testFileReader {
public static void main(String[] args) {
try {
//创建File对象,如果此文件不存在,那么这个内存对象依然存在
//这个对象的创建与文件的有无没关系。
File srcfile=new File("D://1.txt");
File newfile=new File("D://2.txt");
/**创建字符输入流的对象***/
FileReader fileReader=new FileReader(srcfile);
/**创建字符输出流的对象**/
FileWriter fileWrite=new FileWriter(newfile,true);
char ch[]=new char[1024];
//读取的字符数
int length=0;
while((length=fileReader.read(ch))!=-1){
fileWrite.write(ch, 0, length);
}
fileWrite.flush();
// fileWrite.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
//包装流BufferReader和BufferWriter
public class TestBufferRead {
public static void main(String[] args) {
File srcfile=new File("D://1.txt");
File newfile=new File("D://2.txt");
FileReader fileRead;
FileWriter fileWrite;
try {
fileRead = new FileReader(srcfile);
fileWrite=new FileWriter(newfile);
BufferedReader bufferReader=new BufferedReader(fileRead);
BufferedWriter bufferWriter=new BufferedWriter(fileWrite);
String temp;
while((temp=bufferReader.readLine())!=null){
bufferWriter.write(temp);
}
bufferWriter.flush();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
4.对象的序列化与反序列化
/****对象的序列化,这是用对象流的前提
* 如果对象的属性为对象则应该将对象
* 序列化。
* *****/
public class News implements Serializable{
private String title;
private String author;
private Date date;
public News(String title, String author, Date date) {
this.title = title;
this.author = author;
this.date = date;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
}
public class test {
/**
* 功能:
* ObjectInputStream 是建立在其他流的基础上,
* 因此它是处理流,同时要序列化的对象必须实现Serilizele
*
* **/
public static void main(String[] args) {
News car=new News("天津爆炸", "徐财厚", new Date());
try {
FileOutputStream fos=new FileOutputStream(new File("D://io//1.txt"));
//创建对象输出流
ObjectOutputStream oos=new ObjectOutputStream(fos);
oos.writeBoolean(true); //true 自动装箱为对象,Boolean对象实现了序列化
oos.writeObject(car); //对象的序列化
oos.flush();
FileInputStream fis=new FileInputStream(new File("D://io//1.txt"));
//创建对象输入流
ObjectInputStream ois=new ObjectInputStream(fis);
boolean flag=ois.readBoolean(); //对象的反序列化
System.out.println("flag="+flag);
Object obj=ois.readObject();
System.out.println(obj);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
5.字节数组输入流对象ByteArrayInputStream 和 ByteArrayOutputStream字节数组输出流,这个的源和目标的对象在内存。
//这个数组的实现比较特殊,它没有牵扯本地系统调用。
public class TestByteArrayInputStream {
public static void main(String[] args) {
byte srcArray[]={0,1,2};
byte newArray1[]=new byte[3];
byte newArray2[]=new byte[3];
try
{
/**建立字节数组输入流此字节数组输入流指向的为src数组**/
ByteArrayInputStream byteArrayInputStream=
new ByteArrayInputStream(srcArray);
//将通道中的数据读入newArray1中的数组
byteArrayInputStream.read(newArray1);
/**建立字节数组输出流**/
ByteArrayOutputStream byteArrayOutPutStream=
new ByteArrayOutputStream();
//将src中的数据重新拷贝到新的数组中,也就是
//ByteArrayOutPutStream中封装的数组,
byteArrayOutPutStream.write(srcArray);
//然后又在内存创建一个副本将此数组的地址重新传递到newArray2中
newArray2=byteArrayOutPutStream.toByteArray();
System.out.println(Arrays.toString(newArray2));
System.out.println(Arrays.toString(newArray1));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}