------- android培训、java培训、期待与您交流! ----------
第一节:io流的概述
一、概述:
1、io流用来处理设备之间的数据传输。
比如:上传文件和下载文件。
2、java对数据的操作是同过流的方式。
3、java用于操作流的对象都在io包中。
二、io的分类:
1、按照数据流向
(1)输入流 读取数据
(2)输出流 写出数据
2、按照数据类型
(1)字节流
(2)字符流
注:(1)如果我们没有明确说明按照什么分,默认按照数据类型分。
(2)除非文件用windows自带的记事本打开我们能够读懂,才采用字符流,否则建议使用字节流。
三、io流常用的基类
1、字节流的抽象基类:
InputStream , OutputStream
2、字符流的抽象基类:
Reader , Writer
注:由这四个类派生出来的子类名称都是以其父类名作为子类名的后缀。
(1)例如:OutputStream的子类FileOutputStream
(2)例如:Reader的子类FileReader
第二节:字符流
一、简述:
1、字符流只能处理文字数据,而字节流也可以处理媒体数据。(字节流操作中文数据不是特别的方便,所以就出现了转换流,转换流的作用就是把字节流转换字符流来使用。)
所以可以说:字符流 = 字节流 + 编码表
2、字符流中的对象融合了编码表。使用的是默认的编码,即当前系统的编码。
3、常见的编码表:
GBK:目前最常用的中文码表,2万的中文和符号。用两个字节表示,一部分文字,第一个字节开头是1,第二字节开头是0。
unicode:国际标准码表:无论是什么文字,都用两个字节存储。
UTF-8:基于unicode,一个字节就可以存储数据,不要用两个字节存储,而且这个码表更加的标准化,在每一个字节头加入了编码信息。
IOS8859-1:拉丁码表 latin,用了一个字节用的8位。1-xxxxxxx 负数。
注:编码表:其实就是生活中文件和计算机二进制的对应关系表。
4、常见的字符流
Reader
|--InputStreamReader
|--FileReader
|--BufferedReader
Writer
|--OutputStreamWriter
|--FileWriter
|--BufferedWriter
二、字符流的操作;
代码体现
//需求:将盘中的一个文件进行复制。
//思路:1 首先创建Filereader对象去关联一个文件
//2 用read方法读取文件中的数据,,,定义一个数组
//3 在创建一个FileWriter对象把读取出的数据写出去
import java.io.*;
class Demo1
{
public static void main(String[] args)throws IOException
{
//调用函数
copyIo();
}
public static void copyIo()throws IOException//一个一个的读,一个一个的写进去
{
//创建Filereader对象去关联一个文件
FileReader fr = new FileReader ("fw.txt");
//在创建一个FileWriter对象写入数据的目的
FileWriter fw = new FileWriter("fr.txt");
//定义一个标记
int num =0;
//一个一个的读
while ((num = fr.read())!=-1)
{
//一个一个的写,
fw.write(num);
//进行刷新
fw.flush();
}
//进行关闭资源
fw.close();
fr.close();
}
}
第三讲:字符流缓冲区
一、字符流缓冲区:
BufferedReader与BufferedWriter
1、字符流缓冲区的特点:创建字符流缓冲区需要流,能提高流的读写效率,并且也有自己独特的换行方法,(写入时需要刷新操作)操作它实质上就是对流进行操作的,关闭它就相当于关闭了流。
2、缓冲技术的原理:其实就是对象中封装了数组,对数据的存入与取出。
二、字符流缓冲区的操作:
1、用缓冲技术复制一个文本文件
代码体现
/*需求1 复制一个文本文件
思路:1、源是一个文件 目的是一个文件。并且需要高效
2、源;是一个文件 用FileReader去关联一个文件 又因为需要高效 BufferedReader
3、目的:是一个文件 FileWriter去写入一个文件 又需要高效 BufferedWriter
4、关闭资源。
*/
import java.io.*;
class Demo1
{
public static void main(String[] args)throws IOException
{
//1、关联一个文件 并且需要高效
BufferedReader br=new BufferedReader(new FileReader("d:\\javakan\\kan"));//要是目录不存在 会发生异常。
//2、去写入一个文件 并且需要高效
BufferedWriter bw=new BufferedWriter(new FileWriter("1.txt"));
//3、定一个标记
String str=null;
//4、把读出的一行数据复制给str
while ((str=br.readLine())!=null)
{
//把数据写入到目的中
bw.write(str);
bw.newLine();//换行
bw.flush();//刷新
}
br.close();//关闭资源
bw.close();
}
}
三、对行号进行设置-------LineNumberReader 类
代码体现
import java.io.*;
class Demo1
{
public static void main(String[] args)throws IOException
{
//调用函数
lineNumberReaderIo();
}
public static void lineNumberReaderIo()throws IOException
{
//创建FileReader类的对象去关联一个文件
FileReader fr = new FileReader("ftwo.txt");
//创建LineNumberReader类对象
LineNumberReader lnr = new LineNumberReader(fr);
//设置一个标记
String num = null;
//设置行号
lnr.setLineNumber(1);
//进行循环读取
while ((num = lnr.readLine())!= null)
{
//打印出行号 及每一行上的数据
System.out.println(lnr.getLineNumber()+"......"+num);
}
//关闭资源
lnr.close();
}
}
第四讲:装饰设计模式
一、装饰设计模式解决:对一组类进行功能的增强。
二、包装:写一个类(包装类)对被包装对象进行包装
1、包装类和被包装对象要实现同样的接口。
2、包装类要持有一个被包装对象。
3、包装类在实现接口时,大部分方法是靠调用被包装对象来实现的,对于需要修改的方法我们自己实现。
三、装饰设计模式和继承的区别:
1、装饰设计模式比继承要灵活。避免了继承体系臃肿。而且降低了类于类之间的关系。
2、装饰类因为增强已有对象,具备的功能和已有的是相同的,只不过提供了更强功能。所以装饰类和被装饰类通常是都属于一个体系中的。
第五讲:字节流
一、简述
1、字节流的基本操作与字符流类相同,但它不仅可以操作字符,还可以操作其他媒体文件等格式的文件。
2、常见的字节流
InputStream
|-----BufferedInputStream
|------FileInputStream
OutputStream
|-----BufferedOutputStream
|------FileOutputStream
二、字节流的操作:
1、用字节流拷贝jpg格式图片
代码体现
import java.io.*;
class Demo17
{
public static void main(String[] args) throws IOException
{
//常用方法复制
copy();
}
public static void copy()throws IOException
{
//关联要复制的文件
FileInputStream fis=new FileInputStream("1.jpg");
//指定复制的路径
FileOutputStream fos=new FileOutputStream("2.jpg");
//利用数组的读取方式
byte[] b=new byte[1024];
int len=0;
//进行循环读取
while ((len=fis.read(b))!=-1)
{
//写入数据
fos.write(b,0,len);
}
//关闭资源
fis.close();
fos.close();
}
}
三、字节流缓冲区:
1、它跟字符流的缓冲区对象一样,同样是为了提高了读写效率。
2、字节流中的read()方法读取的是一个字节而返回值类型不是byte而是int
原因是:在读取的时候有可能连续读取8个二进制1的情况,而8个二进制1对应的十进制为-1,所以还没等到数据读完,就结束的情况,那是因为我们是通过结尾标记 为-1来确定判断的,为了避免这种情况的出现,就将读到的字节进行int类型的提升,并在保留原数据情况下前面补了24个0,这样既可以保留原数据不变,又 能避免-1 的出现,而在写入数据时只写int类型数据的最低8位。
四、键盘录入
1、System类下面有这样的两个字段
in 标准输入流
out 标准输出流
System.in:对应的标准输入设备,键盘。
System.out对应的是标准的输出设备,控制台。
2、三种键盘录入方式
(1):main方法的args接收参数
(2)System.in通过BufferedReader进行包装
BufferedReader br = new BufferedReader(new InputStreamReader(System.in))。
(3)Scanner
Scanner sc = new Scanner(System.in)。
3、输出语句的原理和如何使用字符流输出数据
(1)原理
System.out.println("你好啊");
PrintStream ps=System.out;
ps.println("你好啊");
(2)把System.out用字符缓冲流包装一下使用
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out))。
五、转换流
1、两个转换流
OutputStreamWriter和InputStreamReader是字符和字节的桥梁:也可以称之为字符转换流。
字符转换流原理:字节流+编码表。
InputStreamReader 是字节流通向字符流的桥梁
OutputStreamWriter 是字符流通向字节流的桥梁
2、什么时候使用转换流呢?
(1):源或者目的对应的设备是字节流,但是操作的却是文本数据,可以使用转换作为桥梁,提高对文本操作的便捷。
(2):一旦操作文本涉及到具体的指定编码表时,必须使用转换流 。
第六讲 流的操作规律
一、流操作的基本规律:
1、我们通过四个明确来完成。
(1)明确源和目的
源:InputStream Reader
目的:OutputStream Writer
(2)明确数据是否是纯文本数据。
源:是纯文本:Reader
否:InputStream
目的:是纯文本 Writer
否:OutputStream
到这里,就可以明确需求中具体要使用哪个体系。
(3)明确具体的设备。
源设备:
硬盘:File
键盘:System.in
内存:数组
网络:Socket流
目的设备:
硬盘:File
控制台:System.out
内存:数组
网络:Socket流
(4)是否需要其他额外功能。
(4).1是否需要高效(缓冲区);
是,就加上buffer.
(4).2转换。
2、需求:复制一个文本文件。
(1)明确源和目的。
源:InputStream Reader
目的:OutputStream Writer
(2)是否是纯文本?
是!
源:Reader
目的:Writer
(3)明确具体设备。
源:
硬盘:File
目的:
硬盘:File
FileReader fr = new FileReader("d:\\javakan\\kan ")。
FileWriter fw = new FileWriter("2 .txt")。
(4)需要额外功能吗?
需要,需要高效。
BufferedReader bufr = new BufferedReader(new FileReader("d:\\javakan\\kan "))。
BufferedWriter bufw = new BufferedWriter(new FileWriter("2 .txt"))。
(5)代码体现
import java.io.*;
class Demo18
{
public static void main(String[] args)
{
//去关联一个文件
BufferedReader br =null;
//写到一个目的中去
BufferedWriter bw= null;
try
{
//使用了字符缓冲区和转换流
br=new BufferedReader(new FileReader("d:\\javakan\\kan "));
bw=new BufferedWriter(new FileWriter("2.txt"));
//定义一个标记
String st=null;
//循环进行读写
while((st=br.readLine())!=null)
{
//进行写入
bw.write(st);
//换行
bw.newLine();
//刷新
bw.flush();
}
}
catch (IOException ioe)
{
throw new RuntimeException("出现异常");
}
finally
{
try
{
//关闭资源
br.close();
bw.close();
}
catch (IOException io)
{
throw new RuntimeException("异常出现");
}
}
}
}
3、需求:读取键盘录入信息,并写入到一个文件中。
(1)明确源和目的。
源:InputStream Reader
目的:OutputStream Writer
(2)是否是纯文本呢?
是,
源:Reader
目的:Writer
(3)明确设备
源:
键盘。System.in
目的:
硬盘。File
InputStream in = System.in;
FileWriter fw = new FileWriter("3.txt");
这样做可以完成,但是麻烦。将读取的字节数据转成字符串。再由字符流操作。
(4)需要额外功能吗?
需要。转换。 将字节流转成字符流。因为名确的源是Reader,这样操作文本数据做便捷。
所以要将已有的字节流转成字符流。使用字节-->字符 。InputStreamReader
InputStreamReader isr = new InputStreamReader(System.in);
FileWriter fw = new FileWriter("3.txt");
还需要功能吗?
需要:想高效。
BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bufw = new BufferedWriter(new FileWriter("3.txt"));
(5)代码体现
/读取键盘录入信息,并写入到一个文件中。
/*
思路:1、源:键盘System.in 需要高效 录入的是一个字节 需要转换流InputStreamReader
2、目的:一个文件FileWriter 需要高效
*/
import java.io.*;
class Demo19
{
public static void main(String[] args)
{
getCopy();
}
public static void getCopy()
{
//去关联一个文件
BufferedReader br=null;
//写到一个目的中去
BufferedWriter bw=null;
try
{
//使用了字符缓冲区和转换流
br=new BufferedReader(new InputStreamReader(System.in));
bw=new BufferedWriter(new FileWriter("3.txt"));//要是在调用一次上一次的文件会发生覆盖,为了避免出现这种情况 在构造函数中加上 true就行了。
String str=null;
while ((str=br.readLine())!=null)
{
//如果遇到了字符串end键盘录入就结束
if (str.equals("end"))
{
break;
}
bw.write(str);
bw.newLine();
bw.flush();
}
}
catch (IOException ioe)
{
throw new RuntimeException("异常出现");
}
finally
{
try
{
br.close();
bw.close();
}
catch (IOException io)
{
throw new RuntimeException("异常");
}
}
}
}
4、需求:将一个文本文件数据显示在控制台上。
(1)明确源和目的。
源:InputStream Reader
目的:OutputStream Writer
(2)是否是纯文本呢?
是,
源:Reader
目的:Writer
(3)明确具体设备
源:
硬盘:File
目的:
控制台:System.out
FileReader fr = new FileReader("3.txt");
OutputStream out = System.out;//PrintStream
(4)需要额外功能吗?
需要,转换。
FileReader fr= new FileReader("3.txt");
OutputStreamWriter osw = new OutputStreamWriter(System.out);
需要,高效。
BufferedReader bufr = new BufferedReader(new FileReader("3.txt"));
BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(System.out));
(5)代码体现
//将一个文本文件数据显示在控制台上。
/*
思路:1、源:是一个文本 FileReader 需要高效BufferedReader
2、目的:是一个控制台System.out;需要高效 BufferedWriter 需要转换流 OutputStreamWriter
*/
import java.io.*;
class Demo20
{
public static void main(String[] args)
{
copyFile();
}
public static void copyFile()
{
//去关联一个文件
BufferedReader br=null;
//写到一个目的中去
BufferedWriter bw=null;
try
{
br=new BufferedReader(new FileReader("3.txt"));
bw=new BufferedWriter(new OutputStreamWriter(System.out));
String st=null;
while ((st=br.readLine())!=null)
{
//进行写入,换行,刷新
bw.write(st);
bw.newLine();
bw.flush();
}
}
catch (IOException ioe)
{
throw new RuntimeException("异常");
}
finally
{
try
{
//关闭资源
br.close();
bw.close();
}
catch (IOException io)
{
throw new RuntimeException("出现异常");
}
}
}
}
5、需求:读取键盘录入数据,显示在控制台上。
(1)明确源和目的。
源:InputStream Reader
目的:OutputStream Writer
(2)是否是纯文本呢?
是,
源:Reader
目的:Writer
(3)明确设备。
源:
键盘:System.in
目的:
控制台:System.out
InputStream in = System.in;
OutputStream out = System.out;
(4)明确额外功能?
需要转换,因为都是字节流,但是操作的却是文本数据。
所以使用字符流操作起来更为便捷。
InputStreamReader isr = new InputStreamReader(System.in);
OutputStreamWriter osw = new OutputStreamWriter(System.out);
为了将其高效。
BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(System.out));
(5)代码体现
//读取键盘录入数据,显示在控制台上。
/*
思路:1、源:键盘 System.in 需要高效BufferedReader 需要转换 InputStreamReader
2、目的:控制台 System.out 需要高效 BufferedWriter 需要转换OutputStreamWriter
*/
import java.io.*;
class Demo4
{
public static void main(String[] args)
{
//调用函数
copyFile();
}
public static void copyFile()
{
//去关联一个文件
BufferedReader br=null;
//写到一个目的中去
BufferedWriter bw=null;
try
{
//使用了字符缓冲区和转换流
br=new BufferedReader(new InputStreamReader(System.in));
bw=new BufferedWriter(new OutputStreamWriter(System.out));
//定义一个标记
String ss=null;
//循环进行读写
while ((ss=br.readLine())!=null)
{
//如果遇到了字符串end键盘录入就结束
if (ss.equals("end"))
{
break;
}
//进行写入
bw.write(ss);
//换行
bw.newLine();
//刷新
bw.flush();
}
}
catch (IOException ioe)
{
throw new RuntimeException("异常");
}
finally
{
try
{
//关闭资源
br.close();
bw.close();
}
catch (IOException io)
{
throw new RuntimeException("异常啦");
}
}
}
}
6、需求:将一个中文字符串数据按照指定的编码表写入到一个文本文件中.
(1)目的。OutputStream,Writer
(2)是纯文本,Writer。
(3)设备:硬盘File
FileWriter fw = new FileWriter("4.txt");
fw.write("成功了");
注意:既然需求中已经明确了指定编码表的动作。
那就不可以使用FileWriter,因为FileWriter内部是使用默认的本地码表。
只能使用其父类。OutputStreamWriter.
OutputStreamWriter接收一个字节输出流对象,既然是操作文件,那么该对象应该是FileOutputStream
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("4.txt"),name);
需要高效吗?
BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("4.txt"),name));
(4)代码体现
//将一个中文字符串数据按照指定的编码表写入到一个文本文件中.
/*
思路:1、源;是一个字符串
2、目的:是一个文件FileWriter 需要高效 因为要指定一个编码表 所以要用到转换流OutputStreamWriter 假设是gbk编码表
*/
import java.io.*;
class Demo5
{
public static void main(String[] args)
{
copyFile();
}
public static void copyFile()
{
//指定一个中文数据
String str="成功了";
//写入到;一个文件当中去
BufferedWriter bw=null;
try
{
//并且也指定一种编码表
bw=new BufferedWriter(new OutputStreamWriter(new FileOutputStream("4.txt"),"GBK"));
bw.write(str);
}
catch (IOException ioe)
{
throw new RuntimeException("异常");
}
finally
{
try
{
//关闭资源
bw.close();
}
catch (IOException io)
{
throw new RuntimeException("出现异常");
}
}
}
}
7、io流的小总结:
IO流
|--字节流
|--字节输入流
InputStream
int read():一次读取一个字节
int read(byte[] bys):一次读取一个字节数组
|--FileInputStream
|--BufferedInputStream
|--字节输出流
OutputStream
void write(int by):一次写一个字节
void write(byte[] bys,int index,int len):一次写一个字节数组的一部分
|--FileOutputStream
|--BufferedOutputStream
|--字符流
|--字符输入流
Reader
int read():一次读取一个字符
int read(char[] chs):一次读取一个字符数组
|--InputStreamReader
|--FileReader
|--BufferedReader
String readLine():一次读取一个字符串
|--字符输出流
Writer
void write(int ch):一次写一个字符
void write(char[] chs,int index,int len):一次写一个字符数组的一部分
|--OutputStreamWriter
|--FileWriter
|--BufferedWriter
void newLine():写一个换行符
void write(String line):一次写一个字符串