黑马程序员:IO流

来源:互联网 发布:it软件开发培训中心 编辑:程序博客网 时间:2024/04/29 16:57

----------   android培训java培训、期待与您交流! ----------

IO流主要是分为两类:字节流和字符流,他们都可以用来操作文件

其中字符流只要操作纯文本文件,里面嵌套了编码表,对文字进行编码。

字节流除了可以操作文本以外,还可以操作图片、音频、视频等文件,所以使用更广泛。

在java中对IO流的实现如下:

字节流的两个基类:InputStream(读)和OutputStream(写)

字符流的两个基类:Reader(读)和Writer(写)

JAVA中IO流整个体系的实现都是基于以上4个类实现的,基本结构是:例如FileWrite是操作文件对象的字符流Writer的子类,前缀名是该对流的功能,后缀名是父类名

下面我来总结下IO流中各个类的用法

字符流:Writer和Reader

FileWriter

FileWriter是用于对纯文本文件进行写入操作。

使用FileWriter读取纯文本文件的步骤:

1.创建一个FileWriter对象,该对象一被初始化就必须要明确杯操作的文件,而且该文件会被创建到指定目录下。如果该目录下已有同名文件,则被覆盖

FileWriter fw = new FileWriter("demo.txt");

2.调用write方法,将字符串写入到流中去。但此时还不会写到文件中去。

fw.write("abcde");

3.刷新该流对象缓冲中的数据,将数据写到指定文件中去

fw.flush();

4.关闭流资源,关闭之前会刷新一次缓冲中的数据。关闭流资源在IO中是必须要做的一件事。

fw.close;

一般完整的创建一个流对象的过程如下:

FileWriter fw = null;//先创建指向nulltry{fw = new FileWriter("d:\\demo.txt");fw.write("qweqdasda");}catch(IOException e){System.out.println(e.toString());}finally{try{if(fw != null)//防止上面未创建成功,保证代码的健壮性fw.close();}catch(IOException e){System.out.println(e.toString());}}

FileReader

和FileWriter相对应的一个流对象,是用于对纯文本文件进行读取操作的。

 使用FileReader读取纯文本文件的步骤如下:

1.创建一个FileReader对象,与制定名称的文件相关联。此时,要保证文件时存在的,如果不存在,会发生FileNotFoundException异常。

FileReader fr = new FileReader("demo.txt");

2.调用FileReader对象的read()方法,对文本进行读取,这是一次读一个字符,自动往下读,当读取完毕以后会返回-1

int ch = 0;while((ch=fr.read())!=-1){System.out.println(ch);//此时输入的是ASCLL码}

3.关闭流资源,再次强调任何IO操作最终都要关闭流资源

fr.close();

BufferedWriter和BufferedReader

BufferedWriter和BufferedReader是在Writer和Reader的基础上加入了缓冲区,缓冲区的出现是为了提高流的效率,所以在创建缓冲区之前,必须要有一个流对象

BufferedWriter

在BufferedWriter中提供了一个跨平台的换行符:newLine()

因为换行符在windows下是"\r\n",在Linux下是"\n"

FileWriter fw = new FileWriter("demo.txt");BufferedWriter bufw = new BufferedWriter(fw);

BufferedReader

该字符读取流缓冲区提高了一个一次读一行的方法readLine(),此方法的出现极大的方便了对文本数据的读取,当返回null的时候,表示读到了文件末尾。

readLine()方法返回一行数据的时候只返回回车符之前的数据内容,不返回回车符,所以要自己打回车符。

String line = null;while((line=bufr.readLine())!=null){System.out.print(line);}

LineNumberReader

可以返回行号(getLineNumber())和设置开始行号(setLineNumber(int))。

字节流:InputStream和OutputStream

在字节流中也存在与上述4个方法类似的方法,他们操作文件的范围更加广泛,不仅可以操作纯文本文件,还可以操作图片、音频、视频等。

它们是FileOutputStream、FileInputStream、BufferedOutputStream、BufferedInputStream,基本操作与上述相对应的流对象类似。

需要注意的是:在BufferedInputStream中不存在一次性读取一行的操作readLine(),BufferedOutputStream中也不存在换行newLine()。

字节流转换为字符流:InputStreamReader和OutputStreamWriter

由于字节流中不存在像readLine()这种一次性读取一行的方法,但是readLine()又十分好用,所以就出现了转换流。

BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in) );//最常用的键盘读取,可以一次读取一行BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(System.out));

在转换流中可以对文本内容打开、读取的编码格式进行设置:

OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("demo.txt"),"utf-8");

所以,转换流是连通字节流和字符流之间的桥梁,一般在涉及到字符编码的时候,需要用到转换流。

标准输入、输出设备

标准输入:System.in

标准输出:System.out

输入设备可以分为:键盘、硬盘、内存

输出设备可以分为:控制台、硬盘、内存

我们可以设置标准输入和输出的来源

System.setIn(InputStream in);

System.setOut(PrintStream out);

流操作的基本规律

三个明确:

1.明确源和目的:

源:输入流:InputStream、Reader

目的:输出流:OutputStream、Writer

2.明确操作的数据是否是纯文本

是纯文本:字符流

不是纯文本:字节流

是否要高效:来判断是否加上Buffered

3.明确要使用在哪个具体的对象上

源设备:内存ArrayStream、硬盘FileStream、键盘System.in

目的设备:内存ArrayStream、硬盘FileStream、控制台System.out

File对象

 File类常见的方法:

1.创建:

boolean createNewFile():在指定位置创建文件,如果该文件已经存在,则不创建,返回false

和输出流不一样,输出流一建立读写就会创建文件,如果文件已经存在则会覆盖。

2.删除:

boolean delete():删除失败返回false。如果文件正在被使用,则删除不了返回falsel。

void deleteOnExit();在程序退出时删除指定文件。

3.判断:

boolean exists():文件是否存在

boolean isFile():是否是文件,若文件不存在,还是会返回false

boolean isDirectory:是否是目录

boolean isHidden():是否隐藏

boolean isAbsolute():是否为绝对路径

4.获取信息:

getName():获取文件名

getPath():获取目录,此目录是封装成对象时候的目录                             

getParent():获取父目录,不存在则返回null

getAbsolutePath() :获取文件的绝对路径

long lastModified():获取文件的最好修改时间,返回时long,可以转换为Date

long length():获取文件的大小

renameTo(File dest) :重命名

5.文件列表

String[] list():返回此目录下的文件和文件件名称

File[] listRoots():得到系统的盘符

IO中的其他流对象 

打印流:PrintStream和PrintWriter

该流对象提供了打印方法,可以将各种数据类型的数据原样打印。

字节打印流:PrintStream

构造函数可以接收的参数类型:

1.file对象:File

2.字符串路径:String

3.字节输出流:OutputStream

字符打印流:PrintWriter

1.file对象:File

2.字符串路径:String

3.字节输出流:OutputStream

4.字符输出流:Writer

合并流:SequenceInputStream

可以将2个及2个以上的InputStream对象合并成一个流对象,当有2个以上的InputStream的时候,要用到Enumeration

序列化对象:ObjectInputStream和ObjectOutputStream

ObjectInputStream的readObject(),用于读取对象

ObjectOutputStream的writerObjec(Object obj),用于存对象 

这两个流对象是专门用来对对象进行读写的

当一个类,他的对象要被这两个流对象操作时,就必须要实现Serializable接口,这个接口没有任何方法,只是用于标记类。

Serializable接口的作用就在于,给每个要序列化的类一个唯一的UID,用于以后读的时候找到这个类。

但是要注意的时,类中的信息只要一改变,它的UID就会改变,此是就用可能读不出我们想要的数据了。

于是乎我们可以用这个来固定类的UID:static final long serialVersionUID = 42L;这样就算类改变了,还是可以找的到的。

还要注意一点,静态的变量不能被序列化,也就是说,你后期改变了它的值,他还是最初的值,不会变。

如果要想非静态的变量也不要序列化,则在变量前加transient则可以。

当存入多个对象的时候,readObject()会一个一个的去读出来。

管道流PipedInputStream和PipedOutputStream

数据由某个线程写入 PipedOutputStream 对象,并由其他线程从连接的 PipedInputStream 读取,相当于一个管道一样,一头读,一头写。

RandomAccessFile

内部封装了一个大型byte数组,而且通过指针对数组的元素进行操作。

可以通过getFilePointer获取指针位置,

同时可以通过seek改变指针的位置。

也就是说可以对文件里面的内容随机访问。

可以实现文件的分段写入:用一个线程控制一段数据,分别写入。

基本数据类型的流对象DataOutputStream和DateInputStream

一系列读写基本数据类型的操作。

其中要注意:

writerUTF(DataInput in):修正后的UTF-8编码,只能用相对应的readUTF()去读取才行。

readUTF()

ByteArrayStream

ByteArrayInputStream

ByteArrayInputStream包含一个内部缓冲区,该缓冲区包含从流中读取的字节。内部计数器跟踪 read 方法要提供的下一个字节。

关闭 ByteArrayInputStream无效。此类中的方法在关闭此流后仍可被调用,而不会产生任何 IOException。

ByteArrayOutputStream

此类实现了一个输出流,其中的数据被写入一个 byte 数组。缓冲区会随着数据的不断写入而自动增长。可使用 toByteArray() 和 toString() 获取数据。

 

 

 

 

----------   android培训java培训、期待与您交流! ----------

详情请查看:http://edu.csdn.net/heima/

 

原创粉丝点击