Java基础---IO(一)---IO流概述、字符流

   IO概述

概述

1、IO流:即InputOutput的缩写。

2、特点:

1)IO流用来处理设备间的数据传输。

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

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

4)流按操作数据分为两种:字节流和字符流。

5)流按流向分为:输入流和输出流。

注意:流只能操作数据,而不能操作文件。

3、IO流的常用基类:

1)字节流的抽象基流:InputStream和OutputStream

2)字符流的抽象基流:Reader和Writer

注:此四个类派生出来的子类名称都是以父类名作为子类名的后缀,以前缀为其功能;

如   InputStream子类FileInputStream;

  Reader子类FileReader

第二讲    字符流

一、简述

1、字符流中的对象融合了编码表。使用的是默认的编码,即当前系统的编码。

2、字符流只用于处理文字数据,而字节流可以处理媒体数据。

3、既然IO流是用于操作数据的,那么数据的最常见体现形式是文件。查看API,找到一个专门用于操作文件的Writer子类对象:FileWriter。   后缀是父类名。前缀名是流对象的功能。该流对象一被初始化,就必须有被操作的文件存在。

二、字符流的读写

1、写入字符流步骤

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

注意:

1、其实java自身不能写入数据,而是调用系统内部方式完成数据的书写,使用系统资源后,一定要关闭资源。

      即可以在finally中对流进行关闭资源。

2、文件的数据的续写是通过构造函数 FileWriter(Strings,boolean append),在创建对象时,传递一个true参数,代表不覆盖已有的文件。并在已有文件的末尾处进行数据续写。(windows系统中的文件内换行用\r\n两个转义字符表示,在linux系统中只用\n表示换行)

3、由于在创建对象时,需要指定创建文件位置,如果指定的位置不存在,就会发生IOException异常,所以在整个步骤中,需要对IO异常进行try处理。

思考:  

     1、有了垃圾回收机制为什么还要调用close方法进行关闭?

    答:垃圾回收机制是不定时的,回收时间不是我们所能控制的,并且流不单单在内存中分配了空间,也在操作系统占有了资源,java的gc是能从内存中回收不         使用的对象,但对操作系统分配的资源是无能为力的,所以就要调用close()方法来通知OS来释放这个资源。

   2、为什么IO异常一定要处理?

    答:程序运行中出现异常就会终止程序,  导致后面的代码运行不到,  我们要是写的代码面向客户, 出现问题客户不一定知道为什么, 所以我们要对可能出现的

      问题进行处理.  一旦发现可能出现问题的代码,而我们可以通过捕获异常,使异常后面的程序正常运行。即提高代码的健壮性。

2、读取字符流步骤

1)创建一个文件读取流对象,和指定名称的文件相关联。要保证该文件已经存在,若不存在,将会发生异常FileNotFoundException。

2)调用读取流对象的read()方法。read():一次读一个字符,且会继续往下读。

第一种方式:读取单个字符。第二种方式:通过字符数组进行读取。

3)读取后要调用close方法将流资源关闭。

示例:

 1 //将C盘一个文本文件复制到D盘
 2
 3 /*
 4 复制的原理:
 5     其实就是将C盘下的文件数据存储到D盘的一个文件中。
 6
 7 步骤:
 8     1    在D盘创建一个文件。用于存储C盘文件中的数据
 9     2    定义读取流和Cpan文件关联
10     3    通过不断的读写完成数据存储
11     4    关闭资源
12 */
13 import java.io.*;
14 class CopyTest
15 {
16     public static void main(String[] args)
17     {
18         copy_2();
19     }
20     public static void copy_2()
21     {
22         FileWriter fw=null;
23         FileReader fr=null;
24         try
25         {
26             fw=new FileWriter("SystemDemo_copy.txt");//写入流关联文本文件
27             fr=new FileReader("SystemDemo.java");//读取流关联文本文件
28             char[] buf=new char[1024];//创造第三方 字节数组,使两个流能够联系起来
29             int len=0;
30             while((len=fr.read(buf))!=-1)  //将读取流的字节存到字节数组中,只要没有读到-1(即结束标志),继续存
31             {
32                 fw.write(buf,0,len);//将字节数组中的数据,通过写入流  写入 关联的文本文件
33             }
34         }
35         catch (IOException e)
36         {
37             throw new RuntimeException("读写失败");
38         }
39         finally
40         {
41             if(fr!=null)
42                 try
43                 {
44                     fr.close(); //将读取流的数据关闭
45                 }
46                 catch (IOException e)
47                 {
48                 }
49             if(fw!=null)
50                 try
51                 {
52                     fw.close();//将写入流的数据刷到指定文件内,并关闭流资源
53                 }
54                 catch (IOException e)
55                 {
56                 }
57         }
58     }
59
60
61     public static void copy_1()throws  IOException
62     {
63         //创建目的地
64         FileWriter fw=new FileWriter("Demo_copy1.txt");
65         //与已有文件关联
66         FileReader fr=new FileReader("Demo.txt");
67         int ch=0;
68         while((ch=fr.read())!=-1)//一个字节一个字节读的,而且会自动往下读
69         {
70             fw.write(ch);
71         }
72         fw.close();
73         fr.close();
74     }
75
76 }

注意:

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

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

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

三、字符流的缓冲区——BufferedReader和BufferedWriter

1、缓冲区的出现:提高了流的读写效率,所以在缓冲区创建前,要先创建流对象。即先将流对象初始化到构造函数中。

2、缓冲技术原理:此对象中封装了数组,将数据存入,再一次性取出。

3、写入流缓冲区BufferedWriter的步骤:

 1 /*缓冲区的出现是为了提高流的操作效率而出现的
 2
 3 所以在创建缓冲区之前,必须要先有流对象
 4
 5 该缓冲区中提供了一个跨平台的换行符
 6 newline()
 7 */
 8 import java.io.*;
 9 class BufferedWriterDemo
10 {
11     public static void main(String[] args)throws IOException
12     {
13         //创建一个字符流写入流对象
14
15         FileWriter fw=new FileWriter("buf.txt");
16          //为了提高字符写入流的效率。加入了缓冲技术
17          //只要将需要被提高效率的流对象作为参数传递给缓冲区的构造函数即可
18         BufferedWriter bufw=new BufferedWriter(fw);
19
20         for(int x=1;x<5;x++)
21         {
22             bufw.write("abcd"+x);
23             bufw.newLine();
24             bufw.flush();
25         }
26     //记住,只要用到缓冲区,就要记得刷新
27     //bufw.flush();
28     //其实关闭缓冲区,就是在关闭缓冲区中的流对象。
29         bufw.close();
30
31     }
32 }

小知识:BufferedWriter缓冲区中提供了一个跨平台的换行符:newLine();可以在不同操作系统上调用,用作数据换行。

如:bufw.newLine();

4、读取流缓冲区BufferedReader

该缓冲区提供了一个一次读一行的方法readLine,方便于堆文本数据的获取,当返回null时表示读到文件末尾。readLine方法返回的时候,只返回回车符之前的数据内容。并不返回回车符。

readLine方法原理:

无论是读一行。或者读取多个字符。其实最终都是在在硬盘上一个一个读取。所以最终使用的还是read方法一次读一个的方法。

步骤:

1)创建一个读取流对象和文件相关联

如: FileReader fr=newFileReader("buf.txt");

2)为了提高效率。加入缓冲技术。将字符读取流对象作为参数传递给缓冲区对象的构造函数。

如: BufferedReader bufr=new BufferedReader(fr);

3)调用该缓冲区提供的readLine方法一行一行读取,如果到达文件末尾,则返回null

如: String s=bufr.readLine();

4)关闭流资源

如: bufr.close();、

示例:通过缓冲区复制一个文本文件。

 1 /*
 2
 3 通过缓冲区复制一个。java文件*/
 4 import java.io.*;
 5 class CopyTextBybuf
 6 {
 7     public static void main(String[] args)
 8     {
 9         BufferedReader bufr=null;//为了防止异常的产生,首先要创建缓冲区
10         BufferedWriter bufw=null;
11         try
12         {
13             bufr=new BufferedReader(new FileReader("BufferedWriterDemo.java"));//将关联文件后的读写流都放到缓冲区中
14             bufw=new BufferedWriter(new FileWriter("bufWriter_Copy.txt"));
15
16             String line=null;
17             while((line=bufr.readLine())!=null)//缓冲区提供了一次读一行的方法
18             {
19                 bufw.write(line);
20                 bufw.newLine();
21                 bufw.flush();//刷新缓冲区
22             }
23         }
24         catch (IOException e)
25         {
26             throw new RuntimeException("读写失败");
27         }
28         finally
29         {
30             try
31             {
32                 if(bufr!=null)
33                     bufr.close();
34             }
35             catch (IOException e)
36             {
37                 throw new RuntimeException("读取关闭失败");
38             }
39
40             try
41             {
42                 if(bufw!=null)
43                     bufr.close();
44             }
45             catch (IOException e)
46             {
47                 throw new RuntimeException("写入关闭失败");
48             }
49         }
50     }
51 }

5、自定义BufferedReader:

原理:

可根据BufferedReader类中特有一行一行读取方法readLine()的原理,自定义一个类中包含相同功能的方法

步骤:

a、初始化自定义的类,加入流对象。

b、定义一个临时容器,原BufferedReader封装的是字符数组,此类中可定义一个StringBuilder的容器,最终可实现字符串的提取。

 1 /*
 2 明白了BufferedReader 类中特有方法 readLine() 的原理后,
 3 可以自定义一个类中包含一个功能和readLine 一致的方法
 4
 5 用来模拟一下 BufferedReader
 6 */
 7 import java.io.*;
 8 class MyBufferedReader extends Reader
 9 {
10     private Reader r;
11     MyBufferedReader(Reader r)
12     {
13         this.r=r;
14
15     }
16     //可以一次读一行  数据的方法
17     public String myReaderLine() throws IOException
18     {
19         //定义一个临时容器。  原BufferReader 封装的是字符数组
20         //为了演示方便。定义一个StringBuilder容器
21         //因为最终还是要将数据变成字符串
22         StringBuilder sb=new StringBuilder();//创建字符串容器,用于存储文本中的字符
23         int ch=0;
24         while((ch=r.read())!=-1)//一次读一个,但是没有遇到回车符时,会暂时先存储在StringBuilder中
25         {
26             if(ch==‘\r‘)
27                 continue;
28             if(ch==‘\r‘)
29                 return sb.toString();
30             else
31                 sb.append((char)ch);
32         }
33         if(sb.length()!=0)
34             return sb.toString();
35         return null;
36
37
38     }    /*
39     因为MyBufferedReader extends Reader,而Reader中存在抽象方法
40     所以我们要覆盖Reader类中的抽象方法。
41
42     */
43     public int read(char[] cbuf, int off, int len) throws IOException
44     {
45         return r.read(cbuf,off,len) ;
46     }
47
48     public void close()throws IOException
49     {
50         r.close();
51     }
52     public void myClose()throws IOException
53     {
54         r.close();
55     }
56 }
57 class MyBufferedReaderDemo
58 {
59     public static void main(String[] args)throws IOException
60     {
61         FileReader fr=new FileReader("buf.txt");//字符读取流关联文本文件
62         MyBufferedReader myBuf=new MyBufferedReader(fr);//建立读取缓冲区容器,将字符读取流放入
63         String line=null;
64         while((line=myBuf.myReaderLine())!=null)  //实现自定义读取方式
65         {
66             System.out.println(line);//打印出每行 读取到的内容
67         }
68
69         myBuf.myClose();//关闭 读取缓冲区
70     }
71 }

四、装饰设计模式

 1 /*
 2 装饰设计模式:
 3 当想要对已有的对象进行功能增强时,
 4 可以定义类,将已有对象传入,基于已有的功能,并提供加强功能。
 5 那么自定义的该类称为装饰类
 6
 7 装饰类通常会通过构造函数方法接收被装饰的对象。
 8
 9 并基于被装饰的对象的功能,提供更强的功能
10 */
11 class Person
12 {
13     public void chifan()
14     {
15         System.out.println("吃饭");
16     }
17     public void wc()
18     {
19         System.out.println("go to wc");
20     }
21 }
22 class SuperPerson
23 {
24     private Person p;
25     SuperPerson(Person p)
26     {
27         this.p=p;
28     }
29     public void superChifan()
30     {
31
32         System.out.println("开胃酒");
33         p.chifan();
34         p.wc();
35         System.out.println("甜点");
36         System.out.println("来一根");
37     }
38 }
39 class PersonDemo
40 {
41     public static void main(String[] args)
42     {
43         Person p=new Person();
44         //p.chifan;
45         SuperPerson sp=new SuperPerson(p);
46         sp.superChifan();
47     }
48 }

装饰和继承的区别:

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

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

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

注:在定义类的时候,不要以继承为主;可通过装饰设计模式进行增强类功能。灵活性较强,当装饰类中的功能不适合,可再使用被装饰类的功能。

时间: 2024-08-04 10:28:44

Java基础---IO(一)---IO流概述、字符流的相关文章

黑马程序员——Java基础--IO流(一)---字符流和字节流

------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- 一.IO流的介绍及体系 IO流用来处理设备之间的数据传输.java对数据的操作是通过流的方式.java用于操作流的对象都在IO包中. 输入流和输出流相对于内存设备而言:将外设中的数据读取到内存中:输入.将内存中的数据写出到外设中:输出. 流按照操作数据分为两种:字节流和字符流. 字符流的由来:其实就是字节流读取文字字节数据后,不直接操作而是先查指定的编码表,获取对应的文字,再对这个文字进行操作

Java之IO初识(字节流和字符流)

IO概述 生活中,你肯定经历过这样的场景.当你编辑一个文本文件,忘记了 ctrl+s ,可能文件就白白编辑了.当你电脑上插入一个U盘,可以把一个视频,拷贝到你的电脑硬盘里.那么数据都是在哪些设备上的呢?键盘.内存.硬盘.外接设备等等.我们把这种数据的传输,可以看做是一种数据的流动,按照流动的方向,以内存为基准,分为 输入input 和 输出output ,即流向内存是输入流,流出内存的输出流.Java中I/O操作主要是指使用 java.io 包下的内容,进行输入.输出操作.输入也叫做读取数据,输

java io流(字符流) 文件打开、读取文件、关闭文件

java io流(字符流) 文件打开 读取文件 关闭文件 //打开文件 //读取文件内容 //关闭文件 import java.io.*; public class Index{ public static void main(String[] args) throws Exception{ //打开文件 //字符流方式打开 //字符流每次按一个字符读取 FileReader wj = new FileReader("D:/java/kj/javanew/src/Index.java"

J2SE知识点归纳笔记(七)---Java IO Part 4:基本字符流

J2SE知识点归纳笔记(七)---Java IO Part 4:基本字符流                                                                 --转载请注明出处:coder-pig 本节引言: 上一节中,我们对于Java IO流中的一些基本字节流进行了学习,他们都是InputStream与 OutputStream的子类;本节学习的字符流则是Reader与Writer的子类,好了,话不多说, 开始本节内容! 本节正文: 1.Reade

复习java基础第六天(IO)

一:File 类 • 输入:读取外部数据(磁盘.光盘等存储设备的数据)到程序(内存)中. • 输出:将程序(内存)数据输出到磁盘.光盘等存储设备中 • Java 的 IO 流主要包括输入.输出两种 IO 流,每种输入.输出流有可分为字节流和字符流两大类: – 字节流以字节为单位来处理输入.输出操作 – 字符流以字符为单位来处理输入.输出操作 注意:输入.输出是以程序为参照. • File 类代表与平台无关的文件和目录. • File  能新建.删除.重命名文件和目录,但 File 不能访问文件内

JAVA基础知识之IO——Java IO体系及常用类

Java IO体系 个人觉得可以用"字节流操作类和字符流操作类组成了Java IO体系"来高度概括Java IO体系. 借用几张网络图片来说明(图片来自 http://blog.csdn.net/zhangerqing/article/details/8466532 )  基于字节的IO操作 基于字符的IO操作   从上图可以看到,整个Java IO体系都是基于字符流(InputStream/OutputStream) 和 字节流(Reader/Writer)作为基类,根据不同的数据载

Java基础知识之IO(2)

文件复制小案例(温习Java基础知识之IO(1)中的知识) package copy; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; public class CopyDemo { public stat

JAVA之旅(二十四)——I/O流,字符流,FileWriter,IOException,文件续写,FileReader,小练习

JAVA之旅(二十四)--I/O流,字符流,FileWriter,IOException,文件续写,FileReader,小练习 JAVA之旅林林总总也是写了二十多篇了,我们今天终于是接触到了I/O了.如果你初学,不懂IO流,你可以从前往后慢慢看,但是你工作了一段时间你会发现,流的使用场景以及技术点是非常的强硬的,我们势必要掌握这个知识点,如果你觉得翻阅API比较鼓噪,看视频得不到精髓,看书看不到要点,你就跟随我的JAVA之旅,一起去探索吧! 一.I/O概述 I/O全名:Input Output

java基础知识回顾之javaIO类--管道流PipedOutputStream和PipedIutputStream

管道流(线程通信流):管道流的主要作用是可以进行两个线程间的通讯,分为管道输出流(PipedOutputStream).管道输入流(PipedInputStream),如果想要进行管道输出,则必须要把输出流连在输入流之上.如图所示: 1.管道输入流应该连接到管道输出流 ,输入流和输出流可以直接连接       2.使用多线程操作,结合线程进行操作.通常由某个线程从管道输入流中(PipedInputStream)对象读取.          并由其他线程将其写入到相应的端到输出流中.不能使用单线程

【JAVA IO流之字符流】

一.概述. java对数据的操作是通过流的方式.java用于操作流的对象都在IO包中.流按照操作数据不同分为两种,字节流和字符流.流按照流向分为输入流,输出流. 输入输出的“入”和“出”是相当于内存来说的. 字符流:字节流读取文字字节数据后,不直接操作,而是先查指定的编码表,获取对应的文字,再对这个文字进行操作.简单来说就是字节流+码表. 在IO流中,字节流的顶层父类是Writer和Reader. 二.java.io.FileWriter类. public class FileWriterext