黑马程序员_IO流(一)

来源:互联网 发布:熊猫协议软件 编辑:程序博客网 时间:2024/05/29 03:19

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------

一、IO流概述

概述

IO流用来处理设备之间的数据传输。Java对数据的操作是通过流的方式。

Java用于操作流的对象都在IO包中。输入流和输出流相对于内存设备而言。


IO流常用的基类

字节流:InputStream   OutputStream

字符流:Reader            Writer

字符流基于字节流


在这四个类中,他们的子类共有一个特点:子类名后缀都是父类名,前缀名都是这个子类的功能名称。

比如Reader的子类FileReader,InputStream的子类FileInputStream


二、FileWriter

FileWriter是一个操作字符文件的输入流

写入字符流步骤的代码示例

import java.io.*;class  FileWriterDemo {public static void main(String[] args) throws IOException {//创建一个FileWriter对象。该对象一被初始化就必须要明确被操作的文件。//而且该文件会被创建到指定目录下。如果该目录下已有同名文件,将被覆盖。//其实该步就是在明确数据要存放的目的地。FileWriter fw = new FileWriter("demo.txt");//调用write方法,将字符串写入到流中。fw.write("abcde");//刷新流对象中的缓冲中的数据。//将数据刷到目的地中。fw.flush();//关闭流资源,但是关闭之前会刷新一次内部的缓冲中的数据。//将数据刷到目的地中。//和flush区别:flush刷新后,流可以继续使用,close刷新后,会将流关闭。fw.close();}}
续写

上面的代码有一个弊端,就是即使存在已有文件,也会将其覆盖。所以为了保证不覆盖并且能在文件的末尾出续写,可以往FileWriter中传入参数true

代码示例

FileWriter fw = new FileWriter("demo.txt",true);fw.write("abcde");


IO流的异常处理方式:为防止代码异常导致流无法关闭,因此在finally中对流进行关闭。

代码示例

import java.io.*;class FileWriterDemo {public static void main(String[] args) {//在try外建立引用,在try内进行初始化。这样fw变量就作用于整个函数FileWriter fw=null;try {fw=new FileWriter("demo.txt",true);//存在参数true,续写数据fw.write("abcdefg");}catch (IOException e) {System.out.println("catch:"+e.toString());}finally {try {/*fw.close()是一定执行的语句,所以要放在finally中,但fw.close存在异常,所以要单独try一下。要是在对象初始化时发生异常,  fw就为空,就不能执行close方法所以要进行判断。*/if(fw!=null)fw.close();}catch (IOException e) {System.out.println("catch:"+e.toString());}}}}

三、FileReader

FileReader是文本文件读取流

存在着字符字节读取和字符数组读取两种读取方式


字符字节读取代码示例

import java.io.*;class  FileReaderDemo {public static void main(String[] args) throws IOException {//创建一个文件读取流对象,使用FileReader让创建好的流对象和指定名称的文件相关联。//要保证该文件是已经存在的,如果不存在,会发生异常FileNotFoundExceptionFileReader fr = new FileReader("demo.txt");//调用读取流对象的read方法。//read():一次读一个字符。而且会自动往下读。int ch = 0;    //条件是没有读到结尾while((ch=fr.read())!=-1) {System.out.println(}fr.close();}}

字符字节读取比较麻烦一般使用字符数组读取

字符数组读取代码示例

import java.io.*;class FileReaderDemo2 {public static void main(String[] args) throws IOException {FileReader fr = new FileReader("demo.txt");//定义一个字符数组。用于存储读到字符。//该read(char[])返回的是读到字符个数,一般是1024的倍数。char[] buf = new char[1024];int num = 0;while((num=fr.read(buf))!=-1) {System.out.println(new String(buf,0,num));}fr.close();}}

注意

调用读取流对象的read方法,read():一次读一个字符,而且会自动往下读,如果读到流的末尾,则返回-1(结束标识)

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

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

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


练习:将C盘一个文本文件存储到D盘

/*复制的原理:其实就是将C盘下的文件数据存储到D盘的一个文件中。步骤:1,在D盘创建一个文件。用于存储C盘文件中的数据。2,定义读取流和C盘文件关联。3,通过不断的读写完成数据存储。4,关闭资源。*/import java.io.*;class CopyText {public static void main(String[] args) throws IOException {copy_2();}public static void copy_2() {FileWriter fw = null;//在外初始化,作用于整个函数FileReader fr = null;try{fw = new FileWriter("SystemDemo_copy.txt");//复制的新文件fr = new FileReader("SystemDemo.java");//读取的旧文件//利用数组存储字符char[] buf = new char[1024];int len = 0;while((len=fr.read(buf))!=-1) {fw.write(buf,0,len);}}catch (IOException e) {throw new RuntimeException("读写失败");}finally {if(fr!=null)try {fr.close();}catch (IOException e) {}if(fw!=null)try {fw.close();}catch (IOException e) {}}}//从C盘读一个字符,就往D盘写一个字符。public static void copy_1()throws IOException {//创建目的地。FileWriter fw = new FileWriter("RuntimeDemo_copy.txt");//与已有文件关联。FileReader fr = new FileReader("RuntimeDemo.java");int ch = 0;while((ch=fr.read())!=-1) {  //读到流的末尾返回-1fw.write(ch);}fw.close();fr.close();}}

四、字符流缓冲区BufferedReader和BufferWriter

缓冲区的出现就是为了提高流的操作效率,所以在创建缓冲区之前,必须要先有流对象,将流对象初始化到构造函数中去。

缓冲区出现了一个跨平台的换行方法newLine();

BufferedReader提供了readLine方法,一次读一行文本数据,方便了数据的获取。当返回null时,表示读到了文件末尾。

readLine方法读取到的内容中只包括每行数据的回车换行符之前的内容。因此如果同时调用BufferedWriter的write方法时,要同时调用newLine方法,才能实现换行。


练习:通过缓冲区复制一个java文件

import java.io.*;class CopyTestByBuf {public static void main(String[] args) {BufferedWriter bufw=null;BufferedReader bufr=null;try {//创建目的地,并使用缓冲技术bufw=new BufferedWriter(new FileWriter("bufWriter_copy.java"));//与已有文件关联,并使用缓冲技术bufr=new BufferedReader(new FileReader("Demo.java"));String line=null;while((line=bufr.readLine())!=null) {bufw.write(line);//写出一行的数据bufw.newLine();//readLine不返回换行符,所以newLine和readLine一起使用才能实现换行读取bufw.flush();}}catch (IOException e) {throw new RuntimeException("读写失败");}finally {try {if(bufr!=null)bufr.close();}catch (IOException e) {throw new RuntimeException("读取关闭失败");}try {if(bufw!=null)bufw.close();}catch (IOException e) {throw new RuntimeException("写入关闭失败");}}}}

五、装饰设计模式

概述

当想要对已有的对象进行功能增强时,可以定义新的类然后将原有的对象传入,基于已有的对象并提供加强的功能。这个自定义的类称为装饰类。


特点

装饰类通常都会通过构造方法接收被装饰的对象,并基于被装饰的对象的功能,提供更强的功能


代码示例

class Person {       void chifan() {            System.out.println("吃饭");      }}//采用装饰的方式增强Person类//这个类的出现是为了增强Person而出现的class NewPerson {       private Person p;      NewPerson(Person p) {             this.p = p;      }       public void chifan() {            System.out.println("开胃酒");            p.chifan();            System.out.println("甜点");      }}//采用继承的方式增强Person类class NewPerson2 extends Person {       public void chifan() {            System.out.println("开胃酒");             super.chifan();            System.out.println("甜点");      }}public class PersonDemo{       public static void main(String[] args) {            Person p = new Person();            NewPerson np1 = new NewPerson(p);            np1.chifan();            System.out.println( "............");            NewPerson2 np2 = new NewPerson2();            np2.chifan();      }}//继承和装饰结果相同,那么他们的区别是什么

装饰和继承的区别:

装饰模式比继承要灵活。避免了继承体系的臃肿,且降低了类与类之间的关系。

装饰类因为增强已有对象,具备的功能和已有的是相同的,只不过提供了更强的功能,所以装饰类和被装饰的类通常都是属于一个体系。

从继承结构转为组合结构。


六、File字节流的读写

概述

基本操作与字符流类相同。但它不仅可以操作字符,还可以操作其他媒体文件。


读写字节流:

InputStream 输入流(读)    OutputStream 输出流(写)


InputStream特有方法

int available();//返回文件中的字节个数

注意!可以利用此方法来指定读取方式中传入数组的长度,从而省去循环判断。但是如果文件较大,而虚拟机启动分配的默认内存一般为64M。

当文件过大时,此数组长度所占内存空间就会溢出。所以,此方法慎用,当文件不大时,可以使用。


注意!FileWriter的write方法不同,这里的不需要刷新动作


通过下面这段代码了解字节流的使用

import java.io.*;class CopyPic {public static void main(String[] args) {FileInputStream fis=null;FileOutputStream fos=null;try {fis=new FileInputStream("e:\\1.gif");//字节读取流对象和图片关联fos=new FileOutputStream("e:\\2.gif");//字节写入流对象创建一个图片文件byte[] buf=new byte[1024];//创建数组用于存储图片数据int len=0;//返回的是读取字节的个数while((len=fis.read(buf))!=-1) {fos.write(buf,0,len);//通过循环写出数组中的图片数据}}catch (IOException e) {throw new RuntimeException("文件复制失败");}finally {try {if(fis!=null)fis.close();//不需要刷新流}catch (IOException e) {throw new RuntimeException("读取关闭失败");}try {if(fos!=null)fos.close();}catch (IOException e) {throw new RuntimeException("写入关闭失败");}}}}

七、字节流缓冲区

读写特点

read():会将字节byte型值提升为int型值

write():会将int型强转为byte型,即保留二进制数的最后八位。


练习:复制mp3文件

import java.io.*;public class CopyMp3Test{       public static void main(String[] args) throws IOException {            copy_1();      }            public static void copy_1() throws IOException {            //创建输入流,使用缓冲技术            FileInputStream fis = new FileInputStream("0.mp3" );            BufferedInputStream bufis = new BufferedInputStream(fis); //创建输出流,使用缓冲技术            FileOutputStream fos = new FileOutputStream("2.mp3" );            BufferedOutputStream bufos = new BufferedOutputStream(fos);             int ch = 0;<span style="white-space:pre"></span>     //文件全部被取出read方法返回-1             while((ch = bufis.read()) != -1){                  bufos.write(ch);            }            bufis.close();            bufos.close();      }}





0 0
原创粉丝点击