這是一個我似乎無法在 Node.js 檔案上找到答案的話題(我知道這是可能的,因為 exif 之類的庫),我也無法在互聯網上找到答案,除非每個人都說只使用一個庫。
我不想使用庫,所以我想在本地執行此操作并了解有關讀取檔案元資料的更多資訊,并可能最終在構建我自己的迷你工具時更新元資料。
如果我運行類似的東西,fs.statSync()我可以獲得在 Stats 物件中回傳的通用元資料;但是,就我而言,我正在尋找所有其他元資料,而不僅僅是基本檔案資訊,如size,birthtime等。
我想要其他元資料,例如dimensions, date taken,尤其是您在影像、視頻或音頻檔案中看到的內容。
也許有類似的東西:
const deepMetaData = fs.readFileSync().getMetaDataAsString();
console.info(/Date Taken/.test(deepMetaData)); // true
或者
const deepMetaData = fs.createReadStream().buffer().toString();
const dateTaken = deepMetaData.match(/Date Taken: (\d{4}-\d{2}-\d{2})/)[1];
console.info(dateTaken);
如果我需要使用緩沖區、流等,而不是字串輸出,那也很酷。理想情況下是同步的。因此,如果有人可以提供一個簡單的示例,說明如何在沒有庫的情況下讀取這種元資料,我至少可以從中查找使用的方法,以便以后了解更多,并利用與任何方法相關的檔案。謝謝!
uj5u.com熱心網友回復:
Nodejs fs 函式,例如fs.statSync()僅在檔案上提供作業系統級別的元資料(例如 createDate、modificationDate、檔案大小等)。這些是檔案系統中檔案的屬性。這些與檔案本身的實際資料沒有任何關系。
當您談論 EXIF(用于照片)時,這是從檔案資料本身決議的。要了解該型別的資料,您必須至少讀取和決議檔案的開頭,并且您必須能夠識別和理解您可能遇到的所有不同檔案格式。對于照片,這將包括 JPEG、PNG、HEIC、GIF 等……每一種都有不同的檔案格式,并且需要唯一的代碼來理解嵌入在檔案中的元資料。
Nodejs 不支持任何內置的。
因此,它將為每種檔案型別采用自定義代碼。如果您還想包含其他型別的檔案,例如視頻,您需要擴展您可以閱讀、決議和理解的不同檔案型別的串列。對于您正在談論的檔案的深度,這是一項艱巨的作業,特別是在針對野外存在的所有不同檔案和元資料變體進行測驗時。
我個人可以為一種特定的檔案型別(如 JPEG)實作我自己的代碼,但如果我的任務是支持數十種型別的檔案,特別是如果我的任務是支持廣泛的視頻檔案格式,我會立即尋找來自現有庫的幫助,這些庫已經完成了所有耗時的作業來研究、撰寫和測驗如何正確閱讀和理解所有變體。
我知道這是可能的,因為像 exif 這樣的庫
這是一個庫的示例,它讀取影像檔案的開頭,根據預期的格式對其進行決議,并知道如何解釋 EXIF 標頭中所有可能的標簽以及它們的含義。
因此,如果有一個簡單的例子,有人可以提供如何在沒有庫的情況下讀取這種元資料
去研究 EXIF 庫的代碼,看看它是如何作業的。如果您要自己實作它,那就是您必須這樣做的方式。我仍然不確定如果它們已經存在,你為什么要避免使用作業庫。這是 nodejs 生態系統的最大優勢之一 - 您可以構建所有已經存在的開源代碼,而無需自己從頭開始重新實作,并將您的編碼時間花在其他人尚未實作的部分問題上。
如何使用節點讀取該元資料?
您實際上必須從檔案中讀取資料(通常在檔案的開頭)。您可以使用該fs模塊提供的任何機制。例如,您可以使用fs.createReadStream()然后在檔案中流式傳輸,在資料到達時對其進行決議和解釋,然后在超過元資料末尾時停止流式傳輸。當然,您可以使用打開檔案句柄fs.open()并使用它fs.read()來讀取檔案的塊,直到您已讀取到足以擁有所有元資料為止。
您面前有一個示例代碼,它在您似乎已經知道的 NPM 上的 EXIF 庫中執行此操作。去檢查它的代碼。代碼就在那里。
我只是在尋找有關獲取該資訊的簡單答案,即使它是一串字串。
這也許是你的主要問題。獲取該資訊沒有簡單的答案,它不只是作為字串存在。這些檔案有時是二進制檔案(出于空間效率的原因)。您必須學習如何讀取和決議二進制資料。去研究EXIF 庫中的代碼,看看它已經在做什么,你可以從中學習。沒有比這更好的例子了。
但是,對于使用 heic 檔案型別的簡單示例,這將獲取檔案元資料的前 5000 個字符,然后可以對其進行搜索:
const fileDescriptor = fs.openSync(absPathToHeicPhoto);
const charCount = 5000;
const buffer = Buffer.alloc(charCount);
const headerBytes = fs.readSync(fileDescriptor, buffer, 0, charCount);
const bufferAsStr = buffer.toString('utf8', 0, charCount);
console.info(/\d{4}:\d{2}:\d{2}/.test(bufferAsStr));
僅供參考,我在 NPM 上查看了這個 EXIF 庫的代碼,它的實作很差。它用于fs.readFile()將整個影像加載到 RAM 中(即使它只需要檔案開頭的一小部分資料)。由于這個原因(記憶體和磁盤效率低下),這是一個糟糕的實作。
但是,它確實有一個名為processImage的方法和一個名為extractExifData的方法,它們處理檔案的二進制資料以決議出 EXIF 資訊。這些是指向其實際代碼的鏈接。你可以在那里開始學習。
僅供參考,作為一名攝影師,我使用一個名為exiftool的命令列程式,它將 exif 資訊轉儲到標準輸出或許多影像的檔案中。作為一種不同的方法,您可以從您的 nodejs 程式中運行該工具(使用 child_process 模塊并捕獲其輸出并使用該輸出,讓它完成您對生成的輸出進行操作的繁重作業。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/524399.html
