学习网站
IO(Input Output)流
IO流用来处理设备之间的数据传输
Java对数据的操作是通过流的方式
Java用于操作流的对象都在IO包中
流按操作数据分为两种:字节流与字符流。
流按流向分为:输入流,输出流。
ASCII 读的目标是相对于内存
字符流由来就是:早期的字节流+编码表,为了更便于操作文字数据。
记住:只要是操作字符数据,应该优先使用字符流。
IO流常用基类
l 字节流的抽象基类:
• InputStream ,OutputStream。
l 字符流的抽象基类:
• Reader , Writer。
l 注:由这四个类派生出来的子类名称都是以其父类名作为子类名的后缀。
• 如:InputStream的子类FileInputStream。
• 如:Reader的子类FileReader。
l 四个体系中的子类们,后缀名都是父类名。前缀名都是这个子类的功能。
IO程序的书写
导入IO包中的类
进行IO异常处理
在finally中对流进行关闭
思考:
有了垃圾回收机制为什么还要调用close方法进行关闭。
为什么IO异常一定要处理。
字符流——创建文件
创建流对象,建立数据存放文件
FileWriterfw = new FileWriter(“Test.txt”);
调用流对象的写入方法,将数据写入流
fw.write(“text”);
关闭流资源,并将流中的数据清空到文件中。
fw.close();
不写close方法会有什么结果呢?
如果想在原有文件上继续加入新的数据呢?
package com.jiangyi.io;
import java.io.FileWriter;
import java.io.IOException;
public class FileWriterDemo1 {
public FileWriterDemo1() {
// TODO Auto-generated constructor stub
}
public static void main(String[] args) throws Exception {
/*
* 需求:将内存中的字符串数据写入到硬盘上。 1,内存数据到硬盘,应该是输出,也就是写。需要使用输出流。 2,要操作的是文本数据。应该字符流。
* 3,综上所述,应该使用字符输出流。Writer。 4,因为是将数据写到硬盘上,而硬盘存储数据的方式就是文件。
* 5,应该找一个可以操作文件的字符输出流对象。找到了FileWriter。
*/
/*
* 1,创建FileWriter对象。 创建对象,运行时就会创建指定的文件,因为写入数据必须先有数据存储的目的。
* 如果要创建的文件已经存在,则会覆盖。
*/
FileWriter fw = new FileWriter("jiangyi.txt");
// 2,写入一个字符串。写入到了缓冲区中。
fw.write("this is a demo");
// 3,使用flush方法。将缓冲中的数据写入到目的地中。
fw.flush();
// 4,关闭 close
fw.close();
/*
* close()和flush()的区别? 1,调用flush,可以将数据刷到目的地中,流依然存在,可以继续使用。
* 调用close,可以将数据刷到目的地中,流已被关闭。不能继续使用。最后使用。 2,close不仅刷新缓冲区,还关闭底层资源。
*/
}
}
/*
* 如果在构造时,传入第二个参数为true,将在原有文件末尾处进行续写。
*/
FileWriter fw = new FileWriter("demo.txt",true);
字符流——读取文件
建立一个流对象,和指定的文件数据关联。
FileReader fr = new FileReader(“Test.txt”);
创建一个临时存放数据的数组。
char[] ch = new char[1024];
调用流对象的读取方法将流中的数据读入到数组中。
fr.read(ch);
思考:
在加载文件时候是否是将文件全部加载进流
为什么定义数组,要定义多大呢?
FileReader fr = new FileReader(“Test.txt”);
创建一个临时存放数据的数组。
char[] ch = new char[1024];
调用流对象的读取方法将流中的数据读入到数组中。
fr.read(ch);
思考:
在加载文件时候是否是将文件全部加载进流
为什么定义数组,要定义多大呢?
定义文件路径时,可以用“/”或者“\\”。
在创建一个文件时,如果目录下有同名文件将被覆盖。
在读取文件时,必须保证该文件已存在,否则出异常。
在创建一个文件时,如果目录下有同名文件将被覆盖。
在读取文件时,必须保证该文件已存在,否则出异常。
@Test
public void readFile() {
/*
* 需求:读取一个已有的文本文件,将读到的数据打印到控制台(屏幕)。 思路: 1,应该是将硬盘的数据读去到内存中,使用输入流。
* 2,操作的数据是文本数据,应该使用字符流更为便捷。 3,即使输入,又是字符,应该是字符输入流:Reader
* 4,要用到字符输入流的哪个功能对象呢?操作文件的,FileReader 。
*/
// 1,创建FileReader对象。 并通过构造函数明确数据源。
// 创建读取对象,和数据源相关联。
FileReader fr = null;
try {
fr = new FileReader("temp\\demo.txt");
// 2,调用Reader中的read方法,一次读取一个字符。
// 3,使用循环解决问题。
int ch = 0;
while ((ch = fr.read()) != -1) {
System.out.println((char) ch);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
System.exit(-1);
} catch (IOException e) {
e.printStackTrace();
} finally {
// 4,关闭资源。
if (fr != null) {
try {
fr.close();
} catch (IOException e) {
System.exit(-1);
e.printStackTrace();
}
}
}
}
讲数据读到数组中
@Test
public void readInbuffer() throws Exception {
/*
* read(char[]);
*/
// 1,创建读取流对象和数据源关联。
FileReader fr = new FileReader("temp\\demo.txt");
// 2,创建一个字符数组。用于存储读到字符数据。
<span style="color:#ff0000;">char[] buffer = new char[1024];// </span>一般定义的都是1024的整数倍。
// 3,调用读取流的read(char[]),将读到的字符存储到字符数组中。
/*
* int len1 = fr.read(buffer); System.out.println("len1="+len1+";"+new
* String(buffer)); int len2 = fr.read(buffer);
* System.out.println("len2="+len2+";"+new String(buffer)); int len3 =
* fr.read(buffer); System.out.println("len3="+len3+";"+new
* String(buffer)); int len4 = fr.read(buffer);
* System.out.println("len4="+len4+";"+new String(buffer));
*/
// 4,循环。
int len = 0;
while ((len = <span style="color:#ff0000;">fr.read(buffer)</span>) != -1) {
System.out.println(new String(buffer, 0, len));
}
fr.close();
}
文件复制
public static void copyText() throws IOException {
//较低效
//1,创建一个字符读取流和指定的源相关联。
FileReader fr = new FileReader("temp\\CopytTextTest.java");
//2,确定数据存储的目的。
FileWriter fw = new FileWriter("temp\\demo_copy.txt");
//3,读一个写出去。有很多字符,需要循环。 当读取动作返回-1,说明结束。
int ch = 0;
while((ch=fr.read())!=-1){
fw.write(ch);
}
//4,关闭资源。
fw.close();
fr.close();
}
public static void copyText2() {
/*
* 复制使用数组缓冲区完成。教搞笑
*
*/
//1,创建读取流和写入流。
FileReader fr = null;
FileWriter fw = null;
try {
fr = new FileReader("temp\\CopytTextTest.java");
fw = new FileWriter("temp\\demo_copy2.txt");
//定义一个缓冲区数组。
char[] buf = new char[1024];
int len = 0;
while((len=fr.read(buf))!=-1){
fw.write(buf,0,len);//读取几个就写几个。
}
} catch (Exception e) {
e.printStackTrace();
}finally{
if(fw!=null)
try {
fw.close();
} catch (Exception e2) {
throw new RuntimeException("写入关闭失败");
}
if(fr!=null)
try {
fr.close();
} catch (Exception e2) {
throw new RuntimeException("读取关闭失败");
}
}
}
字符流的缓冲区
缓冲区的出现提高了对数据的读写效率。
对应类
BufferedWriter
BufferedReader
缓冲区要结合流才可以使用。
在流的基础上对流的功能进行了增强。
对应类
BufferedWriter
BufferedReader
缓冲区要结合流才可以使用。
在流的基础上对流的功能进行了增强。
@Test
public void bufferWriter() throws Exception{
/*
* 演示BufferedWriter.
* 缓冲区是对流中的数据进行缓冲的。所以必须要在构造缓冲区时,明确具体的流对象。
*/
//1,创建字符输出流对象;
FileWriter fw = new FileWriter("temp\\buf.txt");
//2,创建缓冲区对象,将流对象传给缓冲区的构造函数。
BufferedWriter bufw = new BufferedWriter(fw);
// BufferedWriter bufw=new BufferedWriter(new FileWriter("temp\\buf.txt"));
for(int x=1; x<=4; x++){
bufw.write(x+"-hehe");
bufw.newLine();
bufw.flush();//一旦使用了缓冲区 需要刷新
}
bufw.close();//不用在对fw进行关闭,因为关闭缓冲区的就是在关闭该流。
}
@Test
public void bufferReader() throws Exception {
/*
* 字符输入流缓冲区演示BufferedReader.
*/
// 1,创建字符输入流对象。
FileReader fr = new FileReader("temp\\buf.txt");
// 2,创建字符输入流缓冲区对象。
BufferedReader bufr = new BufferedReader(fr);
// BufferedReader bufr=new BufferedReader(new
// FileReader("temp\\buf.txt"));
// 3,使用BufferedReader的特有方法,一次读一行。
// String line = bufr.readLine();
// System.out.println(line);
String line = null;
while ((line = bufr.readLine()) != null) {
System.out.<span style="color:#ff6666;">print</span>(line);
}
bufr.close();
}
通过缓冲io对象复制文件
public static void copyTextByBuffer() throws IOException {
//1,创建流对象和缓冲区对象。
FileReader fr = new FileReader("temp\\buf.txt");
BufferedReader bufr = new BufferedReader(fr);
FileWriter fw = new FileWriter("temp\\buf_copy.txt");
BufferedWriter bufw = new BufferedWriter(fw);
//2,对一行文本进行读写。
String line = null;
while((line=bufr.readLine())!=null){
bufw.write(line);
bufw.newLine();
bufw.flush();
}
bufw.close();
bufr.close();
}
装饰设计模式
l对原有类进行了功能的改变,增强。
l装饰模式的基本格式。
l它与继承有什么不同?
l
了解
BufferedReader
的原理.
<span style="font-size:18px;">public class WrapperDemo {
/**
* @param args
*/
public static void main(String[] args) {
Person p = new Person();
// NewPerson p = new NewPerson();
NewPerson pp = new NewPerson(p);
pp.chifan();
/*
* 装饰模式:为了解决给类的功能进行增强而出现的。
*
* Writer
* |--TextWriter
* |--MediaWriter
*
* 想要对流对象的功能进行增强,比如提高写入的效率。
* 使用缓冲技术。
* Writer
* |--TextWriter
* |--BufferedTextWriter
* |--MediaWriter
* |--BufferedMediaWriter
*
* 每一个子类这样实现是可以的,但是导致继承体系较为臃肿。
* 发现其实无论哪个子类需要高效,使用的都是缓冲技术。
* 干脆将缓冲技术进行单独的描述和封装。
* 要缓冲区谁,就将谁传给缓冲区。
* BufferdWriter
*
* class BufferedWriter extends Writer
* {
* BufferedWriter(Writer w)
* {}
* }
*
* 装饰设计模式。
* Writer
* |--TextWriter
* |--MediaWriter
* |--BufferedWriter
*
* 装饰类和被装饰的特点:
* 1,装饰类中的构造函数需要接受被装饰类。
* 2,装饰类和被装饰类应该所属于同一个体系。
*
*/
}
}
class Person{
void chifan(){
System.out.println("吃饭");
}
}
class NewPerson{
private Person p ;
NewPerson(Person p){
this.p = p;
}
public void chifan(){
System.out.println("开胃酒");
p.chifan();
System.out.println("甜点");
System.out.println("来一根");
}
}
/*
class NewPerson extends Person{
@Override
void chifan() {
System.out.println("开胃酒");
super.chifan();
System.out.println("甜点");
System.out.println("来一根");
}
}
*/
</span>
字节流
基本操作与字符流类相同
但它不仅可以操作字符,还可以操作其他媒体文件
<span style="white-space:pre"> </span>@Test
public void writeFile() throws IOException {
/*
* 将内存中的数据写到硬盘上。
* 1,输出。
* 2,文件。
* 3,因为要演示字节流所以要找一个能处理文件的字节输出流。
*/
// FileOutputStream fos = new FileOutputStream("temp\\fos.txt");
FileOutputStream out=new FileOutputStream("temp/fos.txt");
//使用流对象write方法,将数据写入到目的地。
byte[] buf = "abc".getBytes();
out.write(buf);//直接可以将数据写入到目的地。
//关闭资源。
out.close();
}
<span style="font-size:18px;"><span style="white-space:pre"> </span>@Test
public void readFile2() throws IOException {
FileInputStream fis = new FileInputStream("temp\\fos.txt");
// System.out.println(fis.available());//获取文件的字节数。
// byte[] buf = new byte[fis.available()];//以它作为缓冲区的长度是不合适
// fis.read(buf);
// System.out.println(new String(buf));
//创建一个缓冲区。缓冲读到的字节。
byte[] buf = new byte[1024];
int len = 0;
while((len=fis.read(buf))!=-1){
System.out.println(new String(buf,0,len));
}
fis.close();
}
</span>
字节流的缓冲区
l同样是提高了字节流的读写效率。
</pre><pre code_snippet_id="112313" snippet_file_name="blog_20131217_13_3916749" name="code" class="java"> <span style="font-size:18px;">public static void copyPic2() throws IOException {//速度较快
FileInputStream fis = new FileInputStream("temp\\0.bmp");
FileOutputStream fos = new FileOutputStream("temp\\2.bmp");
BufferedInputStream bufis = new BufferedInputStream(fis);
BufferedOutputStream bufos = new BufferedOutputStream(fos);
byte[] buf = new byte[1024];
int by = 0;
while((by=bufis.read())!=-1){//从内存中读 速度快
bufos.write(by);
}
bufos.close();
bufis.close();
}</span>
转换流
InputStreamReader,OutputStreamWriter
转换流的由来
字符流与字节流之间的桥梁
方便了字符流与字节流之间的操作
转换流的应用
字节流中的数据都是字符时,转成字符流操作更高效。
例程:标准输入输出。
标准输入输出流
转换流的由来
字符流与字节流之间的桥梁
方便了字符流与字节流之间的操作
转换流的应用
字节流中的数据都是字符时,转成字符流操作更高效。
例程:标准输入输出。
字符通向字节的桥梁
将字符转换为字节 OutputStreamWriter
package cn.itcast.io.p3.transstream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import org.junit.Test;
public class TransStream_WriterDemo {
/**
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
/*
* 演示转换流。
*/
// writeFile();
}
/*
* 第一个,先将已有的中文字符串,按照编码存储到硬盘上。
*/
public static void writeFile() throws IOException{
//使用默认 编码表。
// FileWriter fw = new FileWriter("temp\\default.txt");
// fw.write("你好");
// fw.close();
//使用转换流,通过默认编码表。将字符转换成字节 转换流。OutputStreamWriter
// FileOutputStream fos = new FileOutputStream("temp\\trans_default.txt");
// OutputStreamWriter osw = new OutputStreamWriter(fos);
// osw.write("你好");
// osw.close();
//使用指定编码表GBK。
// FileOutputStream fos = new FileOutputStream("temp\\trans_GBK.txt");
// OutputStreamWriter osw = new OutputStreamWriter(fos,"GBK");
// osw.write("你好");
// osw.close();
/*
转换流:字节流+编码表(可以指定)。
|--用于操作File的子类:字节流+本地默认码表(固定)。对默认编码的字符文件操作起来比父类更为便捷。
*/
//使用指定编码表UTF-8。
FileOutputStream fos = new FileOutputStream("temp\\trans_U8.txt");
OutputStreamWriter osw = new OutputStreamWriter(fos,"UTF-8");
osw.write("你好");
osw.close();
}
@Test
public void name() throws Exception {
OutputStreamWriter outputStreamWriter=new OutputStreamWriter(new FileOutputStream("temp\\trans_U8.txt"),"utf-8");
outputStreamWriter.write("你好");
outputStreamWriter.close();
}
}
字节通向字符的桥梁
将字节转换为字符 InputStreamReader
package cn.itcast.io.p3.transstream;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class TransStream_ReaderDemo {
/**
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
/*
* 演示转换流 字节-->字符。
*/
readFile();
}
public static void readFile() throws IOException {
//1,读取已有的字符文件。为指定过编码。
// FileReader fr = new FileReader("temp\\default.txt");
// char[] buf = new char[1024];
// int len = fr.read(buf);
// String str = new String(buf,0,len);
// System.out.println(str);
// int ch1 = fr.read();
// System.out.println((char)ch1);
// int ch2 = fr.read();
// System.out.println((char)ch2);
// int ch3 = fr.read();
// System.out.println(ch3);
// fr.close();
//2,既然是存储到硬盘的都是字节数据。干脆就使用字节流读不就哦了吗。
//不行,因为读取到的都是字节数据,没有查表,无法获取对应的文字。
//所以应该将字节转成字符数据,使用转换流完成 InputStreamReader.
// FileInputStream fis = new FileInputStream("temp\\trans_default.txt");
// InputStreamReader isr = new InputStreamReader(fis,"gbk");//使用的默认的字符集。或者使用gbk的码表
// int ch1 = isr.read();
// System.out.println((char)ch1);
// int ch2 = isr.read();
// System.out.println((char)ch2);
// int ch3 = isr.read();
// System.out.println(ch3);
// isr.close();
/*FileInputStream fis = new FileInputStream("temp\\default.txt");
int ch1 =fis.read();
System.out.println(ch1);
int ch2 =fis.read();
System.out.println(ch2);
int ch3 =fis.read();
System.out.println(ch3);
int ch4 =fis.read();
System.out.println(ch4);
int ch5 =fis.read();
System.out.println(ch5);
fis.close();
*/
FileInputStream fis = new FileInputStream("temp\\trans_U8.txt");
InputStreamReader isr = new InputStreamReader(fis,"utf-8");
char[] buf = new char[1024];
int len = isr.read(buf);
String str = new String(buf,0,len);
System.out.println(str);
isr.close();
}
}<h2>
</h2>
标准输入输出流
System类中的字段:in,out。
它们各代表了系统标准的输入和输出设备。
默认输入设备是键盘,输出设备是显示器。
System.in的类型是InputStream.
System.out的类型是PrintStream是OutputStream的子类FilterOutputStream 的子类.
例:获取键盘录入数据,然后将数据流向显示器,那么显示器就是目的地。
通过System类的setIn,setOut方法对默认设备进行改变。
System.setIn(new FileInputStream(“1.txt”));//将源改成文件1.txt。
System.setOut(new PrintStream(“2.txt”));//将目的改成文件2.txt
因为是字节流处理的是文本数据,可以转换成字符流,操作更方便。
BfferedReader bufr =
new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bufw =
new BufferedWriter(new OutputStreamWriter(System.out));
它们各代表了系统标准的输入和输出设备。
默认输入设备是键盘,输出设备是显示器。
System.in的类型是InputStream.
System.out的类型是PrintStream是OutputStream的子类FilterOutputStream 的子类.
例:获取键盘录入数据,然后将数据流向显示器,那么显示器就是目的地。
通过System类的setIn,setOut方法对默认设备进行改变。
System.setIn(new FileInputStream(“1.txt”));//将源改成文件1.txt。
System.setOut(new PrintStream(“2.txt”));//将目的改成文件2.txt
因为是字节流处理的是文本数据,可以转换成字符流,操作更方便。
BfferedReader bufr =
new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bufw =
new BufferedWriter(new OutputStreamWriter(System.out));
//获取System中标准的输入流对象。
InputStream in = System.in;
// int ch1 = in.read();
// System.out.println("ch1="+ch1);
// int ch2 = in.read();
// System.out.println("ch2="+ch2);
// int ch3 = in.read();
// System.out.println("ch3="+ch3);
// int ch4 = in.read();
// System.out.println("ch4="+ch4);
// System.out.println((int)'\r');
// System.out.println((int)'\n');
//in.close();可以不用关闭,如果关闭,就无法继续获取了。
}
IO流的操作规律
字符流:
FileReader
FileWriter
BufferedReader
BufferedWriter
InputStreamReader
OutputStreamWriter
字节流:
FileInputStream
FileOutputStream
BufferedInputStream
BufferedOUtputStream
//疑问:开始时,用哪个流对象解决问题呢?
明确一:明确源和目的。
源:就需要读,就需要使用输入体系。InputStream Reader
目的:就需要写,就需要使用输出体系。OutputStream Writer
明确二:处理的数据是否是纯文本数据。
是:就使用字符流。
源:Reader
目的:Writer
否:就是用字节流。
源:InputStream
目的:OutputStream
两个明确都确定后,可以确定需要使用哪个体系。
明确三:具体是哪个设备,明确设备的目的是为了确定具体的对象。
源设备:
键盘,System.in
硬盘,操作文件的对象。File开头的流对象。
内存,数组。
网络,Socket
目的设备:
硬盘,操作文件的对象。File开头的流对象。
屏幕(控制台)System.out
内存,数组
网络,Socket
需求:将字符串数据写到硬盘上。
目的:OutputStream Writer
纯文本?是,Writer
设备?硬盘,FileWriter
FileWriter fw = new FileWriter("a.txt");
明确四:是否需要额外功能?
1,需要高效吗?Buffered
2,需要字节和字符之间的桥梁吗?转换流。
3,待续...
---------------------------------------------------
需求1:对文本文件进行复制。
明确1:源和目的。
源:InputStream Reader
目的:OutputStream Writer
明确2:是否是纯文本。
是!
源:Reader
目的:Writer
明确3:具体的设备。
源:硬盘。
目的:硬盘。
FileReader fr = new FileReader("a.txt");
FileWriter fw = new FileWriter("b.txt");
明确4:额外功能。
需要,高效。
BufferedReader bufr = new BufferedReader(new FileReader("a.txt"));
BufferedWriter bufw = new BufferedWriter(new FileWriter("b.txt"));
当然如果仅为复制文件,在该例中可以使用字节流完成。
需求2:读取键盘录入数据并保存到文件中。
明确1:源,目的。
源:InputStream Reader
目的:OutputStream Writer
明确2:是纯文本。
是!
源:Reader
目的:Writer
明确3:具体设备。
源设备:键盘。
目的设备:硬盘。
InputStream in = System.in;
//byte[] buf = new byte[1024];
//int len = in.read(buf);
//str = new String(buf);
FileWriter fw = new FileWriter("a.txt");
fw.write(str);
虽然可以用该代码完成,但是麻烦。
解决问题,源是字节流,目的是字符流。而最终确定的都是字符流体系。
源使用的Reader就可以了。那么怎么能将源字节流转成字符流呢?
明确4:额外功能?
需要,转换。将字节流转成字符流。
InputStreamReader isr = new InputStreamReader(System.in);
FileWriter fw = new FileWriter("a.txt");
这时就需要定义一个字符数据作为缓冲。
还需要其他功能吗?需要,高效。
BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));//以后获取键盘录入,就使用该句。
BufferedWriter bufw = new BufferedWriter(new FileWriter("a.txt"));
String line = null;
while((line=bufr.readLine())!=null)
{
if("over".equals(line))
break;
bufw.write(line);
bufw.newLine();
bufw.flush();
}
需求3:读取硬盘上的文本文件将数据打印到屏幕上。
明确1:源,目的。
源:InputStream Reader
目的:OutputStream Writer
明确2:纯文本?
是!
源:Reader
目的:Writer。
明确3:具体设备:
源设备:硬盘。
目的设备:屏幕。
FileReader fr = new FileReader("a.txt");
PrintStream out = System.out;
明确4:额外功能。
高效!
BufferedReader bufr = new BufferedReader(new FileReader("a.txt"));
也希望目的也高效。想使用字符流的缓冲区对其高效。而System.out是字节流。
读到的字符,最终要转成成字节流,到System.out屏幕上。
需要用字符转成字节的桥梁。
BufferedWrier bufw = new BufferedWriter(new OutputStreamWriter(Sysetm.out));
需求4:读取一个文本文件,将数据转成UTF-8保存到另一个文件中。
明确1:源,目的。
源:InputStream Reader
目的:OutputStream Writer
明确2:纯文本?
是!
源:Reader
目的:Writer。
明确3:具体设备。
源:硬盘。
目的:硬盘。
FileReader fr = new FileReader("a.txt");
FileWriter fw = new FileWriter("b.txt");
不行!
源可以使用FileReader,因为可以使用默认本地编码。
而目的明确指定了编码表。就不可以使用FileWriter。
在字符转成字节的过程,需要加入编码。
明确4:需要额外功能?
需要,转换。
FileReader fr = new FileReader("a.txt");
//要转成可以操作文件的字节流。
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("b.txt"),"UTF-8");
还需要额外功能吗?
需要,高效。
BufferedReader bufr = new BufferedReader(new FileReader("a.txt"));
BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("b.txt"),"utf-8"));
-------------------------------------------------------
练习:读取键盘录入,将读取的数据进行临时存储,如果存储的数据是over。则键盘录入结束。
如果不是,则将数据转成大写显示在屏幕上。
如果不用readLine,你怎么做呢?
预习:自己演示一下File类中的list listFiles方法。尤其是带着过滤器的方法。
FileReader
FileWriter
BufferedReader
BufferedWriter
InputStreamReader
OutputStreamWriter
字节流:
FileInputStream
FileOutputStream
BufferedInputStream
BufferedOUtputStream
//疑问:开始时,用哪个流对象解决问题呢?
明确一:明确源和目的。
源:就需要读,就需要使用输入体系。InputStream Reader
目的:就需要写,就需要使用输出体系。OutputStream Writer
明确二:处理的数据是否是纯文本数据。
是:就使用字符流。
源:Reader
目的:Writer
否:就是用字节流。
源:InputStream
目的:OutputStream
两个明确都确定后,可以确定需要使用哪个体系。
明确三:具体是哪个设备,明确设备的目的是为了确定具体的对象。
源设备:
键盘,System.in
硬盘,操作文件的对象。File开头的流对象。
内存,数组。
网络,Socket
目的设备:
硬盘,操作文件的对象。File开头的流对象。
屏幕(控制台)System.out
内存,数组
网络,Socket
需求:将字符串数据写到硬盘上。
目的:OutputStream Writer
纯文本?是,Writer
设备?硬盘,FileWriter
FileWriter fw = new FileWriter("a.txt");
明确四:是否需要额外功能?
1,需要高效吗?Buffered
2,需要字节和字符之间的桥梁吗?转换流。
3,待续...
---------------------------------------------------
需求1:对文本文件进行复制。
明确1:源和目的。
源:InputStream Reader
目的:OutputStream Writer
明确2:是否是纯文本。
是!
源:Reader
目的:Writer
明确3:具体的设备。
源:硬盘。
目的:硬盘。
FileReader fr = new FileReader("a.txt");
FileWriter fw = new FileWriter("b.txt");
明确4:额外功能。
需要,高效。
BufferedReader bufr = new BufferedReader(new FileReader("a.txt"));
BufferedWriter bufw = new BufferedWriter(new FileWriter("b.txt"));
当然如果仅为复制文件,在该例中可以使用字节流完成。
需求2:读取键盘录入数据并保存到文件中。
明确1:源,目的。
源:InputStream Reader
目的:OutputStream Writer
明确2:是纯文本。
是!
源:Reader
目的:Writer
明确3:具体设备。
源设备:键盘。
目的设备:硬盘。
InputStream in = System.in;
//byte[] buf = new byte[1024];
//int len = in.read(buf);
//str = new String(buf);
FileWriter fw = new FileWriter("a.txt");
fw.write(str);
虽然可以用该代码完成,但是麻烦。
解决问题,源是字节流,目的是字符流。而最终确定的都是字符流体系。
源使用的Reader就可以了。那么怎么能将源字节流转成字符流呢?
明确4:额外功能?
需要,转换。将字节流转成字符流。
InputStreamReader isr = new InputStreamReader(System.in);
FileWriter fw = new FileWriter("a.txt");
这时就需要定义一个字符数据作为缓冲。
还需要其他功能吗?需要,高效。
BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));//以后获取键盘录入,就使用该句。
BufferedWriter bufw = new BufferedWriter(new FileWriter("a.txt"));
String line = null;
while((line=bufr.readLine())!=null)
{
if("over".equals(line))
break;
bufw.write(line);
bufw.newLine();
bufw.flush();
}
需求3:读取硬盘上的文本文件将数据打印到屏幕上。
明确1:源,目的。
源:InputStream Reader
目的:OutputStream Writer
明确2:纯文本?
是!
源:Reader
目的:Writer。
明确3:具体设备:
源设备:硬盘。
目的设备:屏幕。
FileReader fr = new FileReader("a.txt");
PrintStream out = System.out;
明确4:额外功能。
高效!
BufferedReader bufr = new BufferedReader(new FileReader("a.txt"));
也希望目的也高效。想使用字符流的缓冲区对其高效。而System.out是字节流。
读到的字符,最终要转成成字节流,到System.out屏幕上。
需要用字符转成字节的桥梁。
BufferedWrier bufw = new BufferedWriter(new OutputStreamWriter(Sysetm.out));
需求4:读取一个文本文件,将数据转成UTF-8保存到另一个文件中。
明确1:源,目的。
源:InputStream Reader
目的:OutputStream Writer
明确2:纯文本?
是!
源:Reader
目的:Writer。
明确3:具体设备。
源:硬盘。
目的:硬盘。
FileReader fr = new FileReader("a.txt");
FileWriter fw = new FileWriter("b.txt");
不行!
源可以使用FileReader,因为可以使用默认本地编码。
而目的明确指定了编码表。就不可以使用FileWriter。
在字符转成字节的过程,需要加入编码。
明确4:需要额外功能?
需要,转换。
FileReader fr = new FileReader("a.txt");
//要转成可以操作文件的字节流。
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("b.txt"),"UTF-8");
还需要额外功能吗?
需要,高效。
BufferedReader bufr = new BufferedReader(new FileReader("a.txt"));
BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("b.txt"),"utf-8"));
-------------------------------------------------------
练习:读取键盘录入,将读取的数据进行临时存储,如果存储的数据是over。则键盘录入结束。
如果不是,则将数据转成大写显示在屏幕上。
如果不用readLine,你怎么做呢?
预习:自己演示一下File类中的list listFiles方法。尤其是带着过滤器的方法。
字符流继承体系简图
字节流继承体系简图