输入输出流-缓冲流,过滤流,包装流
JAVA中的IO分类
可以分为输入/输出流,还可以分为字节流和字符流,还可以分为基础流和过滤流,可以根据自己的需要使用。一般的应用使用过滤流(实际上是功能增强的流)的时候比较多
应用程序对不同的外部设备操作所使用的流类的对象是不同的。针对不同外部设备操作所使用的流的过程中全部都是:InputStream ,Reader, OutputStream, Writer的子类。
分类:节点流,缓冲流(过滤流),序列化,包装流,随机访问文件流
节点流:运行速度慢安全系数低
缓冲流:运行速度快安全系数高
Java.io包封装了一系列有关输入输出的的技术。
IPO----------I(输入)-P(信息处理,应用程序)-O(输出) 顺序的读写
输入设备:(数据源)磁盘/键盘/内存,读取磁盘上的文件。
a. txt文件中保存了用户名和密码,应用程序可以直接从磁盘上读取文件,和用户输入的对比,看用户输入的是否正确。正确就成功登录。
b. 数据库
输出设备:(数据宿)数据库/磁盘中的文件(存入磁盘)/内存/标准:a.显示器
数据源:数据的来源,应用程序从数据源中读取数据。
数据宿:存放数据的地方,应用程序可以把数据写到数据宿中
流:JAVA的应用程序和外部设备(输入设备和输出设备)进行交互,对数据的传输是通过流这种技术来完成的,它内部所流的数据是字节(byte)或字符(char)的格式。也叫缓冲内存。
流的优点:减少数据存储的复杂性。??
按方向分:
输入流:(读流)应用程序从输入设备中读取数据所使用的流。
输出流:(写流)应用程序要把数据写入到输出设备中。
输出设备O |
应用程序P |
输入设备I |
读流 写流 可以看作人在抄写并修改一本书 |
流操作的对象:文件,数据库,内存,打印机等:
用文件为例讲解输入输出流;
文件的输入输出流:
把文件作为对象来处理,多个文件为一个类,
java.io.File类:
File构造方法摘要 |
File(File parent, String child) File f1=new (f,”a.txt”)//f与f1放在一起是个完整路径。 根据 parent 抽象路径名和 child 路径名字符串创建一个新 File 实例。 |
文件所在磁盘的完整路径。File f=new File(“c://a.txt”) 通知jvm想要在c://a.txt创建f这个对象; 通过将给定路径名字符串转换成抽象路径名来创建一个新 File 实例。 |
File(String parent, String child)
根据 parent 路径名字符串和 child 路径名字符串创建一个新 File 实例。 |
传输协议:ftp:和http: |
方法摘要 | |
boolean | createNewFile( ) //在指定的磁盘路径下面,创建新的空文件 File f=new File(“c://ada.txt”); f.createNewFile( ); |
boolean | delete()//删除指定目录上的文件。
|
boolean | exists( ) //文件在指定的磁盘目录下面是否存在 File f=new File("c://aba.txt");
if(f.exists( )) { f.delete( ); }
else f.createNewFile( ) |
boolean | isDirectory( ) 判断对象是否为目录 |
例:File方法练习
import java.io.*;
class d
{
public static void main(String args[ ])throws IOException
{
File f=new File("c://ada.txt");
f.createNewFile( );
System.out.println (f.getParent( ));//c:/
System.out.println (f.getPath( )); //c:/ada.txt路径
System.out.println (f.toString( ));//c:/ada.txt
System.out.println (f.isAbsolute( ));//true 决对路径完整路径
System.out.println (f.length( ));//0文件的长度
System.out.println (f.mkdir( ));//false
System.out.println (f.lastModified( ));//最后一次修改的时间
File f1=new File("c:/ss");
f1.mkdir( );//创建当前目录的子目录ss
System.out.println (f1.isDirectory( ));//true是否为目录
System.out.println (f.isDirectory( ));//flase是否为目录
System.out.println (f.isFile( ));//true是否为文件
System.out.println (f1.isFile( ));//false是否为文件
System.out.println (f.canRead( ));//true是否可读,默认即可读也可写
System.out.println (f.setReadOnly( )+"只读成功设置");
System.out.println (f.canWrite( ));//true是否可写
System.out.println (f.isHidden( ));//false是否隐藏
System.out.println (f.getName( ));//ada.txt
System.out.println (f1.list( ));//null返回目录下的文件及子目录名列表??
File f3=new File("c://adss.txt");
f.renameTo(f3);//ada.txt--adss.txt更名
}
}
作业:在c:/创建xxx.java文件,判断该文件日不是只读文件,f.canRead( ),f.canWrite,
将其转换成只读,记录最后的修改时间。将原有的文件夹,改名为yyy,java
JAVA流总图:
| InputStream类 | 字节读流 | 输入流 |
Object超类 | Reader类 | 字符读流 |
|
OutputStream类 | 字节写流 | 输出流 | |
| Writer类 | 字符写流 |
|
应用程序对不同的外部设备操作所使用的流类的对象是不同的。针对不同外部设备操作所使用的流的过程中全部都是:InputStream ,Reader, OutputStream, Writer的子类。
分类:节点流,缓冲流,序列化,随机访问文件流
节点流:应用程序和外部设备直接进行交互,所使用的流叫节点流。
特点:在JAVA中,只有节点流才能直接与目标设备进行交互;
p159
节点流总表:
节点类型 | 字符流 | 字节流 |
Merry基本流的7个子类 | CharArrayReader 应用程序和内存建立连接所使用的输入流,内所流的为“字符” CharArrayWriter 应用程序和内存建立连接所使用的输出流,内所流的为“字符” | ByteArrayInputStream
ByteArrayOutpputStream |
String Reder 应用程序和内存建立连接所使用的输入流,内所流的为“字符串” String Writer | StringBufferInputStream | |
| ||
Pipe
| PipedReader PipedWriter | PipedInputStream PipedOutPutStream |
File 基本流的4 个子类 | FileReader类 FileWriter类 | FileInputStream类 FileOutputStream类 |
在java语言中,不同的流类创建了一系列的read()y方法,或是read的重载。
创建输入流的三个步骤:
1,打开数据流: | 实例化(FileReader流类)或FileInputStream流类的对象。 |
2,读数据: | 用流类对象调用read(byte[ ]b) |
3, 关闭数据流, | 调用close( ) |
创建输出流的三个步骤:
1,打开数据流: | 实例化FileOutputStream流类的对象。 |
2,写数据: | 调用write( ) |
3, 关闭数据流, | 调用close( ) |
问题:FileInputStream流里面为字节,如果想调用write( )写的过程之前,一定要将数据类型转换字节类型。多个字符转为一个字节数据
例:在c:/创建yy.txt文件并将String s=” ”写入yy.txt
import java.io.*;
class aa
{
public static void main(String args[ ])throws IOException
{
FileOutputStream f=new FileOutputStream("c://yy.txt");
String s="abcde4543543rtetrewf";
f.write(s.getBytes( ));
f.close( );
//yy.txt写到zz.txt
FileInputStream f2=new FileInputStream("c://yy.txt");
byte b[ ]=new byte[f2.available( )];
f2.read(b);
f2.close( );
FileOutputStream f1=new FileOutputStream("c://zz.txt");
f1.write(b);
f1.close( );
}
}
例:在c:/建一个jqpx.txt文件,内容为www.jqpx.com
import java.io.*;
class aa
{
public static void main(String args[ ])throws IOException
{
String s="www.jqpx.com";
FileOutputStream fis=new FileOutputStream("c:/jqpx.txt");
byte[ ]b=s.getBytes( );
fis.write(b);
//f.write(s.getBytes( ));
fis.close( );
FileInputStream fis1 =new FileInputStream("c:/jqpx.txt");//读流x.txt的所有字节,
byte[ ]buf=new byte[fis1.available( )];//available( )判断可读入的数据
int i=fis1.read(buf);//将fis1中数据读入到字节数组buf中,并返回读入的字节数。p160
System.out.println (i);
fis1.close( );
System.out.println (new String(buf));
}
}
作业:
import java.io.*;
class aa
{
public static void main(String args[ ])throws IOException
{
File f=new File("c://xxx.java");
File f2=new File("c://yyy.java");
f.createNewFile( );
if(f.canWrite( )&&f.canRead( ))//是不可写读
{
f.setReadOnly( );
long n= f.lastModified( );//
System.out.println (n);
// File f2=new File("c://yyy.java");
f.renameTo(f2);//更名
}
System.out.println ( f.getPath( ));
System.out.println ( f2.getPath( ));
}
}
、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、
例:节点流创建x.txt,从x.txt读入,写入y.txt10次
import java.io.*;
class aa
{
public static void main(String args[ ])throws IOException
{
String s="我是中国人china";
FileOutputStream fis=new FileOutputStream("c:/x.txt");
byte[ ]b=s.getBytes( );
fis.write(b);
//f.write(s.getBytes( ));
fis.close( );
FileInputStream fis1 =new FileInputStream("c:/x.txt");//读流从x.txt
byte[ ]buf=new byte[fis1.available( )];
fis1.read(buf);
fis1.close( );
FileOutputStream fos1=new FileOutputStream("c:/y.txt");//写流到y.txt10次
for(int i=0;i<10;i++)
{
fos1.write(buf);
}
fos1.close( );
}
}
158页:
节点流:
输入输出总是相对你的程序来说的,你要获取信息了,就要找一个inputstream输入到你的程序里,你要输出信息了,就建立一个outputstream输出信息.记住这一点就能以不变应万变,你会发现很多地方java都是这样设计的.
例:创建aba.txt,判断是不存在,如果存在将其删除。
import java.io.*;
class d
{
public static void main(String args[ ]) throws IOException
{
File f=new File("c://aba.txt");
If (f.exists( ))
{
f.delete( );
}
else
f.createNewFile( );
}
}
??import java.io.*;没建
class aa
{
public static void main(String args[ ])throws IOException
{
File f=new File("c://xdx.htm");
FileInputStream fis=new FileInputStream(f);
}
}
public class test
{
public static void main(String[ ] args)
{
int i, j;
for (i = 1; i < 5; i++)
{
for (j = 1; j < i; j++)
{
System.out.println("i=" + i + "..j=" + j);
}
}
}
}
程序完后i循环和J循环执行次数是多少??
import java.io.*;
class aa
{
public static void main(String args[ ])throws IOException
{
FileInputStream fis=new FileInputStream("c:/jqpx.txt");
byte [ ]buf=new byte[fis.available( )];
int i=fis.read(buf);
fis.close( );
System.out.println (new String(buf));
}
}
…………………
缓冲流(过滤流),包装流
2007年5月19日星期六
l 节点流是主要的流,过滤流是起装饰作用的,经过过滤流装饰后的流具有主要流和装饰流的双重功能.装饰模式!decorate!
l 过滤流又称为包装流 是用来包装字节流 来实现双缓冲的,还有的时候,无法对字节流进行直接操作,就需要包装流来包装一下
l 字节流和字符流: (流共有属性)
对于纯文本文件的读取操作一般就用字符流!对于二进制数据(如声音,音频)和非txt文件则用字节流!
对于字符流,不同的存储方式:chararray,string,file,pipe,特殊处理:buffered,filter
对于字节流,不同的存储方式:bytearray,file,stringbuffer,pipe,特殊处理:buffered, filter buffered和filter是用来配合“负责不同数据存储方式的类”使用的!
其中最常用的是buffered
节点流:运行速度慢,安全系数不高,从特定的地方读写的流类,例如:磁盘或一块内存区域。
缓冲流:速度快,mark( )标记,受到缓冲内存大小的限制,默认512个字节。如果不能确定必须使用节点流。
过滤流:安全系数高使用节点流作为输入或输出。过滤流是使用一个已经存在的输入流或输出流连接创建的。
包装流:必须建立在结点流对象之上外层的是包装流,里面的是基础流(人喜欢打扮,流也不例外).当然,包装会有包装的好处,比如包装后的流可以调用包装流的方法,满足不同人的不同要求.
基础流:InputStream,ByteArrayInputStream,FileInputStream等等(包括对应的OutputStream)
包装流:FilterInputStream,BufferedInputStream,DataInputStream, LineNumberInputStream,PushbackInputStream以及有关的OutputStream. BufferedOutputStream,ObjectInputStream,ObjectOutputStram,Printwriter
节点流:从特定的地方读写的流类,例如:磁盘或一块内存区域。 过滤流:使用节点流作为输入或输出。过滤流是使用一个已经存在的输入流或输出流连接创建的。
FileInputStream和FileOutputStream,节点流,用于从文件中读取或往文件中写入字节流。如果在构造FileOutputStream时,文件已经存在,则覆盖这个文件。 BufferedInputStream和BufferedOutputStream,过滤流,需要使用已经存在的节点流来构造,提供带缓冲的读写,提高了读写的效率。 DataInputStream和DataOutputStream,过滤流,需要使用已经存在的节点流来构造,提供了读写Java中的基本数据类型的功能。 PipedInputStream和PipedOutputStream,管道流,用于线程间的通信。一个线程的PipedInputStream对象从另一个线程的PipedOutputStream对象读取输入。要使管道流有用,必须同时构造管道输入流和管道输出流。 http://fenlei27.52csdn.net/864952 |
BufferedInputStream构造方法:
BufferedInputStream (InputStream n) | 创建一个缓冲流,缓冲流流量最在为512k字节 |
BufferedInputStream(InputStream n,int size) | 缓冲流流量由Int参数决定 |
BufferedOutputStream构造方法:
BufferedInputStream (OutputStream n) | 创建一个缓冲流,缓冲流流量最在为512k字节 |
BufferedInputStream(OutputStream n,int size) | 缓冲流流量由Int参数决定 |
例:
FileInputStream fis =fileInputStream(“c:/a.txt”);//节点流
BufferedInputSteam bis=new BufferedInputSteam(fis);
//缓冲流,因为FileInputSteam为InputStream类的子类,fis为结点流对象(里氏代换)
BufferedInputStream常用方法:Reader类
Int available( )throws IOException | Int 返回可读入的字节数 |
Void close( ) | 关闭输入流,并释放与该流有关的资源 |
public void mark(int readAheadLimit) throws IOException | //给当前流作标记,最多支持readAheadLimit个字符的回溯。 mark( )时是在输入流中做一个标记,reset( )是返回mark( )标记的位置 当然,流要支持mark( ),用markSupported( )查看是否支持 |
Boolenan markSupported( ) | 测试该输入流是否支持mark( )和reset( )?? |
public void reset( ) throws IOException; | //将当前流重置到做标记处?? |
Pulbic long skip(long n)throws IOException | 跳过输入流上的n个字节?? |
1.Reader类是处理所有字符流输入类的父类。
◇ 读取字符
public int read( ) throws IOException; //读取一个字符,返回值为读取的字符
public int read(char cbuf[ ]) throws IOException; /*读取一系列字符到数组cbuf[ ]中,返回值为实际读取的字符的数量*/
public abstract int read(char cbuf[ ],int off,int len) throws IOException;
/*读取len个字符,从数组cbuf[ ]的下标off处开始存放,返回值为实际读取的字符数量,该方法必须由子类实现*/
◇ 标记流
public boolean markSupported( ); //判断当前流是否支持做标记
public void mark(int readAheadLimit) throws IOException;
//给当前流作标记,最多支持readAheadLimit个字符的回溯。
public void reset( ) throws IOException; //将当前流重置到做标记处
◇ 关闭流
public abstract void close( ) throws IOException;
BufferedOutputStream常用方法:Writer类
Void flush( ) | 刷空输出流,并输出所有被缓存的字节。 |
public void write(int c) throws IOException; | 将指定的字节写到缓冲输出流中 |
public abstract void write(char cbuf[ ],int off,int len) throws IOException; | 将字符数组cbuf[ ]中的从索引为off的位置处开始的len个字符写入输出流 |
Void close( ) | 关闭输出流 |
2. Writer类是处理所有字符流输出类的父类。
◇ 向输出流写入字符
public void write(int c) throws IOException;
//将整型值c的低16位写入输出流
public void write(char cbuf[ ]) throws IOException;
//将字符数组cbuf[ ]写入输出流
public abstract void write(char cbuf[ ],int off,int len) throws IOException;
//将字符数组cbuf[ ]中的从索引为off的位置处开始的len个字符写入输出流
public void write(String str) throws IOException;
//将字符串str中的字符写入输出流
public void write(String str,int off,int len) throws IOException;
//将字符串str 中从索引off开始处的len个字符写入输出流
◇ flush( )
刷空输出流,并输出所有被缓存的字节。
java.io
类 BufferedInputStream
java.io.BufferedInputStream
例:判断:
FileInputStream fis =fileInputStream(“c:/a.txt”);//节点流对文件操作
BufferedInputSteam bis=new BufferedInputSteam(fis);//实例化一个建立在节点流基础上的bis对象,建立了缓冲流
//缓冲流,因为FileInputSteam为InputStream类的子类,fis为结点流对象(里氏代换)
BufferedOutputStream bos=new BufferedOutputStream(fis);//不正确,流方向不一,fis为输入流。
BufferedInputStream bis1 =new BufferedInputStream(bis);//正确:因为此参数按道理来说应传InputStream类型的对象,但因为BufferedInputStream类一定为InputStream类的子类,语法完全可以,从构造的格式看bis1是建立在(已经建立在节点流对象fis之上的缓冲流bis)上面
缓冲流-------缓冲流-------结点流。
缓冲流想对管道进行操作:
PipedInputStream pis=new PipedInputStream(“c:/a.txt”); //节点流对文件操作
BufferedInputStream bis=new BufferedInputStream(pis);//缓冲流
例:p165BufferedOutputStream实例
import java.io.*;
class aa
{
public static void main(String args[ ])//传参为完整路径
{
if(args.length!=1)
{
System.out.println ("请输入要创建的文件名");
System.exit(-1);
}
try
{
FileOutputStream out=new FileOutputStream(args[0]);
BufferedOutputStream bufout=new BufferedOutputStream(out);
//创建文件输出流,缓冲输出流;
String msg="Hello";
byte[ ]ob=msg.getBytes( );
for(int i=0;i<1000;i++)//将数组内容写到缓冲1000次
bufout.write(ob,0,ob.length);
//bufout.flush( );??//作用是什么啊
bufout.close( );
}
catch(IOException e)//例外处理
{
e.printStackTrace( );
}
}
}
`````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````
例:乘法口决
import java.io.*;
class aa
{
public static void main(String args[ ])throws IOException
{
FileOutputStream f=new FileOutputStream("c://wyp.txt");
BufferedOutputStream f1=new BufferedOutputStream(f);
StringBuffer s1=new StringBuffer( );
for(int i=0;i<10;i++)
{
for(int j=0;j<=i;j++)
{
s1.append(i+"*"+j+"="+i*j+"/t");
//将指定的参数转成String后追加到s1的后面
}
s1.append("/n");
}
//byte[ ]c=new byte[f.available( )];//此句是错误的,因为available方法不属于写流的方法
//byte[ ]r= s1.toString( ).getBytes( );
// f1.write(r);//BufferString-----String---byte[ ]
f1.write(s1.toString( ).getBytes( ));
f1.flush( );
f1.close( );
f.close( );
System.out.print(s1);
}
}
``````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````
作业:p180 5.9
import java.io.*;
class mytest{
public static void main(String args[ ])throws IOException//命令行传参为完整路径
{
FileOutputStream f1=new FileOutputStream("c://good.txt");
String s="1234567890";
byte a[ ]=s.getBytes( );
f1.write(a);
f1.close( );
FileInputStream f2=new FileInputStream(args[0]);
byte b[ ]=new byte[f2.available( )];//返回f2可读入的字节数;
f2.read(b);
f2.close( );
FileOutputStream f3=new FileOutputStream(args[1]);
f3.write(b,2,4);
f3.close( );
}
}
、、包装流(对象序列化)
import java.io.*;
import java.util.Date;
public class SaveDate
{
public static void main(String args[ ])throws Exception
{
FileOutputStream fos=new FileOutputStream("date.out");
ObjectOutputStream oos=new ObjectOutputStream(fos);
Date date=new Date( );
oos.writeObject(date);
oos.flush( );
oos.close( );
fos.close( );
System.out.println (date);
//读
FileInputStream fis=new FileInputStream("date.out");//完整路径
ObjectInputStream sos=new ObjectInputStream(fis);
Date yy=(Date)sos.readObject( );
sos.close( );
fis.close( );
System.out.println (yy);
}
}