java 基础之IO流 字符流与装饰模式概述 --06



17 IO 流

IO流用来处理设备之间的数据传输
Java对数据的操作是通过流的方式
Java用于操作流的对象都在IO包中

流按操作数据分为两种:字节流 input,output 与字符流 reader,writer 。  
流按流向分为:输入流 input,reader,输出流 output, writer。

17.1 IO常用基类

字节流的抽象基类:
InputStream ,OutputStream。
字符流的抽象基类:
Reader , Writer。
注:由这四个类派生出来的子类名称都是以其父类名作为子类名的后缀。
如:InputStream的子类FileInputStream。
如:Reader的子类FileReader。

io的书写规范
导入IO包中的类
进行IO异常处理
在finally中对流进行关闭
思考:
有了垃圾回收机制为什么还要调用close方法进行关闭。
  io流调用的windos的流处理线程 因此回收机制不会对此处理 需要单独 关闭  
为什么IO异常一定要处理。

17.2 字符流 Reader  Writer

文件字符流  FileReader FileWriter
创建流对象,建立数据存放文件
FileWriter fw = new FileWriter(“Test.txt”);
调用流对象的写入方法,将数据写入流
fw.write(“text”);
关闭流资源,并将流中的数据清空到文件中。
fw.close();
不写close方法会有什么结果呢?
java调用的是windos的系统资源  如果流不关闭着不会关闭该系统资源
如果想在原有文件上继续加入新的数据呢?
1.FileWriter(File file, boolean append) 
          根据给定的 File 对象构造一个 FileWriter 对象。 appede 确定是否添加在文件末尾
2.FileWriter(String fileName, boolean append) 
          根据给定的文件名以及指示是否附加写入数据的 boolean 值来构造 FileWriter 对象。
IO异常的专业处理方式
  IO 异常一般要往上层抛 要判断 fw是否等于null;

建立一个流对象,将已存在的一个文件加载进流。
FileReader fr = new FileReader(“Test.txt”);
创建一个临时存放数据的数组。
char[] ch = new char[1024];
调用流对象的读取方法将流中的数据读入到数组中。
fr.read(ch);
思考:
在加载文件时候是否是将文件全部加载进流
   不会,一般会有缓冲机制  
为什么定义数组,要定义多大呢?
    定义数组就相当于水龙头的开关 决定每次重缓冲池读取多少量的数据

注意事项:
定义文件路径时,可以用“/”或者“\\”。
在创建一个文件时,如果目录下有同名文件将被覆盖。
在读取文件时,必须保证该文件已存在,否则出异常。
文件Copy综合示例  使用缓冲流copy 复制
package cn;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;


/**
 * 使用带缓冲功能的字节流复制文件。
 * @author 李昂志
 */
public class Test5 {
	public static void copy(String fileName,String toWhere) throws IOException{
		System.out.println("开始copy文件 文件路径:"+fileName +",复制路径:"+toWhere);
		BufferedReader br = null;
		BufferedWriter out = null;
		try {
			//BufferedReader 缓冲读取流
			br = new BufferedReader(new FileReader(fileName));
			//BufferedWriter 缓冲写入流
			out = new BufferedWriter(new FileWriter(new File(toWhere)));
			String s = null;
			while((s=br.readLine())!=null){
				System.out.println(s);
				out.append(s+"\n");  //写入的时候要记得换行
				out.flush(); //记得流要刷新
			}
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally{
			//关闭流
			if(br!=null){
				br.close();
			}
			if(out!=null){
				out.close();
			}
		}
		System.out.println("copy完毕");
	}
	public static void main(String[] args) {
		try {
			Test5.copy("abc.txt", "CopyFile/abc.txt");
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

上述示例使用了 Buffered 缓冲流

17.3  字符流的缓冲区

作用:缓冲区的出现提高了对数据的读写效率。
        对应类
        BufferedWriter
BufferedReader
缓冲区要结合流才可以使用。
在流的基础上对流的功能进行了增强。

自定义缓冲流
package test2;

import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;


/**
 * 自定义缓冲字符流
 * 难点: 如果要实现一个类似缓冲流的缓冲区  这个问题还没想透彻
 * @author 李昂志
 */
public class MyBufferedReader extends Reader{
	private static int bufferdSize = 9999;   //字符缓冲区
	private Reader in = null;
	private char[] cs;  //用来存储字符缓冲的数据
	
	public MyBufferedReader(Reader in , int size){
		super(in);
		if(size<=0){
			throw new IllegalArgumentException("Buffer size <= 0");
		}
		MyBufferedReader.bufferdSize = size;
		this.in = in;
	}
	public MyBufferedReader(Reader in){
		this(in,bufferdSize);
	}
	@Override
	public int read(char[] cbuf, int off, int len) throws IOException {
		
		return in.read(cbuf, off, len);
	}
	/**
	 * 读取一行文本 ,读到换行处则 退出
	 * @return 读取一行的文本 字符串
	 * @throws IOException
	 */
	public String readline() throws IOException{
		StringBuilder sb = null;
		char c ='A';
		cs = new char[bufferdSize];
		int i,j =0;
		while((i = in.read()) != -1){
			if(sb == null){
				sb = new StringBuilder();
			}
			c = (char) i;
			if ( c == '\r') continue;
			if ( c == '\n') break;
			cs[j++] = c;
		}
		if(sb != null ) sb.append(cs ,0 ,j);
		else return null;
		return sb.toString();
	}
	/**
	 * 获取缓冲池大小
	 * @return
	 */
	public int getBufferdSize() {
		return bufferdSize;
	}
	@Override
	public void close() throws IOException {
		// TODO Auto-generated method stub
		if(in != null){
			in.close();
		}
	}
	public static void main(String[] args) throws IOException {
		System.out.println("----");
		MyBufferedReader in = new MyBufferedReader(new FileReader("abc.txt")); 
		String s = null;
		while((s = in.readline())!= null){
			System.out.println(s);
		}
		in.close();
	}
}

17.4 装饰设计模式

1. 概述 
Decorator装饰模式是一种结构型模式,它主要是解决:“过度地使用了继承来扩展对象的功能”,
由于继承为类型引入的静态特质,使得这种扩展方式缺乏灵活性;并且随着子类的增多(扩展功能的
增多),各种子类的组合(扩展功能的组合)会导致更多子类的膨胀(多继承)。继承为类型引入的
静态特质的意思是说以继承的方式使某一类型要获得功能是在编译时。所谓静态,是指在编译时;动态,是指在运行时。
   GoF《设计模式》中说道:动态的给一个对象添加一些额外的职责。就增加功能而言,Decorator模式
比生成子类更为灵活。
缓冲流使用了装饰设计模式
BufferedWriter --- 装饰 Writer
BufferedReader --- 装饰 Reader 
这两个类均是使用的装饰设计模式
在装饰类中 一般会给构造函数传入一个需要装饰的类
如在: BufferedReader的构造方法中都需要 传入一个Reader的子类
下面我们来看看BufferedReader的几个构造方法
BufferedReader(Reader in) 
          创建一个使用默认大小输入缓冲区的缓冲字符输入流。 
BufferedReader(Reader in, int sz) 
          创建一个使用指定大小输入缓冲区的缓冲字符输入流。 

2. 特点
(1) 装饰对象和真实对象有相同的接口。这样客户端对象就可以和真实对象相同的方式和装饰对象交互。
(2) 装饰对象包含一个真实对象的引用(reference)
(3) 装饰对象接受所有来自客户端的请求。它把这些请求转发给真实的对象。
(4) 装饰对象可以在转发这些请求以前或以后增加一些附加功能。这样就确保了在运行时,不用修改
      给定对象的结构就可以在外部增加附加的功能。在面向对象的设计中,通常是通过继承来实现对给定
      类的功能扩展。
3.适用性
以下情况使用Decorator模式
(1) 需要扩展一个类的功能,或给一个类添加附加职责。
(2) 需要动态的给一个对象添加功能,这些功能可以再动态的撤销。
(3) 需要增加由一些基本功能的排列组合而产生的非常大量的功能,从而使继承关系变的不现实。
(4) 当不能采用生成子类的方法进行扩充时。一种情况是,可能有大量独立的扩展,为支持每一种
      组合将产生大量的子类,使得子类数目呈爆炸性增长。另一种情况可能是因为类定义被隐藏,或
      类定义不能用于生成子类。
4.优点 
(1) Decorator模式与继承关系的目的都是要扩展对象的功能,但是Decorator可以提供比继承更多的灵活性。
(2) 通过使用不同的具体装饰类以及这些装饰类的排列组合,设计师可以创造出很多不同行为的组合。

5.缺点
(1) 这种比继承更加灵活机动的特性,也同时意味着更加多的复杂性。
(2) 装饰模式会导致设计中出现许多小类,如果过度使用,会使程序变得很复杂。
(3) 装饰模式是针对抽象组件(Component)类型编程。但是,如果你要针对具体组件编程时,
      就应该重新思考你的应用架构,以及装饰者是否合适。当然也可以改变Component接口,增加新的公
      开的行为,实现“半透明”的装饰者模式。在实际项目中要做出最佳选择。
6.代码示例
在装饰模式中的各个角色有:
  (1)抽象构件(Component)角色:给出一个抽象接口,以规范准备接收附加责任的对象。
  (2)具体构件(Concrete Component)角色:定义一个将要接收附加责任的类。
  (3)装饰(Decorator)角色:持有一个构件(Component)对象的实例,并实现一个与抽象构件接口一致的接口。
  (4)具体装饰(Concrete Decorator)角色:负责给构件对象添加上附加的责任。
下面我们来实现一个装饰模式 基类为GpsPhone
package test2;

/**
 * 定义一个手机的接口  gps 定位
 * @author 李昂志
 *
 */
public abstract class GpsPhone {
	/**
	 * 拨号吗 成功返回true
	 * @return
	 */
	public abstract String gps();
}
/**
 * 三星手机属于 手机的一个子类
 * @author 李昂志
 */
class SanXinPhone extends GpsPhone{
	
	@Override
	public String gps() {
		// TODO Auto-generated method stub
		return "SanXinPhone 发送 Gps 定位";
	}
}
/**
 * 装饰类  --- 加强手机的功能
 * 这个类继承了一个GpsPhone 类 又 自定义了一个 GpsPhone 对象
 * 这样做的意义是:Decorator类又使用了另外一个Component类。
 * 我们可以使用一个或多个Decorator对象来“装饰”一个Component对象,且装饰后的对象仍然是一个Component对象。
 * @author 李昂志
 */
class Decorator extends GpsPhone {
	private GpsPhone ph;
	public Decorator(GpsPhone ph){
		this.ph = ph;
	}
	/**
	 * 提供一个记忆查找功能
	 */
	public void RemberPhone(){
		System.out.println("查找");
	}
	@Override
	public String gps() {
		System.out.println("Decorator  :  进行了装饰优化" );
		return ph.gps();
	}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
数字乡村和智慧农业的数字化转型是当前农业发展的新趋势,旨在通过应用数字技术,实现农业全流程的再造和全生命周期的管理服务。中国政府高度重视这一领域的发展,提出“数字中国”和“乡村振兴”战略,以提升国家治理能力,推动城乡融合发展。 数字乡村的建设面临乡村治理、基础设施、产业链条和公共服务等方面的问题,需要分阶段实施《数字乡村发展战略纲要》来解决。农业数字化转型的需求包括满足市民对优质农产品的需求、解决产销对接问题、形成优质优价机制、提高农业劳动力素质、打破信息孤岛、提高农业政策服务的精准度和有效性,以及解决农业融资难的问题。 数字乡村建设的关键在于构建“1+3+4+1”工程,即以新技术、新要素、新商业、新农民、新文化、新农村为核心,推进数据融合,强化农业大数据的汇集功能。数字农业大数据解决方案以农业数字底图和数据资源为基础,通过可视化监管,实现区域农业的全面数字化管理。 数字农业大数据架构基于大数据、区块链、GIS和物联网技术,构建农业大数据中心、农业物联网平台和农村综合服务指挥决策平台三大基础平台。农业大数据中心汇聚各类涉农信息资源和业务数据,支持大数据应用。信息采集系统覆盖市、县、乡、村多级,形成高效的农业大数据信息采集体系。 农业物联网平台包括环境监测系统、视频监控系统、预警预报系统和智能控制系统,通过收集和监测数据,实现对农业环境和生产过程的智能化管理。综合服务指挥决策平台利用数据分析和GIS技术,为农业决策提供支持。 数字乡村建设包括三大服务平台:治理服务平台、民生服务平台和产业服务平台。治理服务平台通过大数据和AI技术,实现乡村治理的数字化;民生服务平台利用互联网技术,提供各类民生服务;产业服务平台融合政企关系,支持农业产业发展。 数字乡村的应用场景广泛,包括农业生产过程、农产品流通、农业管理和农村社会服务。农业生产管理系统利用AIoT技术,实现农业生产的标准化和智能化。农产品智慧流通管理系统和溯源管理系统提高流通效率和产品追溯能力。智慧农业管理通过互联网+农业,提升农业管理的科学性和效率。农村社会服务则通过数字化手段,提高农村地区的公共服务水平。 总体而言,数字乡村和智慧农业的建设,不仅能够提升农业生产效率和管理水平,还能够促进农村地区的社会经济发展,实现城乡融合发展,是推动中国农业现代化的重要途径。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值