流(IO):(input/output):实现的是两个设备之间的数据传输
设备:网络、磁盘(硬盘)、内存、控制台、键盘、文件
注意:流的输入还是输出是以内存为对比的
分类:
第一:根据操作的方式分类:输入类和输出流
第二:根据数据的类型分类:字节流和字符流
字节流:传输的是字节,可以操作任意类型数据的传入和传出 例:图片、视频、音频、文本
字符流:传输的也是字节,好处是在字节的基础上融入了编码,操作更方便,只能传输文本或者字符型的数据 例:文本
以内存作为参考:
字节流的两个父类:
InputStream:字节输入流
OurputStream:字节输出流
字符流的两个分类:
Reader:字符的读入(输入流)---将数据读入内存
Writer:字符输出流(写出)--将数据从内存中取出
//先学习字符流
//以磁盘的数据存储为例
分析:是将内容从内存写入文本,所以为输出流,又因为传输的是文本,所以用字符流---FileWriter
注意点:
(1)关联的文件的特点:这个文件如果之前不存在,程序会自动创建一个新的,如果存在,就直接使用,但会将文件之前的内容覆盖掉
(2).我们可以自己指定路径,但是要注意路径一定要真实存在,否则会报异常
(3).默认的路径是当前的工程
(4)在执行write方法时,数据被临时放到了流对象的内部数组中,这是一个字节数组,会自动去查默认的编码表
(5)在使用完毕后,一定要关闭流
close方法有两个功能:关闭流和刷新
(6)当流被关闭之后,不能再继续写操作了
1.创建输出流对象,并关联将要写入内容的文件
FileWriter filewriter= new FileWriter("temp1.text");
2.调用写方法
filewriter.writer("temeipu");
//3.刷新//这可以不写,关闭流的方法可以自动刷新,最好写
//filewriter.flush();
4.关闭流
filewriter.closed;
总结:在写有关流的相关代码的时候步骤
(1)先创建流对象并将路径指定好
(2)再先写关闭流的方法
(3)最后再写是读入的数据还是写出的数据
文件的续写:
方法:FileWriter(String filename,boolean value)
当value为true的时候,不会将原来的内容删掉,会接着写
1.创建对象关联文件并支持续写且将异常解决
FileWriter fileWriter = null;
try{
fileWriter = new FileWriter("temp1.txt",true);
fileWriter.writer("hello");
}catch(IOException e){
e.printStackTrace();
}finally{//这里是为了一定要输出关闭流的方法
if(fileWriter != null){
try{
fileWriter.close();
}catch(IOException e){
e.printStackTrace();
}
}
}
读入:
将字符从文本文件读入内存,并显示在控制台--FileReader
1.创建对象并关联文件
FileReader fileReader = new FileReader("temp1.txt");
2.读
read():一次读一个字符
read(数组):一次读多个字符
返回值就是当前读到的字符,以ASCII的形式返回
int num=0;
while((num=fileReader.read()) != -1){
System.out.print((char)num);
}
3.关闭流
fileReader.close();
一次读取多个字符
read(数组)
():临时存放数据的地方,我们本次读取到的数据临时存放在这个数组中,这个数组的大小决定了我们一次可以取的字符的个数,一般这个数组的大小在1kb左右
char[] arr = new char[2];
int num=0;
//num = fileReader.read(arr);//返回值代表的是本次读到的真实的字符个数,如果是将整个文本都已经读完了,返回-1
while((num = fileReader.read(arr)) != -1){
System.out.println(new String(arr,0,num)+" "+num);
}
3.关闭流
fileReader.close();
字符串知识讲解:
获取0-2之间的字符,并将它转成字符串
char[] temp={'a','b','c','d'};
String tempStr = new String(temp,0,2);
System.out.println(tempStr);
D:\workspace\BigData1708N20\src\com\qianfeng\test\Demo1.java
绝对路径:从根路径开始的全路径
相对路径:从全路径的某一个阶段开始截取的一段路径(必须包含Demo1.java)
\默认是转义字符,一般要分其他的字符拼接成有特殊含义的字符,比如:\t:制表符 \n:换行符(linux系统) \r\n:换行符(windows系统)
如果想让\表示普通含义,就要让他将自己转义:即\代表普通的
在程序中\与/通常被认为含义差别不大,可以都看作是路径
缓冲流:字符的缓冲流(缓冲区)
定义:为了提高读写的能力,但是本身没有读写的能力。如果想实现读写必须借助于字符流
可以将缓冲流类比于催化剂或者高速的小车
缓冲流的分类:
1.字符缓冲的输入流:BufferedReader--可以增强读的能力
2.字符缓冲的输出流:BufferedWriter---可以增强写的能力
注意:在利用缓冲流在读写的时候,创建缓冲流对象的过程中需要将实际工作对象传进去,因为缓冲流自己本身不能读写,只能将能读写的字符流当做属性并创建对象来进行读写
例:
FileWriter fileWriter = new FileWriter("temp1.txt");
BufferedWriter bufferred = new BufferedWriter(fileWriter);
然后再通过bufferedWriter这个对象来读写
注意:字符流和字节流都是这样的
在缓冲字符输出流中有一个特殊的方法叫newLine(),直接调用即可,bufferedWriter.newLine();
在缓冲字符输入流中有一个特殊的方法叫newRead(),这个方法可以一次读一行,其用法如下:
原理(最重要):一个一个字符的读,直到读到换行符为止,然后将所有读到的字符返回
注意:a:不会讲当前的换行符返回 b:返回值就是读到的内容,但如果内容已经读完,默认返回null
String string = null;
while((string = bufferedRead.readLine()) != null){
System.out.print(string);
System.out.println("\r\n");//换行
}
LineNumberReader:是BufferedReader的子类,不能实现读,在提高效率的同时可以设置行号,获取行号
LineNumberReader line = new LineNumberReader(new FileReader(new FileReader("copy1.txt")));
lineNumberReader.setLineNumber(10);
这里调用了特有的setLineNumber(int num)方法
手动模拟BufferedReader
步骤:--要属于当前的流体系
1.要有一个FileReader类型的成员变量
2.要有一个带参数的构造方法接受外部的流
3.实现读一行的方法
4.关闭
通过这个模拟引出了装饰设计模式:
装饰设计模式:基于已经实现的功能,提供增强的功能
他的由来就是通过对缓冲流的而研究实现的
Reader--->BufferedReader
特点:从缓冲流的角度理解
1.使流原来的继承体系更加简单
2.提高了效率
3.因为是在原有的基础上提高增强的功能,所以他还要属于原有的体系
如果自要使用装饰设计模式,怎么做?
1.原来的类:Test
2.装饰类:BTest
步骤:
1.让Btest extends Test
2.在BTest内有一个Test类型的成员变量
3.通过BTest带参数的构造方法去接收外部的一个Test类型的对象,赋给自己内部的Test类型成员变量
4.在实现功能的时候,调用Test类型的成员变量实现基本的功能,自己实现增强的功能
适配器设计模式:通常可以变相的理解成装饰设计模式
实例:要求在子类中只使用play方法
分析:Zi是继承了ZiMidel类,ZiMidel类实现了Inter接口
当Zi类指向实现Inter接口的一个方法的时候,如果直接实现Inter接口,就必须将所有的方法都实现,如果在Zi类与Inter接口之间插入一个类,让这个类去实现Inter接口的所有方法,作为这个类的子类只需要实现自己需要的方法
我们将中间的这个类就可以称为适配器类
注意:适配器设计模式的前提是这个接口的方法很多,如果方法就两三个就不虚要用这个设计模式,直接创建类并实现即可
字节流:可以处理任意类型的数据
InputStream:字节输入流
OutputStream:字节输出流
注意在字节流中如果要写的话,必须是字节,不能使字符串等,如果是字符需要通过string.getBytes()来转化
字节输入流,如果是一个一个读以及通过数组多个的读其方法和字符流中的一样的写法,只是对象不一样,在字节输入流中有一个方法时一次将所有字节读完
//1.确定文档中总字节的个数
//注意点:如果文本的字节数太大,不建议使用,因为这是一种变相的数组读的方法
int temp = intutStream.available;//获取文档中的总字节
//2.读
byte[] arr = new byte[temp];
inputStream.read(arr);
System.out.println(new String(arr));//这里不用while循环是因为已经将全部字节已经放入了一个数组里面了
inputStream.close();
标准输出流:System.in:默认是将数据从控制台写入内存,接受的是接盘敲入的数据
标准输入流:System.out:默认是将数据从内存写入控制台
标准输入流:刺溜已打开并准备提供输入数据。通常,此流对应于键盘输入或者由主机环境或游湖指定的另一个源//源可以理解成源头,是数据的一端
转换流:将字节流转成字节流--本身是字节流、
转换流的目的:是想办法去使用readLine()方法
两类:InputStreamReader:输入流
OutputStreamWriter:输出流
在用这个流的时候,需要将字节流传进去才能成为字符流,然后字节流也可以通过System.in来创建,则可以写成如下:
1.获得标准输入流
InputStream intputStream = System.in;
2.通过转换流得到字符流
InputStreamReader inputStreamReader = new InputStreamReader(intputStream);
3.得到字符缓冲读入流
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
可以简写成如下:
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
4.标准输出流转成字符缓冲输出流
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(System.out));
然后就可以根据缓冲的字符流来进行操作
注意:在写流的代码时,一要考虑死循环的问题,需不需要设置结束条件;二要考虑刷新的问题,即使写了close方法,最好也把flush方法也写上
网友评论