毕向东Java视频学习笔记【day21-IO流<1>】
来源:互联网 发布:常州软件开发公司 编辑:程序博客网 时间:2024/06/05 01:09
01-IO流(输入流&输出流)
输入流和输出流相对于内存设备而言.
将外设中的数据读取到内存中:输入
将内存的数写入到外设中:输出。
02-IO流(字节流&字符流)
字符流的由来:
其实就是:字节流读取文字字节数据后,不直接操作而是先查指定的编码表。获取对应的文字。
在对这个文字进行操作。简单说:字节流+编码表
字节流的两个顶层父类:
1,InputStream 2,OutputStream.
字符流的两个顶层父类:
1,Reader 2,Writer
这些体系的子类都以父类名作为后缀。
而且子类名的前缀就是该对象的功能。
03-IO流(字符流-FileWriter)
package cn.itcast.p2.io.filewriter; import java.io.FileWriter; import java.io.IOException; //需求:将一些文字存储到硬盘一个文件中。 public class FileWriterDemo { private static final String LINE_SEPARATOR = System.getProperty("line.separator"); public static void main(String[] args) throws IOException { //创建一个可以往文件中写入字符数据的字符输出流对象。 /* * 既然是往一个文件中写入文字数据,那么在创建对象时,就必须明确该文件(用于存储数据的目的地)。 * * 如果文件不存在,则会自动创建。 * 如果文件存在,则会被覆盖。 * * 如果构造函数中加入true,可以实现对文件进行续写! */ FileWriter fw = new FileWriter("demo.txt",true); /* * 调用Writer对象中的write(string)方法,写入数据。 * * 其实数据写入到临时存储缓冲区中。 * */ fw.write("abcde"+LINE_SEPARATOR+"hahaha"); /* * 进行刷新,将数据直接写到目的地中。 */ fw.flush(); /* * 关闭流,关闭资源。在关闭前会先调用flush刷新缓冲中的数据到目的地。 */ fw.close(); }}
FileWriter.write();
- 写入流中(内存中),但是没保存到硬盘上
FileWriter.flush();
- 刷新,保存到硬盘上
- 相当于写文档时的ctrl+s
FileWriter.close();
- 关闭流
- 会自动调用flush,再关闭。
- 在关闭后,无法在使用flush和write。
- 相当于关闭一个txt文件,就无法再保存和写入了。
-
04-IO流(字符流-FileWriter-细节(换行和续写))
换行
- fw.write(“abcde”+LINE_SEPARATOR+”hahaha”);
- fw.write(“abcde\r\nhahaha”);//windows中换行是\r\n
续写,只用在new对象时,增加一个true参数,默认是false
FileReader fr = new FileReader("d:\\demo.txt",true);
05-IO流(字符流-FileWriter-IO异常处理)
- if (fw != null) 一定要记住这一步
package day20;import java.io.FileWriter;import java.io.IOException;public class IOExceptionDemo { private static final String LINE_SEPARATOR = System .getProperty("line.separator"); /** * @param args * @throws IOException */ public static void main(String[] args) { FileWriter fw = null; try { fw = new FileWriter("d:\\demo.txt"); fw.write("abcde" + LINE_SEPARATOR + "hahaha"); } catch (Exception e) { System.out.println(e.toString()); } finally { if (fw != null) {//一定要记住这一步 try { fw.close(); } catch (IOException e) { // TODO 自动生成的 catch 块 e.printStackTrace(); throw new RuntimeException("关闭失败"); } } } }}
06-IO流(字符流-FileReader-读取方式一)
FileReader.read()
- 第一次调用只读取第1个字符的二进制
- 第二次调用就读取下一个字符
- 如果读到文件结尾,返回-1
一般这样写来读取文件中的内容
while((ch=fr.read())!=-1){ System.out.println((char)ch); }
07-IO流(字符流-FileReader-读取方式二)
- System.out.println(new String(buf,0,len));
- 输出buf字符数组中从0到len-1的字符
一般buf字符数组的长度为1024的倍数
char[] buf = new char[3];
- FileReader.read(buf)读取3个字符到buf字符数组中。
- int num = read(buf)
- 能返回读取字符的长度,如果只有2个字符,buf数组长度为3,返回长度2赋给num.
- 如果1个都读取不到,返回0,并且buf为空
- int num = read(buf)
一般这样写
while((len=fr.read(buf))!=-1){ System.out.println(new String(buf,0,len));}
08-IO流(字符流–复制文本文件_1)
package day21;import java.io.FileReader;import java.io.FileWriter;import java.io.IOException;/* * 需求:将c盘的一个文本文件复制到d盘。 * * 思路: * 1,需要读取源, * 2,将读到的源数据写入到目的地。 * 3,既然是操作文本数据,使用字符流。 * */public class CopyTextTest { /** * @param args * @throws IOException */ public static void main(String[] args) throws IOException { //1,读取一个已有的文本文件,使用字符读取流和文件相关联。 FileReader fr = new FileReader("d:\\Demo.txt"); //2,创建一个目的,用于存储读到数据。 FileWriter fw = new FileWriter("d:\\copytext_1.txt"); //3,频繁的读写操作。 int ch = 0; while((ch=fr.read())!=-1){ fw.write(ch); } //4,关闭流资源。 fw.close(); fr.close(); }}
09-IO流(字符流–复制文本文件_2)
package day21;import java.io.FileReader;import java.io.FileWriter;import java.io.IOException;public class CopyTextTest_2 { private static final int BUFFER_SIZE = 1024; /** * @param args */ public static void main(String[] args) { FileReader fr = null; FileWriter fw = null; try { fr = new FileReader("d:\\Demo.txt"); fw = new FileWriter("d:\\copytest_2.txt"); //创建一个临时容器,用于缓存读取到的字符。 char[] buf = new char[BUFFER_SIZE];//这就是缓冲区。 //定义一个变量记录读取到的字符数,(其实就是往数组里装的字符个数 ) int len = 0; while((len=fr.read(buf))!=-1){ fw.write(buf, 0, len); } } catch (Exception e) { throw new RuntimeException("读写失败"); }finally{ if(fw!=null) try { fw.close(); } catch (IOException e) { e.printStackTrace(); } if(fr!=null) try { fr.close(); } catch (IOException e) { e.printStackTrace(); } } }}
10-IO流(字符流-练习-复制文本文件_图解)
波浪线–流
两个流之间没有必然的联系
是通过一个媒介将其联系在一起
这个媒介其实就是缓冲区
11-IO流(字符流-缓冲区-解释)
设计优化-重构
加入设计模式,提升灵活性、复用性
性能优化
缓冲区的使用,高效性能
12-IO流(字符流-缓冲区-BufferedWriter)
缓冲区是提高效率神器
- BufferWriter其实封装了数组 用数组来缓冲
- FileWriter fw = new FileWriter(“buf.txt”);
- new对象时,必须有缓冲的对象“buf.txt”
import java.io.*;public class BufferedWriterDemo { @SuppressWarnings("unused") private static final String LINE_SEPARATOR = System.getProperty("line.separator"); public static void main(String[] args) throws IOException { FileWriter fw = new FileWriter("buf.txt"); //为了提高写入的效率。使用了字符流的缓冲区。 //创建了一个字符写入流的缓冲区对象,并和指定要被缓冲的流对象相关联 BufferedWriter bufw = new BufferedWriter(fw); //使用缓冲区的写入方法将数据先写入到缓冲区中。 bufw.write("asdasd"); //关闭缓冲区。其实关闭的就是被缓冲的流对象。 bufw.close(); }}
关闭缓冲区的流对象,流对象不存在了,就不用再关闭fw的流对象(fw.close)。
- buwf.newLine();
- 换行
- 注意:但是只有BufferWriter中有。
养成习惯刷新flush保存的习惯(ctrl+s)
for(int x=1; x<=4; x++){ bufw.write("abcdef"+x); bufw.newLine(); bufw.flush(); }
13-IO流(字符流-缓冲区-BufferedReader)
- BufferedReader.readLine:string
- 读取文件中的行 行以回车为准(\r\n)
- 如果行中无内容,String返回null
while((line=bufr.readLine())!=null){ System.out.println(line); }
14-IO流(字符流-缓冲区-BufferedReader-readLine方法原理)
BufferedReader:StringBuilder
readLine()使用了读取缓冲区的read方法,(不读取\n换行、\r回车)将读取到的字符进行缓冲并且进行判断换行标记,将标记前的缓存数据变成字符串返回。
15-IO流(字符流-缓冲区-复制文本文件)
用bufferReader和bufferWriter复制文本文件
import java.io.*;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(); }}
16、17-IO流(字符流-缓冲区-自定义MyBufferedReader-read和readLine方法)
自定义的读取缓冲区。其实就是模拟一个BufferedReader.
分析:
缓冲区中无非就是封装了一个数组,
并对外提供了更多的方法对数组进行访问。
其实这些方法最终操作的都是数组的角标。
缓冲的原理:
其实就是从源中获取一批数据装进缓冲区中。
在从缓冲区中不断的取出一个一个数据。
在此次取完后,在从源中继续取一批数据进缓冲区。
当源中的数据取光时,用-1作为结束标记。
package day21.cn.itcast.p4.io.charstream.mybuffer;import java.io.FileReader;import java.io.IOException;import java.io.Reader;public class MyBufferedReader extends Reader { private Reader r; //定义一个数组作为缓冲区。 private char[] buf = new char[1024]; //定义一个指针用于操作这个数组中的元素。当操作到最后一个元素后,指针应该归零。 private int pos = 0; //定义一个计数器用于记录缓冲区中的数据个数。 当该数据减到0,就从源中继续获取数据到缓冲区中。 private int count = 0; MyBufferedReader(Reader r){ this.r = r; } public int myRead() throws IOException{ //1,从源中获取一批数据到缓冲区中。需要先做判断,只有计数器为0时,才需要从源中获取数据。 if(count==0){ count = r.read(buf); pos = 0; } if(count<0) return -1; char ch = buf[pos++]; count--; return ch; } public String myReadLine() throws IOException{ StringBuilder sb = new StringBuilder(); int ch = 0; while((ch = myRead())!=-1){ if(ch=='\r') continue; if(ch=='\n') return sb.toString(); //将从缓冲区中读到的字符,存储到缓存行数据的缓冲区中。 sb.append((char)ch); } if(sb.length()!=0) return sb.toString(); return null; } public void myClose() throws IOException { r.close(); }}
18-IO流(字符流-缓冲区-装饰设计模式)
- 装饰设计模式:
- 对一组对象的功能进行增强时,就可以使用该模式进行问题的解决。
public class PersonDemo { public static void main(String[] args) { Person p = new Person(); NewPerson p1 = new NewPerson(p); p1.chifan(); NewPerson2 p2 = new NewPerson2(); p2.chifan(); }}class Person{ void chifan(){ System.out.println("吃饭"); }}//这个类的出现是为了增强Person而出现的。class NewPerson{//装饰模式 private Person p ; NewPerson(Person p){ this.p = p; } public void chifan(){ System.out.println("开胃酒"); p.chifan(); System.out.println("甜点"); }}class NewPerson2 extends Person{//继承 public void chifan(){ System.out.println("开胃酒"); super.chifan(); System.out.println("甜点"); }}
19-IO流(字符流-缓冲区-装饰设计模式和继承的区别)
装饰和继承都能实现一样的特点:进行功能的扩展增强。
有什么区别呢?
首先有一个继承体系。
Writer
|–TextWriter:用于操作文本
|–MediaWriter:用于操作媒体。
想要对操作的动作进行效率的提高。
按照面向对象,可以通过继承对具体的进行功能的扩展。
效率提高需要加入缓冲技术。
Writer |--TextWriter:用于操作文本 |--BufferTextWriter:加入了缓冲技术的操作文本的对象。 |--MediaWriter:用于操作媒体。 |--BufferMediaWriter:
如果这个体系进行功能扩展,又多了流对象。
那么这个流要提高效率,是不是也要产生子类呢?是。这时就会发现只为提高功能,进行的继承,
导致继承体系越来越臃肿。不够灵活。
重新思考这个问题?用装饰模式
既然加入的都是同一种技术–缓冲。
前一种是让缓冲和具体的对象相结合。
可不可以将缓冲进行单独的封装,哪个对象需要缓冲就将哪个对象和缓冲关联。
class Buffer{ Buffer(TextWriter w) {} Buffer(MediaWirter w) {}}class BufferWriter extends Writer{ BufferWriter(Writer w) {}}
装饰也可用继承的表达方式。
Writer |--TextWriter:用于操作文本 |--MediaWriter:用于操作媒体。 |--BufferWriter:用于提高效率。
装饰比继承灵活。
特点:装饰类和被装饰类都必须所属同一个接口或者父类。
20-IO流(字符流-缓冲区-LineNumberReader)
- LineNumberReader 方法
- 设置行号
21-IO流(字节流-操作文件基本演示)
字节流是不需要临时存储缓冲的,是直接写入目的地中,所以不需要flush方法,但是close方法还是需要的(关闭资源动作)。
“asdasd”.getBytes() 把字符串改成字符
InputStream.available()文件的大小字节
- 对小文件可以使用
- 对大文件最好不去使用
在真正读数据的时候最好new一个1024的字节数组,循环读取文件
22-IO流(字节流-练习-复制MP3)
copy_01:建议的方法
copy_02:建议的方法
copy_03:不建议。 如果文件过大,要不断创建数组,很慢,如果文件过大,直接溢出。
copy_04:千万不要用,效率没有!读一个写一个很慢
package day21.cn.itcast.p7.io.bytestream.test;import java.io.BufferedInputStream;import java.io.BufferedOutputStream;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;public class CopyMp3Test { /** * @param args * @throws IOException */ public static void main(String[] args) throws IOException { copy_4(); }// 千万不要用,效率没有!读一个写一个很慢 public static void copy_4() throws IOException { FileInputStream fis = new FileInputStream("c:\\0.mp3"); FileOutputStream fos = new FileOutputStream("c:\\4.mp3"); int ch = 0; while((ch =fis.read())!=-1){ fos.write(ch); } fos.close(); fis.close(); } //不建议。 如果文件过大,要不断创建数组,很慢,如果文件过大,直接溢出 public static void copy_3() throws IOException { FileInputStream fis = new FileInputStream("c:\\0.mp3"); FileOutputStream fos = new FileOutputStream("c:\\3.mp3"); byte[] buf = new byte[fis.available()]; fis.read(buf); fos.write(buf); fos.close(); fis.close(); } public static void copy_2() throws IOException { FileInputStream fis = new FileInputStream("c:\\0.mp3"); BufferedInputStream bufis = new BufferedInputStream(fis); FileOutputStream fos = new FileOutputStream("c:\\2.mp3"); BufferedOutputStream bufos = new BufferedOutputStream(fos); int ch = 0; while((ch=bufis.read())!=-1){ bufos.write(ch); } bufos.close(); bufis.close(); } public static void copy_1() throws IOException { FileInputStream fis = new FileInputStream("c:\\0.mp3"); FileOutputStream fos = new FileOutputStream("c:\\1.mp3"); byte[] buf = new byte[1024]; int len = 0; while((len=fis.read(buf))!=-1){ fos.write(buf,0,len); } fos.close(); fis.close(); }}
- 毕向东Java视频学习笔记【day21-IO流<1>】
- 毕向东Java视频学习笔记【day21-IO流<2>】
- IO流01--毕向东JAVA基础教程视频学习笔记
- IO流02--毕向东JAVA基础教程视频学习笔记
- IO流03--毕向东JAVA基础教程视频学习笔记
- IO流04--毕向东JAVA基础教程视频学习笔记
- IO流05--毕向东JAVA基础教程视频学习笔记
- 网络编程1--毕向东java基础教程视频学习笔记
- 集合1--毕向东java基础教程视频学习笔记
- IO流(字符流)+JAVA学习笔记-DAY21
- [Java视频笔记]day21
- 毕向东Java视频学习笔记【day01-day07】
- 毕向东Java视频学习笔记【day08-继承】
- 毕向东Java视频学习笔记【Day10 多态+内部类】
- 毕向东Java视频学习笔记【Day11 异常+object类】
- 毕向东Java视频学习笔记【Day11-Day13 多线程】
- 多线程--毕向东java基础教程视频学习笔记
- java学习笔记——毕向东视频day01
- JAVA Script 学习之通过setTimeout 实现钟表的效果
- Android各个版本代号及其特性
- leetcode 70. Climbing Stairs QuestionEditorial
- mysql 5.7.13安装
- 事件监听器_Demo02.java
- 毕向东Java视频学习笔记【day21-IO流<1>】
- 在不加载图片的情况下读取图片宽高
- Kafka消费者生产者编程模型(二)
- lightoj-1109 - False Ordering【思维】
- TextView的setTextSize和getTextSize单位不同
- day01开始学习Java的第一步
- 事件监听器_Demo03.java
- 让UIScrollView上的subView响应触摸事件
- 富文本常用封装(NSAttributedString浅析)