黑马程序员——Java基础--------IO流(一)

来源:互联网 发布:网站哪里注册域名 编辑:程序博客网 时间:2024/05/14 19:47

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

IO流(一)

IO流:输入输出的流动

IO流用来处理设备之间的数据传输

Java对数据的操作是通过流的方式

Java用于操作流的对象都在IO包中

流按操作数据分为两种:字节流与字符流 。

流按流向分为:输入流,输出流。

输入流和输出流相对于内存设备而言.

将外设中的数据读取到内存中:输入(做的动作就是读)

将内存的数据写入到外设中:输出。(写)

字节流:用于处理字节类型的数据的流对象,就成为字节流

分为字节读取流和字节输出流

字符流:为了处理文字数据方便而出现的对象。

其实这些对象的内部使用的还是字节流(因为文字最终也是字节数据),只不过,通过字节流读取了相对应的字节数,没有对这些字节直接操作。而是去查了指定的(本机默认的)编码表,获取到了对应的文字。

简单说:字符流就是 : 字节流+编码表。

字符流分为字符读取流,字符输出流

字节流的两个顶层父类

InputStream OutputStream

字符流的两个顶层父类

Reader Writer

Reader中的一些方法:

read() 读取单个字符。

read(char[] cbuf) 将字符读入数组。返回读取的字符数

read(char[] cbuf, int off, int len) 将字符读入数组的某一部分。

读取方法都是阻塞式的方法

close() 关闭该流。

Writer中的一些方法:

write(String str)  写入字符串。

write(String str, int off, int len) 写入字符串的某一部分。

write(char[] cbuf)  写入字符数组。

write(char[] cbuf, int off, int len) 写入字符数组的某一部分。

write(int c)  写入单个字符。

都是将数据写到临时存储缓冲去中

flush() 刷新此流。将数据直接刷新到目的地中

close() 关闭资源,在关闭前,会先调用flush()方法刷新。

由这四个类派生出来的子类名称都是 以其父类名作为子类名的后缀。

注:

定义文件路径时,可以用“/”或者“\\”。??

在创建一个文件时,如果目录下有同名文 件将被覆盖。

在读取文件时,必须保证该文件已存在, 否则出异常。

FileWriter:可以往文件中写入字符数据的字符输出类流

既然是往一个文件中写入文字数据,那么在创建时,就必须指定该文件的名称,若文件不存在,则会自动创建,文件存在,则会被覆盖,如果构造函数中,假如true,可以实现,对文件的续写

将一些文字存储到硬盘一个文件内

package IO;import java.io.FileWriter;import java.io.IOException;public class WriterDemo {public static void main(String[]args) throws IOException{//创建一个可以往文件中写入字符数据的字符输出流对象。并明确目的地FileWriter fw = new FileWriter("F:\\WriteDemo.txt");//将数据写到临时缓冲区中fw.write("abcde");//将数据刷新到目的地中fw.flush();//关闭流fw.close();}}
FileReader:用于读取字符文件的便捷类

创建读取字符流对象时,必须明确被读取的文件,一定要确定该文件是存在的

读取硬盘中的文件,将其打印在控制台上

package IO;import java.io.FileReader;import java.io.IOException;public class ReaderDemo {public static void main(String[] args) throws IOException {// 用读取流关联一个已经存在的文件FileReader fr = new FileReader("F://WriteDemo.txt");//创建一个临时存放数据的数组。char[] ch = new char[1024];//调用流对象的读取方法将流中的数据读入到数组中。int len = 0;while((len=fr.read(ch))!=-1){//将数据打印在控制台上System.out.println(new String(ch,0,len));}}}
缓冲区:对要操作的内容进行临时缓存

作用:可以提高效率

IO流缓冲区的出现,提高了流对数据的读写效率,所以创建缓冲区之前必须先有流。要结合流才可以使用,在流的基础上对流的功能进行了增强

缓冲区的基本思想:其实就是定义容器将数据进行临时存储。

对于缓冲区对象,其实就是将这个容器进行了封装,并提供了更多高效的操作方法。

字符流缓冲区

BufferedReader BufferedWriter

BufferWriter的出现增强了Writer中的write方法。

但是增强过后,BufferWriter对外提供的还是write方法。只不过是高效的。所以写的实质没有变,那么BufferWriter也是Writer中的一员。

BufferedReader中的特有方法:

readLine():读一行,当没有读到时,返回null,其实,它使用了读取缓冲区的read方法,将读取的字符进行了缓冲并判断断行标记,将标记前的缓冲数据变成了字符串返回

BufferedWriter中的特有方法:

newLine():换行

用缓冲区复制文本

package IO;import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.FileReader;import java.io.FileWriter;import java.io.IOException;public class BufferedDemo {public static void main(String[] args) throws IOException {// TODO Auto-generated method stub//创建字符读取流缓冲区,关联指定文件BufferedReader br = new BufferedReader(new FileReader("F://Buffered.txt"));//创建字符输出流缓冲区,并指定目的地BufferedWriter bw = new BufferedWriter(new FileWriter("G://buffered.txt"));//读取文件内容,并将其写到目的地中String s = null;while((s=br.readLine())!=null){bw.write(s);bw.newLine();bw.flush();}//关闭流br.close();bw.close();}}
自定义的读取缓冲区:其实就是模拟一个BufferedReader

package IO;import java.io.IOException;import java.io.Reader;/** * 自定义的读取缓冲区。其实就是模拟一个BufferedReader. *  * 分析: * 缓冲区中无非就是封装了一个数组, * 并对外提供了更多的方法对数组进行访问。 * 其实这些方法最终操作的都是数组的角标。 *  * 缓冲的原理: * 其实就是从源中获取一批数据装进缓冲区中。(用的使其父类的read(buf)方法) * 在从缓冲区中不断的取出一个一个数据。 *  * 在此次取完后,在从源中继续取一批数据进缓冲区。 * 当源中的数据取光时,用-1作为结束标记。  *  *  * @author Administrator * */public class MyBufferedReader extends Reader {private Reader r;//定义一个数组作为缓冲区。private char[] buf = new char[1024];//定义一个指针用于操作这个数组中的元素。当操作到最后一个元素后,指针应该归零。private int pos = 0;//定义一个计数器用于记录缓冲区中的数据个数。 当该数据减到0,就从源中继续获取数据到缓冲区中。private int count = 0;MyBufferedReader(Reader r){this.r = r;}/** * 该方法从缓冲区中一次取一个字符。  * @return * @throws IOException */public int myRead() throws IOException{if(count==0){count = r.read(buf);pos = 0;}if(count<0)return -1;char ch = buf[pos++];count--;return ch;}//读取一行public String myReadLine() throws IOException{StringBuilder sb = new StringBuilder();int ch = 0;while((ch = myRead())!=-1){if(ch=='\r')continue;if(ch=='\n')return sb.toString();//将从缓冲区中读到的字符,存储到缓存行数据的缓冲区中。sb.append((char)ch);}if(sb.length()!=0)return sb.toString();return null;}public void myClose() throws IOException {r.close();}@Overridepublic int read(char[] cbuf, int off, int len) throws IOException {return 0;}@Overridepublic void close() throws IOException {}}
字节流

InputStream OutputStream

字节读取流一个方法available():返回读取文件的字节数,数据很大不建议使用这个,容易造成内存溢出

子类:

FileInputStream FileOutputStream

带有缓冲区的

BufferedInpuStream BufferedOutputStream

用字节流复制一个mp3文件

package IO;import java.io.BufferedInputStream;import java.io.BufferedOutputStream;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;public class InputStreamDemo {public static void main(String[] args) throws IOException {//为了高效,用缓冲区,确定源复制文件BufferedInputStream bis = new BufferedInputStream(new FileInputStream("F://Avril Lavigne - 滑板少年.mp3"));//确定复制的目的,为了高效,用缓冲BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("F://1.mp3"));//方式一//不建议使用,效率太慢/*int len =0;while((len=bis.read())!=-1){bos.write(len);}*///方式二,建议使用这种/*int len =0;byte[]buf = new byte[1024];while((len=bis.read(buf))!=-1){bos.write(buf,0,len);}*///方式三,数据太大容易造成内存溢出byte[]buf = new byte[bis.available()];bis.read(buf);bos.write(buf);bis.close();bos.close();}}

0 0