原話重寫:一個意外的發現是,原本被視為 bug 的問題其實是 Protobuf 設計中的一個特性
大家好,我是了不起。
最近我們在專案中,透過使用 protobuf 格式作為儲存資料的一個載體。一個不小心就給自己埋了個大坑,還是過了好久才發現。
protobuf 簡介
protobuf 全名為Protocal buffers. 它是由Google 研發的,一種可跨語言、可跨平台、可擴展的序列化數據的機制。類似於 XML ,但它更小、更快、更簡單。你只需要定義一次你希望的資料如何被結構化,然後你可以使用它的產生工具,產生包含一些序列化和反序列化等操作的原始碼。可以輕鬆地從各種資料流和使用各種程式語言寫入和讀取結構化的資料。
proto2版本支援在Java、Python、Objective-C和C 中產生程式碼。使用新的proto3語言版本,你還可以使用Kotlin、Dart、Go、Ruby、PHP和C#,還有更多的語言。
怎麼發現的?
在我們的新專案中,我們透過使用 protobuf 格式來儲存專案運行的資料。這樣我們在調試過程中,可能會根據現場錄製的資料進行本地的調試。
message ImageData { // ms int64 timestamp = 1; int32 id = 2; Data mat = 3; } message PointCloud { // ms int64 timestamp = 1; int32 id = 2; PointData pointcloud = 3; } message State { // ms int64 timestamp = 1; string direction = 2; } message Sensor { repeated PointCloud point_data = 1; repeated ImageData image_data = 2; repeated State vehicle_data = 3; }
我們定義了這樣一組數據, 然後儲存的時候,因為Sensor 這3個資料來源的幀率不一樣,因此儲存的時候,單一Sensor 中其實只包含了一組數據,另外兩個類型的資料並沒有包含進去。
當我們只錄製單一 pack 的時候,我們並沒有遇到問題。直到我們覺得單一包,不能長時間錄製,我們需要找一種解決方法來分割包 。
當時覺得這個一定是很簡單的,我們就設定了一個套件達到 500M 的時候,我們就讓後面的資料存到新的套件裡。很順利的寫完,然後放到現場進行資料錄製。錄製一段時間之後,我們把包包拿回來進行模擬測試我們的新程式。發現有些包的資料解析出來是有問題的。程式運行到一半會卡在那裡不動。經過多次測試,發現部分包有這個問題。
我們一開始懷疑的是,判斷檔案大小的方式不對,影響到了分包。因為判斷文件大小的時候,會去開啟文件。但是經過好幾種其他的不打開文件的方式判斷,從而進行分割。還是遇到了部分錄製的包有問題。
這時我才懷疑到 protobuf 對儲存資料會有一些特殊的要求。後來我看了一些文章,了解到 protobuf 儲存多組資料到一個檔案需要有標誌符。要不然後面從檔案解析回來的時候,protobuf 因為不知道單一資料的停止符在哪裡,導致資料解析出錯。
到這裡,這個坑出現了。 我們儲存了一系列的資料到單一套件中,沒有做任何分隔符號的操作。 protobuf在解析的時候,把文件中所有的內容都解析成了單一Sensor。 Sensor 中包含裡所有數據, protobuf 主動合併了所有儲存的資料。
在這時,我才發現以前單包錄製的時候,數據都是對的,那真的是我運氣好。 protobuf恰好解析成功了。
要怎麼解決呢?
既然知道 protobuf 會這麼操作,那我們就只要知道 protobuf 怎麼分割就行了。這個方法還真不好找,因為像我們這樣使用的人太少了。中文搜尋完全搜不到這一塊的內容,可能大家都不會使用protobuf來儲存資料吧,大家使用的方式應該都是多個服務中進行互動的場景吧。
最後透過stackoverflow上的一些回答找到了答案,從回答中得知,這個解決辦法在 protobuf 3.3 的時候,才正式被合併進去。看起來這個功能真的很少用。
bool SerializeDelimitedToOstream(const MessageLite& message, std::ostream* output); bool ParseDelimitedFromZeroCopyStream( MessageLite* message, io::ZeroCopyInputStream* input, bool* clean_eof);
透過這對方法,可以對檔案進行依照資料流一個一個的儲存讀取。再也不用擔心資料被合併讀取。
當然透過這種方式儲存的數據,不能被原來的解析方式所解析,儲存的而進行格式完全變了。這種方式會先儲存二進位資料的大小,再儲存二進位資料。
結束語
經過一番折騰,終於搞定了這個分割的坑。使用場景可能比較小眾,導致了許多資料根本找不到。靠自己看原始碼才發現這些問題。 C 的原始碼真不好讀,有很多的模板方法、模板類別容易錯過一些細節。最後還是看的C#的程式碼,才完全確認的。
以上是原話重寫:一個意外的發現是,原本被視為 bug 的問題其實是 Protobuf 設計中的一個特性的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

熱門話題

一、引言隨著行動裝置的普及和運算能力的提升,影像分割技術成為了研究的熱點。 MobileSAM(MobileSegmentAnythingModel)是一種針對行動裝置最佳化的影像分割模型,旨在保持高品質分割結果的同時,降低計算複雜度和記憶體佔用,以便在資源有限的行動裝置上高效運行。本文將詳細介紹MobileSAM的原理、優點和應用場景。二、MobileSAM模式的設計想法MobileSAM模式的設計想法主要包括以下幾個面向:輕量級模式:為了適應行動裝置的資源限制,MobileSAM模式採用了輕量級

隨著人工智慧技術的不斷發展,影像語意分割技術已成為影像分析領域的熱門研究方向。在影像語意分割中,我們將一張影像中的不同區域進行分割,並對每個區域進行分類,從而達到對這張影像的全面理解。 Python是一種著名的程式語言,其強大的資料分析和資料視覺化能力使其成為了人工智慧技術研究領域的首選。本文將介紹如何在Python中使用影像語意分割技術。一、前置知識在深入

有時候,我們需要把一個大文件發送給別人,但是限於傳輸通道的限制,比如郵箱附件大小的限制,或者網絡狀況不太好,需要將大文件分割成小文件,分多次發送,接收端再對這些小文件進行合併。今天就來分享一下用Python分割合併大檔案的方法。思路及實作如果是文字文件,可以依行數分割。無論是文字文件還是二進位文件,都可以依指定大小進行分割。使用Python的文件讀寫功能就可以實現文件的分割與合併,設定每個文件的大小,然後讀取指定大小的位元組就寫入一個新文件,接收端依序讀取小文件,把讀取到的位元組依序寫入一個文件,就

Golang與FFmpeg:如何實現音訊合成和分割,需要具體程式碼範例摘要:本文將介紹如何使用Golang和FFmpeg函式庫來實現音訊合成和分割。我們將用到一些具體的程式碼範例來幫助讀者更好地理解。引言:隨著音訊處理技術的不斷發展,音訊合成和分割已成為日常生活和工作中常見的功能需求。而Golang作為一種快速,高效且易於編寫和維護的程式語言,加上FFmpeg作

許多的小夥伴都需要錄影畫面進行辦公室或傳輸文件,但是有時候會出現文件過大的問題製造了很多麻煩,下面就給大家帶來了文件過大的解決方法,一起看看吧。 win10錄影檔太大怎麼辦:1.下載軟體格式工廠來進行壓縮檔。下載位址>>2、進入主頁面,點選「影片-MP4」選項。 3、在轉換格式頁面中點選“新增檔案”,選擇要壓縮的MP4檔案。 4、點擊頁面“輸出配置”,透過輸出品質來壓縮檔案。 5、下拉配置清單選擇「低品質和大小」點選「確定」。 6、點選「確定」完成影片檔案的導入。 7.點選「開始」進行轉換。 8.完成後即可

大家好,我是了不起。最近我們在專案中,透過使用protobuf格式作為儲存資料的一個載體。一個不小心就給自己埋了個大坑,還是過了好久才發現。 protobuf簡介protobuf全名為Protocalbuffers.它是由Google研發的,一種可跨語言、可跨平台、可擴展的序列化資料的機制。類似於XML,但它更小、更快、更簡單。你只需要定義一次你希望的資料如何被結構化,然後你可以使用它的產生工具,產生包含一些序列化和反序列化等操作的原始碼。可以輕鬆地從各種資料流和使用各種程式語言寫入

在PHP開發中,字串常常需要分割成若干個子字串,以便我們在處理資料時更加方便。此時,PHP提供了explode()函數來幫助我們達成這個目的。 explode()函數的基本語法為:explode(string$delimiter,string$string[,int$limit=PHP_MAXPATHLEN])其中,$delimiter

近期,浙江大學ReLER實驗室將SAM與分割視訊進行深度結合,發布Segment-and-TrackAnything(SAM-Track)。 SAM-Track賦予了SAM對視訊目標進行追蹤的能力,並支援多種方式(點、畫筆、文字)進行互動。在此基礎上,SAM-Track統一了多個傳統視訊分割任務,達成了一鍵分割追蹤任意視訊中的任意目標,將傳統視訊分割外推至通用視訊分割。 SAM-Track具有卓越的效能,在複雜場景下僅需單卡就能高品質穩定追蹤數百個目標。專案網址:https://github.co
