2018-06-06 第三十一天

简介:

一、File***Stream和 Buffered***Stream

Buffered带缓存区,提高了内存和内存之间的交互,减少了内存和磁盘之间的交互,效率更高。


1240
1240


二、MyBuffered


import java.io.InputStream;

import java.io.OutputStream;

import java.io.FileInputStream;

import java.io.FileOutputStream;


public class TestMyBufferedStream {


public static void main(String[] args) {

long time = System.currentTimeMillis();

BufferedInputOutputStreamTest.copyFile();

long cost = System.currentTimeMillis()-time;

System.out.println("buffered cost = "+cost);

time = System.currentTimeMillis();

try {

copyFile();

catch (Exception e) {

e.printStackTrace();

}

cost = System.currentTimeMillis()-time;

System.out.println("myBuffered cost = "+cost);

}

static void copyFile() throws Exception{

MyBufferedInputStream mbis = new MyBufferedInputStream(new FileInputStream("c:/77.jpg"));

MyBufferedOutputStream mbos = new MyBufferedOutputStream(new FileOutputStream("c:/99.jpg"));

int value = 0;

while((value = mbis.read()) != -1){

mbos.write(value);

}

mbis.close();

mbos.flush();

mbos.close();

}

}

/**

 * 自定义的带缓冲区的字节输入流,模拟  java.io.BufferedInputStream

 *

 */

public class MyBufferedInputStream {

//定义默认的缓冲区大小

public static final int DEFAULT_BUF_SIZE = 8192;

//字节数组缓冲区

private byte[] buf;

//用于读取数据源的字节输入流的引用,可以是任意的字节输入流

private InputStream is;

//记录当前读取到的字节数组数据的下标

private int pos;

//用于记录缓冲区中有效的字节数据

private int count;

public MyBufferedInputStream(InputStream is) {

this.is = is;

buf = new byte[DEFAULT_BUF_SIZE];

}

public MyBufferedInputStream(InputStream is,int bufSize) {

this.is = is;

buf = new byte[bufSize];

}

//最核心对外提供的read 方法 读取下一个字节的数据

//从buf 中取一个字节的数据

public int read() throws Exception{

if(count == 0){//缓冲区没有数据了

//一次性从通过is 读取底层数据 到buf 中,并记录读取到了多少有效字节数据。

count = is.read(buf);

//一种是 数据源还有数据,一种是数据源没有数据了,返回-1

if(count == -1)//return -1

return -1;

pos = 0;

//使用int 的低八位 保存 读取到的字节数据。

int value = buf[pos] & 0xff;

pos ++;

count --;

return value;

}else{//缓冲区有数据

int value = buf[pos] & 0xff;

pos ++;

count --;

return value;

}

}

//包装流的关闭问题,关闭的是被包装的流。

public void close() throws Exception{

if(is != null){

is.close();

}

}

}


/**

 * 自定义的带缓冲区的输出流

 *

 */

class MyBufferedOutputStream{

//定义默认的缓冲区大小

public static final int DEFAULT_BUF_SIZE = 8192;

//字节数组缓冲区

private byte[] buf;

//用于读取数据源的字节输入流的引用,可以是任意的字节输入流

private OutputStream os;

//用于记录写入缓冲区的字节数据的个数,和当前待写入数组元素的下标

private int pos;

public MyBufferedOutputStream(OutputStream os) {

this.os = os;

buf = new byte[DEFAULT_BUF_SIZE];

}

public MyBufferedOutputStream(OutputStream os,int bufSize) {

this.os = os;

buf = new byte[bufSize];

}

/**

 * 将value 的后八位写出去

 * @param value

 */

public void write(int value) throws Exception{

//缓冲区满了

if(pos == buf.length){

//将缓冲区的内容全部写出去

os.write(buf);

pos = 0;

//然后再将value 写入下标pos = 0 的位置

buf[pos] = (byte)value;

//pos 永远指向 待写入数据的下标

pos ++;

}else{//缓冲区没有满

//将value 写入pos 位置

buf[pos] = (byte)value;

//pos 永远指向 待写入数据的下标

pos ++;

}

}

public void flush() throws Exception{

if(pos != 0){

//将缓冲区中没有写出去的数据,刷新到目的地

os.write(buf, 0, pos);

pos = 0;

}

}

//

public void close() throws Exception{

if(os != null){

//确保在关闭的时候,可以将缓冲区中的数据刷新出去

flush();

os.close();

}

}

}


包装流的关闭问题:

只关闭包装流即可,因为在关闭包装流的方法中,对被包装的流进行了关闭。

 

三、BufferedReaderBufferedWriter

带缓冲区的字符流。缓冲区8192 个字符。 char[]


import java.io.BufferedReader;

import java.io.BufferedWriter;

import java.io.FileReader;

import java.io.FileWriter;

import java.io.IOException;


public class BufferedReaderWriterTest {


public static void main(String[] args) {

copyTextFile();

}

static void copyTextFile(){

FileReader fr = null;

BufferedReader br = null;

FileWriter fw = null;

BufferedWriter bw = null;

try {

fr = new FileReader("./res/my_letter.txt");

br = new BufferedReader(fr);

fw = new FileWriter("./res/my_letter_copy.txt");

bw = new BufferedWriter(fw);

//用于读取一行文本数据,如果方法返回null 则表示读取到了文件的末尾

String str = br.readLine();

while(str != null){

bw.write(str);

//向输出流中写出一个当前系统的换行符  

bw.newLine();

str = br.readLine();

}

catch (Exception e) {

e.printStackTrace();

}finally {

if(br != null){

try {

br.close();

catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

if(bw != null){

try {

bw.close();

catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

if(fr != null){

try {

fr.close();

catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

if(fw != null){

try {

fw.close();

catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

}

}

}


readLine():用于读取一行文本数据。当读取到\r\n时候方法返回。把读取到的所有的内容返回,返回的内容中不包含 \r\n。


四、LineNumberReader

LineNumberReader:是BufferedReader 的子类。增加了用于记录读取到文本数据的多少行的功能。

import java.io.FileReader;

import java.io.LineNumberReader;


public class LineNumberReaderTest {

//将当前文件的所有的内容,打印到控制台,输出的时候,还有行号输出。

public static void main(String[] args) throws Exception{

LineNumberReader lnr = new LineNumberReader(new FileReader("./src/com/bjsxt/io/LineNumberReaderTest.java"));

//设置起始行号

lnr.setLineNumber(100);

String str = null;

//读取一行,并打印一行

while((str = lnr.readLine()) != null){

//获得行号

int number = lnr.getLineNumber();

System.out.println(number + " "+str);

}

lnr.close();

}

}


五、装饰设计模式

装饰设计模式:带缓冲区的字节流,字符流都使用了该设计模式。


作用:增强扩展指定的类的。

public class DecorateTest {

public static void main(String[] args) {

SuperPeople people = new SuperPeople(new Person());

people.eat();

}

}


class Person{

void eat(){

System.out.println("人要吃饭,为了生存!");

}

}

//继承扩展现有的类

class SuperPerson extends Person{

void eat(){

System.out.println("人吃饭不仅仅是为了生存,还是为了更好的生存!享受健康的生活");

}

}


//使用组合扩展现有类

//组合优于继承:组合既可以扩展指定的类型,还可以是指定类型的子类型。

class SuperPeople {

//被扩展的类作为扩展类的实例成员  组合

private Person person;

public SuperPeople(Person person) {

this.person = person;

}

void eat(){

System.out.println("我喜欢吃鱼!");

System.out.println("我喜欢羊腿+啤酒(不能太凉,怂人乐即可)!");

person.eat();

}

}


六、InputStreamReader 和 OutputStreamWriter

InputStreamReader:转换流:从字节到字符的转换的流。字符流

解码器--所有的字符流都以它为基础进行工作。


public class InputStreamReader extends Reader

InputStreamReader 是字节流通向字符流的桥梁:它使用指定的 charset 读取字节并将其解码为字符。它使用的字符集可以由名称指定或显式给定,或者可以接受平台默认的字符集。


每次调用InputStreamReader 中的一个 read() 方法都会导致从底层输入流读取一个或多个字节。


InputStreamReader :给它提供一堆字节数据,它可以根据字符集返回给你一堆字符数据。

吃的是字节,挤的是字符。



所有的字符输出流,最终写到磁盘中的是字节数据。

write(String)


OutputStreamWriter: 字符输出流

 

public class OutputStreamWriter extends Writer  

OutputStreamWriter 是字符流通向字节流的桥梁:可使用指定的 charset 将要写入流中的字符编码成字节。它使用的字符集可以由名称指定或显式给定,否则将接受平台默认的字符集。

 

每次调用write() 方法都会导致在给定字符(或字符集)上调用编码转换器。在写入底层输出流之前,得到的这些字节将在缓冲区中累积。可以指定此缓冲区的大小,不过,默认的缓冲区对多数用途来说已足够大。注意,传递给 write() 方法的字符没有缓冲。

 

为了获得最高效率,可考虑将OutputStreamWriter 包装到 BufferedWriter 中,以避免频繁调用转换器。

 

总结:InputStreamReader 是所有的字符输入流字节到字符转换的基础。解码转换器。是所有的字符输入流的实现都依赖于该类提供的解码的功能。

OutputStreamWriter  是所有的字符输出流字符到字节转换的基础。编码转换器。是所有的字符输出流的实现都依赖于该类提供的编码的功能。


字节数据:密文

字符集:整数和字符对应的一个映射表

字节数据对应的字符序列:明文


编码:字符-->字节

解码:字节-->字符


例1:

import java.io.BufferedReader;

import java.io.BufferedWriter;

import java.io.FileInputStream;

import java.io.FileWriter;

import java.io.InputStreamReader;


public class InputStreamReaderTest {


public static void main(String[] args) throws Exception {

test1();

}

static void test() throws Exception{

//如果不显示指定字符集,使用平台默认的字符集工作的 转换流,给它提供字节数据

//可以显式指定字符集

InputStreamReader isr = new InputStreamReader(new FileInputStream("./res/3.txt"),"utf-8");

BufferedReader br = new BufferedReader(isr);

String str = br.readLine();

while(str != null){

System.out.println(str);

str = br.readLine();

}

br.close();

}

//接收键盘的输入,将输入的内容写入到指定的文件中。如果输入了bye,那么输入终止

static void test1() throws Exception{

//将键盘输入的字节流,转换为字符流

InputStreamReader isr = new InputStreamReader(System.in);

//为了提高效率 使用BufferedReader 包一层

BufferedReader br = new BufferedReader(isr);

BufferedWriter bw = new BufferedWriter(new FileWriter("./res/input.txt"));

//接收键盘的输入了,当回车的时候,该方法返回。

String str = br.readLine();

while(!"bye".equals(str)){

bw.write(str);

bw.newLine();

bw.flush();

str = br.readLine();

}

br.close();

bw.close();

}


}


例2:

import java.io.BufferedWriter;

import java.io.FileOutputStream;

import java.io.OutputStreamWriter;


public class OutputStreamWriterTest {


public static void main(String[] args) throws Exception {

test();

}

static void test() throws Exception{

//使用平台默认的字符集进行编码 成字节,通过out 字节流,将 编码得到的字节写出到底层

// OutputStreamWriter osw = new OutputStreamWriter(out)

OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("./res/6.txt"),"UTF-8");

BufferedWriter bw = new BufferedWriter(osw);

//写到bw 中的缓冲区中

bw.write("月上柳梢头,人约黄昏后!");

bw.close();

}

}


七、适配器设计模式

适配器设计模式:

InputStreamReader :吃的是字节,产出的是字符。


适配器:Adapter:

笔记本和手机充电器中的适配器的作用:吃的是生活电压(220V),产出的是我们笔记本,和手机充电需要的电压。


有类适配器设计模式和对象适配器设计模式。


public class AdapterTest {

public static void main(String[] args) {

// MyAdapter adapter = new MyAdapter();

// adapter.run();

MyObjAdapter adapter = new MyObjAdapter(new Adaptee());

adapter.run();

}

}


//底层工作的电压

class Adaptee{

int run(){

System.out.println("我提供了220V的电压");

return 220;

}

}


//类适配器设计模式  使用继承

class MyAdapter extends Adaptee{

//笔记本的工作电压为22V

int run() {

int num = super.run();

System.out.println("220V电压被转换为22V工作电压了!");

return num/10;

}

}


//对象适配器设计模式--使用组合方式,把被适配的对象作为成员存在

class MyObjAdapter{

Adaptee adaptee;

public MyObjAdapter(Adaptee adaptee) {

this.adaptee = adaptee;

}

int run(){

int num = adaptee.run();

System.out.println("220V电压被转换为22V工作电压了!");

return num/10;

}

}


1240
目录
相关文章
|
1月前
|
存储 编译器 C++
【C++修行之道】(引用、函数提高)
【C++修行之道】(引用、函数提高)
|
10月前
|
C语言
【C语言—零基础第九课】函数中的爱恨情仇
我们举个例子,你现在是老板你要求你的秘书去完成一项任务你可以给他说让他去做某一项任务,也可以不给他说让他去做某一项任务(暗示他)当然你得是老板。只要你是老板你就可以无限次的让秘书去做某一项任务,并且他没有怨言。
34 0
|
机器学习/深度学习 人工智能 Java
|
存储 算法 Java
揭开数组的真面目
揭开数组的真面目
76 0
|
JavaScript 前端开发 C语言
带你读书之“红宝书”:第十章 函数③
带你读书之“红宝书”:第十章 函数③
77 0
带你读书之“红宝书”:第十章 函数③
|
存储 JavaScript 前端开发
带你读书之“红宝书”:第十章 函数②
带你读书之“红宝书”:第十章 函数②
70 0
带你读书之“红宝书”:第十章 函数②
|
前端开发 JavaScript C语言
带你读书之“红宝书”:第十章 函数①
带你读书之“红宝书”:第十章 函数①
65 0
带你读书之“红宝书”:第十章 函数①
|
前端开发 C语言
带你读书之“红宝书”:第十章 函数④
带你读书之“红宝书”:第十章 函数④
60 0
带你读书之“红宝书”:第十章 函数④
|
前端开发 C语言
带你读书之“红宝书”:第十章 函数⑦
带你读书之“红宝书”:第十章 函数⑦
64 0
带你读书之“红宝书”:第十章 函数⑦
|
安全 前端开发 C语言
带你读书之“红宝书”:第十章 函数⑥
带你读书之“红宝书”:第十章 函数⑥
52 0
带你读书之“红宝书”:第十章 函数⑥