發表文章

目前顯示的是 2016的文章

Node.js 小密技:以 Readline 核心模組一行行讀取檔案內容

圖片
最近參與了一些關於資料處理的專案,處理了很多各式各樣的原始資料(Raw Data)或各種不同格式的資料,於是使用到了 Node.js 上的一些小技巧。像是一行行讀取檔案內容這件事,就隱藏了一些技巧。 對很多人來說,處理的檔案內容都不大,如果用 Node.js 來一行行讀取檔案內容,不外乎就是將整個檔案讀出後再進行切割,做法大致上如下: var fs = require('fs'); fs.readFile('example.txt', function(err, data) { // 以換行字元作為切割點,將內容切成一個大陣列 var lines = data.split('\n'); lines.forEach(function(line) { // 一行行處理 }); }); 但有些時候,由於檔案並不小,若又牽涉到運算,不可能整個檔案都讀出到記憶體上才進行切割,這時就得用到 Stream(資料流)機制,將檔案一段段讀出來進行處理。然後,為了進行一行行的切割,我們會自己做這樣的機制,先將一段段讀取出來的檔案內容放到緩衝區(Buffer),然後找到換行字元進行切斷取出,然後再繼續讀取檔案,重複這樣的過程直到檔案結尾。 的確,實做這樣的機制有點麻煩,所以其實能利用 Node.js 現成內建的核心模組 Readline 來做到切割資料流中一行字串的工作。因為常見的 Readline 用法都是拿來做終端機字元模式下的命令列操作,所以許多人沒有想到可以這樣使用 Readline。作法其實很簡單,就把 Readline 的 input 從標準輸入(Standard Input)換成我們的檔案讀取資料流就可以。 完整做法如下: var fs = require('fs'); var readline = require('readline'); // 建立檔案讀取資料流 var inputStream = fs.createReadStream('example.txt'); // 將讀取資料流導入 Readline 進行處理 var lineReader = readline.createInterfac...

產品開發玩技術很過癮!實作 QML 動畫背景!

圖片
由於最近在開發自己的產品,又開始重操舊業,開發起 Linux 系統的相關應用和嵌入式技術。為了這個產品,精心開發了一個使用者介面,除了動手把驅動程式搞定、圖形化介面搞定,也調教效能、改善系統架構。 開發自己的產品很過癮,愛怎麼搞就怎麼搞!於是,看到死板的背景覺得很不舒服,就在思考是否可以跑個動畫背景呢? 因為使用的是 QML 技術來開發 UI,最直接的想法,就是用 QtMultimedia 的 MediaPlayer 無限循環播放一個影片,當作動畫背景: MediaPlayer { id: bg; source: 'bg.mov'; loops: MediaPlayer.Infinite; autoPlay: true; } VideoOutput { anchors.fill: parent; source: bg; } 當然,我們選擇的背景影片,是一個開頭跟結尾一樣的影片,如果正確循環播放,會無縫接軌的變成一個順暢的動畫背景。 然而,結果不如預期,碰到了一個問題,那就是每當背景影片播放到最後時,會畫面變成全黑,然後才再一次重新開始播放,沒辦法「無縫接軌」。仔細暸解以後,發現 MediaPlayer 元件是 QMediaPlayer 的 QML Type 實作,所有秘密都藏在 QMediaPlayer 之中。因為 QMediaPlayer 預設所有的通知事件,都是固定以 1000ms(1秒)的頻率來觸發,這代表,當 QML 元件發現影片播完時,通常已經是播完以後的事了,所以畫面一定會因為影片結束而變黑,然後 QML 元件才發現影片結束,重新進行播放。 知道緣由後,我們可以從事件更新頻率下手,讓 QML 元件發現影片播完的時間更接近實際影片結束的時間,但這必須動用到 C/C++ 的實作,因為 QMediaPlayer 的事件更新頻率無法以純 QML 的方法修改。 C/C++ 完整應用程式的實作如下,我們把更新頻率調高為每 100ms 一次: #include <QGuiApplication> #include <QQmlApplicationEngine> #include <QQuickWindow> #include ...

JavaScript 好用的 async 異步函數!

圖片
先聲明,async 異步函數是 ECMAScript 第七版(ES7)才被支援的語法和特性,目前 ES7 還沒有被大多數的 JavaScript Engine 所實作,如果你要使用,需要用到 babel 這類工具,先把此程式編譯轉換,讓其可在舊版本 JavaScript Engine 上執行。 如果你覺得以 co 模組來操作 Generator 很好用,你可以想像 async 異步函數就是原生的 co,幾乎是同樣的使用方式,同樣的使用概念,只不過不再需要使用 generator 和 yield 這類語法。如果你是個過不了在函數上有個醜陋「*」符號這一關的人,async 異步函數的使用方式應該會讓你感覺到舒服許多。 什麼是 async 異步函數(async functions)? 異步函數使用方式其實和一般的函數一樣,只不過在這函數之內的程式,可以用 await 的語法去執行並等待異步工作(如:Promise)而不需要使用到骯髒的 callback function。宣告並使用一個 async 異步函數,就是在定義函數時加上「async」,然後直接執行這個函數即可,簡單的範例如下: async function myAsyncFunc() { console.log('Hello async functions!'); } myAsyncFunc(); 搭配 Promise 的使用 Promise 通常被大量用來管理非同步的工作,並讓開發者容易管理錯誤拋出等機制,一個典型的 Promise 使用如下: var task = new Promise(function(resolve, reject) { // 執行一個非同步的工作,完成後呼叫帶入的 callback doAsyncTask(function(err) { // 有問題呼叫 reject,並帶入錯誤值 if (err) return reject(err); // 成功呼叫 resolve 並帶入回傳值 resolve('VALUE'); }); }); // 使用 then 去執行並等待工作完成,成功會呼叫 callba...

下一代的框架:Koa 1.0 起手式

圖片
身為 Node.js 使用者的你,還在使用 Express 嗎?快來使用下一代的 Web Framework 吧!Koa 是由 Express 的開發者們出來所開發的新網站框架,嘗試採用了最新的 ECMAScript 6 語法,讓開發者可以用更簡約的方式,開發網站應用程式,讓程式碼更好維護之外,也能受益於最新的語言特性。 穩定版與不穩定版 現在的 Koa 分為 1.0 和 2.0 兩個版本,1.0 使用 ES6 的 Generator 特性,也是目前的 stable 版本,而 2.0 採用 ES7+ 的 async/await,據 Koa 官方說法,2.0 穩定度可以用於實際產品,只是在 ECMAScript 7 規格正式敲定,且 JavaScript V8 Engine 推出原生的實作之前,將無限期處於 unstable 的狀態。也就是說,若你想要在你自己的專案上使用 2.0,你必須使用 babel 這一類的編譯器,因為裡面用到了 ES7 的語法。 本篇文章的重點將放在 Koa 1.0 之上,畢竟在 ECMAScript 7 還處於草案階段的現在,很難說未來會不會有什麼改變。 安裝 Koa 由於 Koa 需要用到 ECMAScript 6 的語言特性,請先檢查你的 Node.js 版本,最少為 0.12 以上,如果你已經使用了 Node.js 4.0 或更高版本,請不用擔心這個問題。 然後透過 NPM 即可安裝模組: npm install koa 開發第一個應用程式 開發 Koa 應用程式非常容易,下面是程式碼範例: var koa = require('koa'); var app = koa(); app.use(function *() { this.body = 'Hello World'; }); app.listen(3001); 跑起來後,用瀏覽器連入 3001 埠即可看到「Hello World」的字樣,因為 this.body 的內容,將會被輸出到前端瀏覽器上。 使用 Generator 打造的 Middleware koa.use() 將用來載入 Middleware,所有連線工作都會經過 Middleware 處理。所以前一個例子裡,我們...

MakerBoard: 自幹 MT7688 模擬器!簡報釋出!

圖片
使用 MTK LinkIt Smart 7688 這類開發板時,總是很痛苦,由於儲存空間不大,記憶體也不大,常常在開發的過程中飽受折磨。於是我們開始思考如何可以在自己的電腦上,模擬一個 MT7688 的環境,在有充沛資源的機器上進行開發。就這樣,前陣子開發了一個小小的 Open Source 工具專案「MakerBoard」,並在 MakerCup 的共筆網站發表「 沒有板子也可以玩的 7688 模擬器! 」。 雖然這樣一個小小的模擬器運用了 VM 和 Container 相關技術。但其實主要概念並不難,這次 5/10 在台大的開放原始碼課程中,就簡單從 MakerBoard 這專案出發,然後說明了一下怎麼樣自己打造一個簡單的 Container,並利用 QEMU 來進行 Binary Translation 的工作。 簡報釋出,請自行服用: