項目源代碼可訪問我的github:https://github.com/Spacider/Gather-and-store
如果覺得好的話請給個star哦~
開發IDE: IDEA 2018.03 JDK 1.8
開發環境: macOS 10.13.6 (如windows請對項目中部分路徑進行改寫)
數據庫: Oracle 11g
第二階段:數據的採集和寫入日誌文件
在JAVA實踐項目—樹莓派信息自動化採集後入庫項目(二)(https://blog.csdn.net/qq_37163479/article/details/83023261) 中我們從模擬的樹莓派服務器上得到了我們需要採集的數據,接下來我們要乾的事兒就是把得到的XML繼續解析,等到相應的數據把其寫入一個文件中!文件內容如下圖所示:
話不多說,開始編寫代碼:
- 在我們的
SAXReaderHelper
類中編寫方法InLogFile
:將獲取到數據寫入到日誌文件中。
public static void InLogFile(String str,String SensorAddress,String counter){
}
它由3個參數,分別是我們讀取的XML文件(通過流實際上使用的是String來接收),由於SensorAddress
和counter
參數返回的XML文件中沒有這兩個參數,所以我們通過傳參的方式把這兩個參數傳入!
這裏我們又用到了dom4j技術對其進行解析:
// 把客戶端傳過來的 xml 轉化爲字符串存儲
String TotalStr = str.toString();
byte[] TotalBytes = TotalStr.getBytes();
// dom4j 構建對象內填入一個 byte 類型的數組
bais = new ByteArrayInputStream(TotalBytes);
SAXReader reader = new SAXReader();
Document document = null;
通過對象流的方式直接交給dom4j:
try {
document = reader.read(bais,"utf-8");
}
有了document
對象以後我們就可以解析了,接下來我們用一個StringBuilder來對字符串進行拼接,拼接成上圖我們講過的樣子。最後加上"\r\n"
,這樣最後寫入文件的時候每一條數據會換行。
// 獲取根節點
Element Message = document.getRootElement();
StringBuilder sb = new StringBuilder();
// 拼接字符串
sb.append(Message.element("SrcID").getText()+"|");
sb.append(Message.element("DstID").getText()+"|");
sb.append(Message.element("DevID").getText()+"|");
sb.append(SensorAddress+"|");
sb.append(counter+"|");
sb.append(Message.element("Cmd").getText()+"|");
sb.append(Message.element("Data").getText()+"|");
sb.append(Message.element("Status").getText()+"|");
sb.append(new Timestamp(System.currentTimeMillis()));
sb.append("\r\n");
得到拼接好數據的字符串以後我們要做的就是寫入文件了,這裏用到了文件輸出流,最後記得flush
哦!刷一下內容纔會進去
注意:請在src下先創建radwtmp
文件,這裏的"/Users/wjh/Desktop/FirstProject/src/radwtmp"
路徑爲我電腦上路徑,請改成你的路徑!
File file = new File("/Users/wjh/Desktop/FirstProject/src/radwtmp");
if (!file.exists()){
file.createNewFile();
}
fos = new FileOutputStream(file,true);
fos.write(sb.toString().getBytes());
fos.flush();
- 封裝好方法以後我們就可以調用它了,在
ClientReceiveHelper
的ClientGetXml
方法最後加入這麼一行:
// 根據 XML 文件解析,並將其寫入文件中
SAXReaderHelper.InLogFile(sb.toString(), SensorAddress, counter + "");
- 編寫客戶端主程序:
DataClient(溫度溼度客戶端),GuangClient(樹莓派光照客戶端),CarbonDioxideClient(二氧化碳客戶端):
傳入SensorAddress
爲傳感器ID,16表示溫度溼度傳感器,256表示光照傳感器,1280表示二氧化碳傳感器
public static void DataGetObj(){
ClientReceiveHelper.ClientGetXml("16",1);
}
public static void guangGetObj(){
ClientReceiveHelper.ClientGetXml("256",1);
}
public static void CarbonDioxideGetObj(){
ClientReceiveHelper.ClientGetXml("1280",1);
}
- 爲了方便操作,我們設立一個定時器,編寫一個定時器類:
public final class TimerRunClient {
public static void runClientMain() {
// 構建定時器
Timer timer = new Timer(false);
/**
* 第一個參數表示定時器執行的函數,第二個參數表示第一次定時器生效的時間,第三個參數表示每隔多長事件調用第一個參數所指向的方法
* 第二個參數和第三個參數單位是毫秒
*/
timer.schedule(new TimerTask() {
@Override
public void run() {
// 定時器調用的代碼
DataClient.DataGetObj();
GuangClient.guangGetObj();
CarbonDioxideClient.CarbonDioxideGetObj();
}
}, 0, 5000);
}
public static void main(String[] args) {
runClientMain();
}
}
- 運行定時器類(TimerRunClient)和樹莓派系統數據模擬類(DataServer),看到radwtmp類中數據如下圖所示即爲成功!
本文中爲代碼詳解,可能與源代碼不一定相同,可以查看我的github:https://github.com/Spacider/Gather-and-store 查看源代碼與你的代碼進行比對!如果覺得我寫的好的話請給一個star哦!