黑马程序员 IO流-->字符流
2013-04-21 15:56
567 查看
-------
android培训、java培训、期待与您交流! ----------
IO流的简单介绍
1、IO流用来处理设备之间的数据传输;
2、Java对数据的操作是通过流的方式;
3、流按流向分为:输入流和输出流,按操作数据分为:字节流和字符流;
4、IO流的四个抽象基类:字节流 InputStream OutputStream 字符流 Reader Writer
什么是输入流和输出流?
输入流和输出流均是相对于程序而言的,可以理解为从磁盘等往程序中读入数据则是输入流,从程序中往磁
盘文件中写入数据则是输出流。
什么是字节流和字符流?
字节流操作数据是以字节为单位,可以处理一些媒体数据,而一个中文最少占两个字节,如果用字节流操作
中文读入写出的是中文的一半,将会出现不可识别的乱码,所以针对一些文字数据,jdk中提供了可供操作文
字数据的字符流,字符流对象中融合了当前系统默认的码表,操作字符的时候会在码表中找到对应的数据。
字符流
数据的最常见体现形式就是文件,我们可以使用Reader和Writer下的FileReader和FileWriter来操作数据。
怎么从一个文件中往程序中读入数据:
1、创建文件输入流对象,并和指定名称的文件相关联;
2、使用对象的read等方法读入数据;
3、关闭流对象。
示例:
怎么从程序往一个文件中写入数据:
1、创建文件输出流对象;
2、使用对象的write等方法写入数据;
3、关闭流对象。
示例:
练习:将C盘一个文本文件复制到D盘。
原理:复制文件其实就是将指定的源文件读入内存中再写入到目标文件
示例:
第一种方法读取一个字符就写入目标文件一个字符,而第二种方法是先把读取的字符存入一个缓冲区,存满
后一次性写入到目标文件中,这样可以避免对文件系统的多次读写,从而提高效率,所以建议使用第二种方法。
字符流的缓冲区
简单介绍:
字符流的缓冲区就是对字符流的一种处理流BufferedReader和BufferedWriter,处理流对象中封装了数组,
将数据存入,再一次性取出。其实处理流就是运用了设计模式中的装饰模式,对已有对象的功能进行增强,
所以处理流必须要有要增强功能的流对象,即构造方法中需要传入相应的输入或输出流对象。
缓冲区的出现提高了流的读写效率
练习:使用处理流来拷贝文件,提高效率。
示例:
1>缓冲流要结合流才可以使用,它只是在流的基础上对流的功能进行了增强;
2>缓冲流提供了一个跨平台的行分隔符:newLine();
3>BufferedReader提供了一个一次读取一行的方法readLine();方便于对文本数据的读取;
4>readLine读取的数据不包含任何行终止符,当返回null时,表示读到文件末尾;
5>关闭缓冲流对象即是关闭了它处理的流对象资源,因为缓冲流其实就是在内存中创建一个缓冲的区域,
先把数据存入缓冲区,再进行多个字符的读写以提高文本数据的读写效率,当使用close的时候,实际上
在方法的内部关闭的是构造方法时传入的流对象,而readLine()方法实现的最终原理也是从硬盘一个一个
的读入缓冲流对象封装的字符数组,当读到行终止符时以字符串的形式返回读到的数据。
下面就readLine的原理自定义一个类MyBufferedReader,包含与readLine相同功能的方法。
示例:
最后:流一般都是以一对的形式存在的,有输入流就有输出流,例如:FileInputStream和FileOutputStream,
DataInputStream和DataOutputStream等。
android培训、java培训、期待与您交流! ----------
IO流的简单介绍
1、IO流用来处理设备之间的数据传输;
2、Java对数据的操作是通过流的方式;
3、流按流向分为:输入流和输出流,按操作数据分为:字节流和字符流;
4、IO流的四个抽象基类:字节流 InputStream OutputStream 字符流 Reader Writer
什么是输入流和输出流?
输入流和输出流均是相对于程序而言的,可以理解为从磁盘等往程序中读入数据则是输入流,从程序中往磁
盘文件中写入数据则是输出流。
什么是字节流和字符流?
字节流操作数据是以字节为单位,可以处理一些媒体数据,而一个中文最少占两个字节,如果用字节流操作
中文读入写出的是中文的一半,将会出现不可识别的乱码,所以针对一些文字数据,jdk中提供了可供操作文
字数据的字符流,字符流对象中融合了当前系统默认的码表,操作字符的时候会在码表中找到对应的数据。
字符流
数据的最常见体现形式就是文件,我们可以使用Reader和Writer下的FileReader和FileWriter来操作数据。
怎么从一个文件中往程序中读入数据:
1、创建文件输入流对象,并和指定名称的文件相关联;
2、使用对象的read等方法读入数据;
3、关闭流对象。
示例:
import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; public class FileReaderDemo { public static void main(String[] args) { FileReader reader = null; // 由于IO流在操作数据时会抛出异常,我们应该捕获并进行相应的操作 try { // 创建一个文件读取流对象,并和指定名称的文件相关联,如果文件不存在系統会抛出
// FileNotFoundException异常 reader = new FileReader("demo.txt"); /* int ch = -1; // read()一次读一个字符,当数据读完时会返回-1 while ((ch = reader.read()) != -1) { // 每读入一个字符就在控制台打印一个字符 System.out.println("ch=" + (char) ch); } */ // 定义一个字符数组,用于存储读到字符 char[] chArr = new char[1024]; // 用于存储读入char数组中字符的个数 int len = -1; while ((len = reader.read(chArr)) != -1) { // 打印读入数组中的所有字符组成的字符串 System.out.println(new String(chArr, 0, len)); } // 在关闭流资源前可以先刷新一下,把流中的数据刷入目的地 // 仅使用此方法时并不关闭流资源 // reader.flush(); } catch (FileNotFoundException e) { System.out.println("文件读取失败"); } catch (IOException e) { e.printStackTrace(); } finally { try { // 关闭流资源 reader.close(); } catch (IOException e) { System.out.println("关闭流资源失败"); } } } }
怎么从程序往一个文件中写入数据:
1、创建文件输出流对象;
2、使用对象的write等方法写入数据;
3、关闭流对象。
示例:
import java.io.FileWriter; import java.io.IOException; public class FileWriterDemo { public static void main(String[] args) { FileWriter writer = null; try { // 创建一个输出流对象,会在指定目录下创建此文件 // 如果该目录下有同名文件,将会被覆盖。 writer = new FileWriter("demo.txt"); // 如果存在此文件,想要在内容后面续写,传入FileWriter构造方法的第二个参数为true即可 // writer = new FileWriter("demo.txt",true); // 可以直接写入字符串 writer.write("afdhdj"); // 刷新流对象中的缓冲的数据,流仍然存在 // writer.flush(); } catch (IOException e) { System.out.println("写入资源失败"); } finally { try { if (writer != null) { // 关闭流资源 writer.close(); } } catch (IOException e) { System.out.println("关闭流资源失败"); } } } }
练习:将C盘一个文本文件复制到D盘。
原理:复制文件其实就是将指定的源文件读入内存中再写入到目标文件
示例:
import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; public class CopyDemo { public static void main(String[] args) { FileWriter writer = null; FileReader reader = null; try { // 创建输出流对象,并指定目标文件 writer = new FileWriter("d:\\demo.txt"); // 创建输入流对象,并与要操作的文件相关联 reader = new FileReader("c:\\demo.txt"); /* 方法1 int ch = -1; // 每从源文件中读取到一个字符就写入到目标文件中 while ((ch = reader.read()) != -1) { writer.write(ch); } */ // 方法2 char[] buf = new char[1024]; // 读入buf中的字符个数 int len = -1; while((len = reader.read(buf))!=-1){ writer.write(buf, 0, len); } } catch (IOException e) { System.out.println("文件读写失败"); } finally { // 关闭流资源 if (writer != null) { try { writer.close(); } catch (IOException e) { e.printStackTrace(); } } if (reader != null) { try { reader.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
第一种方法读取一个字符就写入目标文件一个字符,而第二种方法是先把读取的字符存入一个缓冲区,存满
后一次性写入到目标文件中,这样可以避免对文件系统的多次读写,从而提高效率,所以建议使用第二种方法。
字符流的缓冲区
简单介绍:
字符流的缓冲区就是对字符流的一种处理流BufferedReader和BufferedWriter,处理流对象中封装了数组,
将数据存入,再一次性取出。其实处理流就是运用了设计模式中的装饰模式,对已有对象的功能进行增强,
所以处理流必须要有要增强功能的流对象,即构造方法中需要传入相应的输入或输出流对象。
缓冲区的出现提高了流的读写效率
练习:使用处理流来拷贝文件,提高效率。
示例:
import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; public class CopyByBuffer { public static void main(String[] args) { // 声明输入输出流对象 FileWriter writer = null; FileReader reader = null; // 声明处理流对象 BufferedWriter bufWriter = null; BufferedReader bufReader = null; try { // 创建输出流对象,并指定目标文件 writer = new FileWriter("d:\\demo.txt"); // 创建输入流对象,并与要操作的文件相关联 reader = new FileReader("c:\\demo.txt"); // 创建处理流对象,并把要增强功能的输出流对象传入 bufWriter = new BufferedWriter(writer); bufReader = new BufferedReader(reader); // 读入内存中的数据 String line = null; // 每次从流中读一行到line中 while ((line = bufReader.readLine()) != null) { // 将内存中的数据写入流中 bufWriter.write(line); // 换行 bufWriter.newLine(); // 将流中的数据刷新到指定文件中 bufWriter.flush(); } } catch (IOException e) { System.out.println("文件读写失败"); } finally { // 关闭流资源 if (bufWriter != null) { try { bufWriter.close(); } catch (IOException e) { e.printStackTrace(); } } if (bufReader != null) { try { bufReader.close(); } catch (IOException e) { e.printStackTrace(); } } } } }注意:
1>缓冲流要结合流才可以使用,它只是在流的基础上对流的功能进行了增强;
2>缓冲流提供了一个跨平台的行分隔符:newLine();
3>BufferedReader提供了一个一次读取一行的方法readLine();方便于对文本数据的读取;
4>readLine读取的数据不包含任何行终止符,当返回null时,表示读到文件末尾;
5>关闭缓冲流对象即是关闭了它处理的流对象资源,因为缓冲流其实就是在内存中创建一个缓冲的区域,
先把数据存入缓冲区,再进行多个字符的读写以提高文本数据的读写效率,当使用close的时候,实际上
在方法的内部关闭的是构造方法时传入的流对象,而readLine()方法实现的最终原理也是从硬盘一个一个
的读入缓冲流对象封装的字符数组,当读到行终止符时以字符串的形式返回读到的数据。
下面就readLine的原理自定义一个类MyBufferedReader,包含与readLine相同功能的方法。
示例:
import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.io.Reader; /** * 自定义一个功能与BufferedReader相似的类,继承Reader 对象中包含一个输入流对象 */ class MyBufferedReader extends Reader { private Reader r; // 构造方法,需要传入一个输入流对象 // 这里用到了多态,父类引用指向子类对象 public MyBufferedReader(Reader r) { this.r = r; } @Override public int read(char[] cbuf, int off, int len) throws IOException { // 直接调用的是输入流对象的方法 return r.read(cbuf, off, len); } @Override public void close() throws IOException { // 从这也可以看出,当调用缓冲区的close的方法时,直接关闭的是传入的输入流的资源 r.close(); } // 重写一个方法来实现readLine方法的功能,并抛出异常由调用者去处理 public String myReadLine() throws IOException { // 定义一个缓冲区,readLine是用数组来实现的 StringBuilder builder = new StringBuilder(); int ch = -1; while ((ch = r.read()) != -1) { // 如果读到\r字符,则继续读下个字符,并不存入缓冲区 if (ch == '\r') { continue; } if (ch == '\n') { // 当读到换行符时,将缓冲区中的数据以字符串形式返回 return builder.toString(); } else { // 将读取的字符存入缓冲区 builder.append((char) ch); } // 如果最后一行并没有行终止符,那么将缓冲区的数据返回 if (builder != null) { return builder.toString(); } } // 读到结尾,返回null return null; } } // 测试类 public class MyBufferedDemo { public static void main(String[] args) { MyBufferedReader bufferedReader = null; try { // 创建一个自定义的缓冲流 bufferedReader = new MyBufferedReader(new FileReader("demo.txt")); String line = null; // 使用自己创建的方法来读取一行的数据 while ((line = bufferedReader.myReadLine()) != null) { System.out.println(line); } } catch (FileNotFoundException e) { System.out.println("文件读取失败"); } catch (IOException e) { System.out.println("文件读取失败"); } finally { // 关闭流资源 try { bufferedReader.close(); } catch (IOException e) { System.out.println("关闭流资源失败"); } } } }
最后:流一般都是以一对的形式存在的,有输入流就有输出流,例如:FileInputStream和FileOutputStream,
DataInputStream和DataOutputStream等。
相关文章推荐
- HTML 字符实体 < >: &等
- <BIO>以字节的方式(写入,读取)文本,以字符的方式(写入,读取)文本和<NIO>的写入,读取
-  |"|&|<|>等html字符转义
- Linux 设备驱动 ====> 字符驱动
- 面试题 <第一个只出现一次的字符>(11)
- ASCII+Unicode+UTF8(字符编码方式->字节) Base64(字节编码方式->64字符)
- Linux-->图形界面与字符界面相互切换
-  |"|&|<|>等html字符转义
- Post传值时间特殊字符处理比如 "<p></p>"当作参数传递到后台
- XML解析时候因为特殊字符&,<,>,",'出错
- (KMP 1.4)hdu 3746 Cyclic Nacklace(使用next数组来求循环节的长度——求一个字符串需要添加多少个字符才能使该字符串的循环节的个数>=2)
- Mac下关于->您不能拷贝项目“”,因为它的名称太长或包括的字符在目的宗卷上无效。<-的删除
- 从0开始<五>:字符串相关-htoi函数,删除字符串中指定字符
- 网络字节转换函数--IP地址转换--字符->int_32
- <class 'suds.sax.text.Text'> 类型转换字符类型
- 使用<a>标签调用struts2的action、传递动态参数、以及参数中出现加号等特殊字符的处理方法
- Gson 的tojson方法 特殊字符 ' ' < > 转换问题
- Linux界面切换:图形界面<——>字符界面
- 在字符串中使用特殊字符<>"'&空格
- $str_2 = "str_1 : ${str_1}2 <br>"; //引用的变量名后,多了个字符2 即$str_12