标签:style blog color io os 使用 ar java for
一、IO概述
1、IO:是Input、Output的缩写。
2、特点:
(1)用于处理设备间的数据传输。
(2)Java对数据的处理是通过“流”完成的。
(3)Java用于操作流的对象都在IO包中。
(4)流按操作分为两种:字节流和字符流。
(5)流按流向分为:输入流和输出流(输入输出是相对于“内存”而言的)。
3、IO流常用基类
(1)字节流abstract基类:InputStream、OutputStream;
(2)字符流抽象基类:Reader、Writer;
二、字符流(Reader、Writer)
(一)概述
字符流只用于处理文字数据,是字节流读取文字字节数据后,不直接操作而是先查指定的编码表,获取对应的文字。简单说:字符流 = 字节流+编码表
(二)写入字符流(Writer)
1、“写入字符流”操作步骤
(1)创建时,要明确文件存储路径。如果文件不存在,则自动创建文件。如果文件存在,则会覆盖原文件。代码示例:
FileWtriter fw = new FileWriter("d:\\d.txt");
(2)调用Writer对象中的write(String s)方法,将数据写入到“临时存储缓冲区”中。代码示例:
fw.write("abcde");
(3)调用flush()方法,刷新该流的缓冲,将数据刷新到目的地中。代码示例:
fw.flush(); //可以用多次
(4)调用close()方法,关闭流资源。代码示例:
fw.close();//但是关闭前会刷新一次内部的缓冲数据,并将数据刷新到目的地中,只能用一次。
注意:close()和flush()区别:flush()刷新后,流可以继续使用;而close()刷新后,将会关闭流,不可再写入字符流。
2、FileWriter细节
(1)换行
Windows系统中的换行是\r\n,而Linux系统中的换行是\n。为了能够适应不同的操作系统,java可以获取系统换行。格式如下
System.getProperty(“line.sepatator”);
(2)续写
如果再FileWriter的构造函数中加入true,可以实现对文件实行续写。格式如下:
FileWtriter fw = new FileWriter("d:\\d.txt" , true);
(3)IO异常处理
将FileWriter对象(FileWriter fw = null)声明在try{}catch(){}外面。
在finally中,关闭流对象,判断fw是否为空,不为空时,才可以用try{}catch(){}来处理fw.close()。否则,会出现java.lang.NullPointerException。
3、FileWriter总结
(1)其实java自身不能写入数据,而是调用系统内部方式完成数据的书写,使用系统资源后,一定要关闭资源。
(2)文件的数据的续写是通过构造函数 FileWriter(Strings,boolean append),在创建对象时,传递一个true参数,代表不覆盖已有的文件。并在已有文件的末尾处进行数据续写。(windows系统中的文件内换行用\r\n两个转义字符表示,在linux系统中只用\n表示换行)
(3)由于在创建对象时,需要指定创建文件位置,如果指定的位置不存在,就会发生IOException异常,所以在整个步骤中,需要对IO异常进行try处理。
(三)读取字符流(Reader)
1、“读取字符流”操作步骤
(1)创建一个文件读取流对象,和指定名称的文件相关联。要保证该文件已经存在,若不存在,将会发生异常FileNotFoundException。代码示例:
FileReader fr = new FileReader(“d:\\demo.txt”);
(2)调用读取流对象的read()方法。read()有两种读取方式:一种是读取单个字符。另一种是通过字符数组进行读取。两种读取方式的代码示例:
① 读取单个字符方式:int ch = fr.read();
② 读取字符数组方式:
1 char[] buf = new char[1024];
2 Int len = 0;
3 While(( len = fr.read(buf))!=-1){
4 System.out.print( new String(buf , 0 , len));
5 }
(3)读取后调用close()方法,关闭流资源。代码示例:
fr.close();
2、FileReader总结
(1)定义文件路径时,可以用“/”或者“\\”。
(2)在创建一个文件时,如果目录下有同名文件将被覆盖。
(3)在读取文件时,必须保证该文件已存在,否则出异常。
(四)字符流练习:
/*
需求:将c盘一个文本文件复制到d盘。
思路:1、需要读取源;2、将读到的源写入到目的地;
步骤:
1、读一个文件,是字符读取流和文件关联;
2、创建一个目的文件,用于存储读到的数据;
3、频繁的读写;
4、关闭流资源;
*/
1 import java.io.*;
2 class ReaderWriterTest {
3 public static void main(String[] args) {
4 // 调用复制方法
5 // copy_1();
6 copy_2();
7 }
8 // 用第一种读取方式进行复制
9 public static void copy_1() {
10 FileWriter fw = null;
11 FileReader fr = null;
12 try {
13 // 关联读取和写入的文件
14 fw = new FileWriter("D:\\HelloWorld.java");
15 fr = new FileReader("C:\\HelloWorld.java");
16 for (int ch = 0; (ch = fr.read()) != -1;) {
17 fw.write(ch);// 一个字符一个字符写入
18 }
19 } catch (IOException e) {
20 throw new RuntimeException("读写失败");
21 } finally {
22 if (fr != null)
23 try {
24 fr.close();// 对读取流和写入流分别关闭
25 } catch (IOException e) {
26 }
27 if (fw != null)
28 try {
29 fw.close();
30 } catch (IOException e) {
31 }
32 }
33 }
34 // 第二种读取方式进行复制
35 public static void copy_2() {
36 FileWriter fw = null;
37 FileReader fr = null;
38 try {
39 // 关联读取和写入的文件
40 fw = new FileWriter("D:\\HelloWorld.java");
41 fr = new FileReader("C:\\HelloWorld.java");
42 char[] arr = new char[1024];
43 for (int len = 0; (len = fr.read(arr)) != -1;) {
44 fw.write(arr, 0, len);// 利用数组一次存入数组中的字符
45 }
46 } catch (IOException e) {
47 throw new RuntimeException("读写失败");
48 } finally {
49 try {
50 if (fr != null)
51 fr.close();
52 } catch (IOException e) {
53 } finally {
54 if (fw != null)
55 try {
56 fw.close();
57 } catch (IOException e) {
58 }
59 }
60 }
61 }
62 }
三、字符流缓冲区
(一)概述
1、字符流缓冲区的作用:提高了对数据的读写效率。
2、对应的类:BufferedWriter以及BufferedReader,要结合流,才可以使用。
(二)BufferedWriter
1、操作步骤
(1)创建一个字符写入流对象,代码示例:
FileWriter fw = new FileWriter("demo.txt");
(2)为了提高字符写入流效率,加入缓冲技术,将需要被提高效率的流对象作为参数传递给缓冲区的构造函数,代码示例:
BufferedWriter bufw = new BufferedWriter(fw);
(3)调用write方法写入数据到指定文件,代码示例:
bufw.write ("abcde");
(4)刷新缓冲区,代码示例:
bufw.flush();
(5)关闭流资源,,代码示例:
bufw.close();
2、小细节:BufferedWriter提供了跨平台的换行符newLine()方法,格式:bufw.newLine();
(三)BufferedReader
1、作用
从字符输入流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取。
2、特点
BufferedReader提供了一次读一行的方法readLine(),方便于文本数据的获取,当返回null时表示读到文件末尾。readLine方法返回的时候,只返回回车符之前的数据内容。并不返回回车符。
3、readLine()原理
使用了读取缓冲区的read()方法,将读取到的字符进行缓冲并判断换行标记,将标记前的缓存数据变成字符串返回。
4、BufferedReader操作步骤
(1)创建一个读取流对象和文件相关联,
FileReader fr = new FileReader("demo.txt");
(2)为了提高效率、加入缓冲技术、将字符读取流对象作为参数传递给缓冲区对象的构造函数。
BufferedReader bufr = new BufferedReader(fr);
(3)调用该readLine()方法一行一行读取,如果到达文件末尾,则返回null
String str = bufr.readLine();
(4)关闭流资源
bufr.close();
(四)练习
/* 需求:使用缓冲技术copy一个文本文件 */
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class CopyTextByBufTest {
public static void main(String[] args) throws IOException {
FileReader fr = new FileReader("buf.txt");
BufferedReader bufr = new BufferedReader(fr);
FileWriter fw = new FileWriter("buf_copy.txt");
BufferedWriter bufw = new BufferedWriter(fw);
String line = null;
while((line=bufr.readLine())!=null){
bufw.write(line);
bufw.newLine();
bufw.flush();
}
//单个字符读取方式
//int ch = 0;
//while((ch=bufr.read())!=-1){
// bufw.write(ch);
//}
bufw.close();
bufr.close();
}
}
(五)自定义缓冲区
1 /*需求:模拟BufferedReader,自定义一个MyBufferedReader缓冲区 */
2 import java.io.*;
3 //自定义缓冲类
4 class MyBufferedReader extends Reader {
5 private Reader r;// 定义接收的流对象
6 MyBufferedReader(Reader r) {
7 this.r = r;
8 }
9 // 自定义整行读取
10 public String myReadLine() throws IOException {
11 // 创建一个容器,用来存储一行的字符
12 StringBuilder sb = new StringBuilder();
13 // 一个字符一个字符读取
14 for (int ch = 0; (ch = r.read()) != -1;) {
15 if (ch == ‘\r‘)// 如果遇到换行符,则继续
16 continue;
17 if (ch == ‘\n‘)// 如果遇到回车符,表示该行读取完毕
18 return sb.toString();
19 else
20 sb.append((char) ch);// 将该行的字符添加到容器
21 }
22 if (sb.length() != 0)// 如果读取结束,容器中还有字符,则返回元素
23 return sb.toString();
24 return null;
25 }
26 // 复写父类中的抽象方法
27 public int read(char[] cbuf, int off, int len) throws IOException {
28 return r.read(cbuf, off, len);
29 }
30 // 复写父类的close方法
31 public void close() throws IOException {
32 r.close();
33 }
34 }
35
36 // 测试MyBufferedReader
37 class MyBufferedReaderDemo {
38 public static void main(String[] args) {
39 MyBufferedReader mbr = null;
40 try {
41 mbr = new MyBufferedReader(new FileReader("d:\\HelloWorld.java"));
42 for (String line = null; (line = mbr.myReadLine()) != null;) {
43 System.out.println(line);// 显示效果
44 }
45 } catch (IOException e) {
46 throw new RuntimeException("读取数据失败");
47 } finally {
48 try {
49 if (mbr != null)
50 mbr.close();
51 } catch (IOException e) {
52 throw new RuntimeException("读取流关闭失败");
53 }
54 }
55 }
56 }
(六)LineNumberReader类
在BufferedReader中有个直接的子类LineNumberReader,其中有特有的方法获取和设置行号:
setLineNumber();//设置初始行号
getLineNumber();//获取行号
(七)装饰设计模式
1、对一组对象的功能进行增强时,就可以使用装饰模式来解决问题。
2、特点:装饰类通常都会通过构造方法接收被装饰的对象,基于被装饰的对象的功能,提供更强的功能。
3、“装饰和继承”的异同?
(1)相同点:进行功能的扩展和增强,
(2)区别:装饰模式比继承要灵活、避免了继承体系的臃肿,降低了类与类之间的继承关系。装饰类和被装饰的类通常都是属于一个体系,有同一个接口或父类。
注:在定义类的时候,不要以继承为主;可通过装饰设计模式进行增强类功能。灵活性较强,当装饰类中的功能不适合,可再使用被装饰类的功能。
标签:style blog color io os 使用 ar java for
原文地址:http://www.cnblogs.com/jianxingjianyuan2014/p/4004621.html