JAVA 实践项目 --- 树莓派信息自动化采集后入库项目 (四)

本贴最后更新于 2088 天前,其中的信息可能已经沧海桑田

项目源代码可访问我的 github:https://github.com/Spacider/Gather-and-store
如果觉得好的话请给个 star 哦~

开发 IDE: IDEA 2018.03 JDK 1.8
开发环境: macOS 10.13.6 (如 windows 请对项目中部分路径进行改写)
数据库: Oracle 11g


第三阶段:从日志文件中采集并发送数据

在 JAVA 实践项目---树莓派信息自动化采集后入库项目(三)中写到将数据写入日志文件中,接下来我们就要从日志文件中数据取出来并发送给 Server 端。
imagepng

此层项目结构为
imagepng


接下来开始看代码:
1.采集模块:

  • 定义一个 Gather 借口
public interface Gather  {
    /**
     * 采集模块接口实现
     * 对 src 下日志进行处理,一行日志封装成一个 Environment 对象或者两个 Environment 对象
     * 所有采集到的对象封装到集合中
     * @return
     */
    Collection<Environment> gather();
}

  • 有了接口之后再定义个包为 Impl,专门用来放实现类,在 Impl 下定义一个类为 GatherImpl,它实现了 Gather 接口。
public final class GatherImpl implements Gather  {
}

在实现类中写一个采集的主方法:

public Collection<Environment> gather(){
}

写方法实现之前想到一个问题:如果客户端发送到服务器的过程中出现意外怎么办?数据是否会丢失?会不会发送错行?
在经过考虑以后,想出一个解决方案:

使用 RandomAccessFile 流,它有一个 seek() 方法可以跳过之前已经读取过的字节数,这样的话我们每发送一次,就把已经发送的字节数储存在一个文件中,每次都读取这个文件,保证现在发的是上一次的末尾。

代码实现:

  • 读取储存文件,如果文件不存在,说明第一次运行,则创造一个新文件:
Properties properties = new Properties();
File positionFile = new File(“/Users/wjh/Desktop/FirstProject/src/main/resources/FilePostion.properties”);
if (!positionFile.exists()){
    positionFile.createNewFile();
}
properties.load(new FileReader(positionFile));
String FilePostion = properties.getProperty("FilePostion");
  • 跳过已经读取的字节数,并通过 String 类的 split 方法拆分字符串
while ((str = raf.readLine()) != null) {
    // 运用 | 来拆分字符串
    String[] stringList = str.split("\\|");
    getenv(stringList);
}

// 将最后的位数写回文件
properties.setProperty("FilePostion" , position+"");
pw = new PrintWriter(positionFile);
properties.store(pw,null);

getenv 方法的作用是根据所传入的拆分后的字符串来生成新的对象并返回,这里在实际与树莓派交互过程中出现了脏数据的情况,通过 if 语句来筛选出正确数据,实现:

private void getenv(String[] stringList){
    String sensorAddress = stringList[3];
    int FinalDate = 0;

    FinalDate = Integer.parseInt(stringList[6].substring(0, 4), 16);

    if (sensorAddress.equals("16")) {
        if (stringList[6].length() != 10){
	        System.out.println("得到的数据为脏数据, 温度湿度错误数据:" + stringList[6]);
        }else {
            /**
             * 温度计算公式:value(int) float Temperature = ((float)value*0.00268127)- 46.85;
             * 湿度:value(int) float Humidity = ((float)value*0.00190735)-6;
             */
            // 生成温度对象,并添加到 list 中
            float Temperature = (float) ((FinalDate * 0.00268127) - 46.85);
            environmentList.add(SetNameAndData(stringList, "温度", Temperature));

            // 生成湿度对象,并添加到 list 中
            FinalDate = Integer.parseInt(stringList[6].substring(4, 8), 16);
            float Humidity = (float) ((FinalDate * 0.00190735) - 6);
            environmentList.add(SetNameAndData(stringList, "湿度", Humidity));
        }
    }else if (sensorAddress.equals("256")){
        if (stringList[6].length() != 6) {
            System.out.println("得到的数据为脏数据, 光照错误数据:" + stringList[6]);
        }else{
            environmentList.add(SetNameAndData(stringList, "光照强度", FinalDate));
        }
    }else if (sensorAddress.equals("1280")){
        if (stringList[6].length() != 6) {
            System.out.println("得到的数据为脏数据, 二氧化碳错误数据:" + stringList[6]);
        }else{
            environmentList.add(SetNameAndData(stringList, "二氧化碳", FinalDate));
        }
    }else{
        System.out.println("得到的数据错误");
    }
}

SetNameAndData 方法为不同的 Enviroment 对象封装名字和数据:

private Environment SetNameAndData(String[] stringList, String name ,float Data){
    String sensorAddress = stringList[3];
    Environment envir = new Environment();
    try {
        envir.setSrcID(stringList[0]);
        envir.setDstID(stringList[1]);
        envir.setDevID(stringList[2]);
        envir.setSensorAddress(sensorAddress);
        envir.setCount(Integer.parseInt(stringList[4]));
        envir.setCmd(Integer.parseInt(stringList[5]));
        envir.setStatus(Integer.parseInt(stringList[7]));
        DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Timestamp ts = new Timestamp(format.parse(stringList[8]).getTime());
        envir.setGather_date(ts);
        envir.setName(name);
        envir.setData(Data);
    } catch (ParseException e) {
        logger.error("设置名字和数据失败");
    }

    return envir;
}

在 GatherImpl 的 gather() 方法中写一个打印语句:

for (Environment environment : environmentList) {
    System.out.println(environment);
}

写到这里,你就可以通过:

public static void main(String[] args) {
    GatherImpl gather = new GatherImpl();
    gather.gather();
}

来进行测试,最后打印出 environment 对象集说明书写正确。


2.发送模块

  • 同样,定义一个接口为 EnvClient:
public interface EnvClient extends WossModel {
    /**
     * 发送采集模块采集的集合对象
     */
    void send(Collection<Environment> col);
}
  • 有了接口以后写它的实现类 EnvClientImpl,它有一个很简单的功能,就是把上文封装好的对象发给服务器:
public class EnvClientImpl implements EnvClient  {
	public void send(Collection<Environment> col) {
	}
}

代码:

socket = new Socket(host,port);
os = socket.getOutputStream();
oos = new ObjectOutputStream(os);
// 运用对象流把生成的对象发给 Server 端
oos.writeObject(col);
oos.flush();

写好这一切以后,定义这一阶段的的主入口,把内容串起来:

public final class ClientMain {

    /**
     * 集合 Client 并提供向外的入口
     * 通过采集所获得的 list 发给 Server
     */
    public static void ClientSendMain(){
        ConfigurationImpl configuration = new ConfigurationImpl();
        Gather gather = configuration.getGather();
        List<Environment> environmentList = (List <Environment>) gather.gather();
        configuration.getClient().send(environmentList);
    }
}
  • Java

    Java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由 Sun Microsystems 公司于 1995 年 5 月推出的。Java 技术具有卓越的通用性、高效性、平台移植性和安全性。

    3169 引用 • 8208 回帖
  • 实践项目
    6 引用

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...

推荐标签 标签

  • jsDelivr

    jsDelivr 是一个开源的 CDN 服务,可为 npm 包、GitHub 仓库提供免费、快速并且可靠的全球 CDN 加速服务。

    5 引用 • 31 回帖 • 52 关注
  • 微软

    微软是一家美国跨国科技公司,也是世界 PC 软件开发的先导,由比尔·盖茨与保罗·艾伦创办于 1975 年,公司总部设立在华盛顿州的雷德蒙德(Redmond,邻近西雅图)。以研发、制造、授权和提供广泛的电脑软件服务业务为主。

    8 引用 • 44 回帖
  • 支付宝

    支付宝是全球领先的独立第三方支付平台,致力于为广大用户提供安全快速的电子支付/网上支付/安全支付/手机支付体验,及转账收款/水电煤缴费/信用卡还款/AA 收款等生活服务应用。

    29 引用 • 347 回帖 • 1 关注
  • Mobi.css

    Mobi.css is a lightweight, flexible CSS framework that focus on mobile.

    1 引用 • 6 回帖 • 708 关注
  • V2Ray
    1 引用 • 15 回帖
  • OnlyOffice
    4 引用 • 15 关注
  • 职场

    找到自己的位置,萌新烦恼少。

    126 引用 • 1699 回帖
  • Webswing

    Webswing 是一个能将任何 Swing 应用通过纯 HTML5 运行在浏览器中的 Web 服务器,详细介绍请看 将 Java Swing 应用变成 Web 应用

    1 引用 • 15 回帖 • 632 关注
  • JVM

    JVM(Java Virtual Machine)Java 虚拟机是一个微型操作系统,有自己的硬件构架体系,还有相应的指令系统。能够识别 Java 独特的 .class 文件(字节码),能够将这些文件中的信息读取出来,使得 Java 程序只需要生成 Java 虚拟机上的字节码后就能在不同操作系统平台上进行运行。

    180 引用 • 120 回帖
  • Oracle

    Oracle(甲骨文)公司,全称甲骨文股份有限公司(甲骨文软件系统有限公司),是全球最大的企业级软件公司,总部位于美国加利福尼亚州的红木滩。1989 年正式进入中国市场。2013 年,甲骨文已超越 IBM,成为继 Microsoft 后全球第二大软件公司。

    103 引用 • 126 回帖 • 442 关注
  • JWT

    JWT(JSON Web Token)是一种用于双方之间传递信息的简洁的、安全的表述性声明规范。JWT 作为一个开放的标准(RFC 7519),定义了一种简洁的,自包含的方法用于通信双方之间以 JSON 的形式安全的传递信息。

    20 引用 • 15 回帖 • 19 关注
  • Kafka

    Kafka 是一种高吞吐量的分布式发布订阅消息系统,它可以处理消费者规模的网站中的所有动作流数据。 这种动作(网页浏览,搜索和其他用户的行动)是现代系统中许多功能的基础。 这些数据通常是由于吞吐量的要求而通过处理日志和日志聚合来解决。

    35 引用 • 35 回帖 • 4 关注
  • GitLab

    GitLab 是利用 Ruby 一个开源的版本管理系统,实现一个自托管的 Git 项目仓库,可通过 Web 界面操作公开或私有项目。

    46 引用 • 72 回帖 • 1 关注
  • FlowUs

    FlowUs.息流 个人及团队的新一代生产力工具。

    让复杂的信息管理更轻松、自由、充满创意。

    1 引用
  • Ngui

    Ngui 是一个 GUI 的排版显示引擎和跨平台的 GUI 应用程序开发框架,基于
    Node.js / OpenGL。目标是在此基础上开发 GUI 应用程序可拥有开发 WEB 应用般简单与速度同时兼顾 Native 应用程序的性能与体验。

    7 引用 • 9 回帖 • 356 关注
  • 负能量

    上帝为你关上了一扇门,然后就去睡觉了....努力不一定能成功,但不努力一定很轻松 (° ー °〃)

    87 引用 • 1206 回帖 • 449 关注
  • 小薇

    小薇是一个用 Java 写的 QQ 聊天机器人 Web 服务,可以用于社群互动。

    由于 Smart QQ 从 2019 年 1 月 1 日起停止服务,所以该项目也已经停止维护了!

    34 引用 • 467 回帖 • 711 关注
  • SQLServer

    SQL Server 是由 [微软] 开发和推广的关系数据库管理系统(DBMS),它最初是由 微软、Sybase 和 Ashton-Tate 三家公司共同开发的,并于 1988 年推出了第一个 OS/2 版本。

    19 引用 • 31 回帖
  • BookxNote

    BookxNote 是一款全新的电子书学习工具,助力您的学习与思考,让您的大脑更高效的记忆。

    笔记整理交给我,一心只读圣贤书。

    1 引用 • 1 回帖 • 1 关注
  • Love2D

    Love2D 是一个开源的, 跨平台的 2D 游戏引擎。使用纯 Lua 脚本来进行游戏开发。目前支持的平台有 Windows, Mac OS X, Linux, Android 和 iOS。

    14 引用 • 53 回帖 • 517 关注
  • Node.js

    Node.js 是一个基于 Chrome JavaScript 运行时建立的平台, 用于方便地搭建响应速度快、易于扩展的网络应用。Node.js 使用事件驱动, 非阻塞 I/O 模型而得以轻量和高效。

    138 引用 • 268 回帖 • 147 关注
  • Postman

    Postman 是一款简单好用的 HTTP API 调试工具。

    4 引用 • 3 回帖
  • VirtualBox

    VirtualBox 是一款开源虚拟机软件,最早由德国 Innotek 公司开发,由 Sun Microsystems 公司出品的软件,使用 Qt 编写,在 Sun 被 Oracle 收购后正式更名成 Oracle VM VirtualBox。

    10 引用 • 2 回帖 • 8 关注
  • OpenStack

    OpenStack 是一个云操作系统,通过数据中心可控制大型的计算、存储、网络等资源池。所有的管理通过前端界面管理员就可以完成,同样也可以通过 Web 接口让最终用户部署资源。

    10 引用 • 1 关注
  • jsoup

    jsoup 是一款 Java 的 HTML 解析器,可直接解析某个 URL 地址、HTML 文本内容。它提供了一套非常省力的 API,可通过 DOM,CSS 以及类似于 jQuery 的操作方法来取出和操作数据。

    6 引用 • 1 回帖 • 477 关注
  • 反馈

    Communication channel for makers and users.

    124 引用 • 907 回帖 • 210 关注
  • API

    应用程序编程接口(Application Programming Interface)是一些预先定义的函数,目的是提供应用程序与开发人员基于某软件或硬件得以访问一组例程的能力,而又无需访问源码,或理解内部工作机制的细节。

    76 引用 • 429 回帖