在開發過程中,我們經常需要將大量數據導出為 JSON 文件,尤其是在處理長列表或大數據集時。然而,直接將所有數據寫入一個文件可能會導致性能問題,尤其是在移動設備上。為了優化性能并提高用戶體驗,我們可以將數據分段導出到多個文件中。
實現思路
-
分段處理數據:將長 JSON 數據分段,每段包含固定數量的數據。
-
使用
plus.io
寫入文件:利用 uni-app 的plus.io
API,將每段數據寫入單獨的文件。 -
提示用戶導出成功:在導出完成后,提示用戶文件保存路徑。
代碼實現
1. 定義導出方法
在組件中定義一個方法 handleExport
,用于分段導出數據。
const handleExport = (annoList) => {console.log("開始分段導出數據");isLoadingPage.value = true;loadingPageText.value = "導出中...";const chunkSize = 10; // 每組10個數據const totalChunks = Math.ceil(annoList.length / chunkSize); // 總組數// 使用 plus.io 寫入文件plus.io.requestFileSystem(plus.io.PUBLIC_DOWNLOADS, (fs) => {fs.root.getDirectory("文件_exports", { create: true }, (dirEntry) => {// 創建一個目錄用于存儲所有 JSON 文件let currentChunk = 0;const writeChunk = () => {if (currentChunk >= totalChunks) {isLoadingPage.value = false;uni.showToast({title: `導出成功,路徑:${dirEntry.fullPath}`,icon: "none",});return;}const start = currentChunk * chunkSize;const end = start + chunkSize;const chunkData = annoList.slice(start, end); // 獲取當前分段數據const jsonString = JSON.stringify(chunkData, null, 2); // 格式化為 JSON 字符串const fileName = `data_chunk_${currentChunk + 1}.json`; // 文件名:data_chunk_1.json, data_chunk_2.json, ...dirEntry.getFile(fileName, { create: true }, (fileEntry) => {fileEntry.createWriter((writer) => {writer.onwrite = () => {console.log(`文件 ${fileName} 導出成功`);currentChunk++;writeChunk(); // 寫入下一個分段};writer.write(jsonString); // 寫入當前分段數據});});};writeChunk(); // 開始寫入});});
};
2. 調用導出方法
調用 handleExport
方法,例如在按鈕點擊事件中觸發。
3. 清空文件
定義一個清空文件夾的方法。
const clearDirectory = async (dirName) => {try {// 獲取文件系統plus.io.requestFileSystem(plus.io.PUBLIC_DOWNLOADS,(fs) => {// 獲取目標文件夾fs.root.getDirectory(dirName,{ create: false },(dirEntry) => {console.log(`目錄 ${dirName} 已獲取成功`);// 創建目錄閱讀器const reader = dirEntry.createReader();// 讀取目錄中的所有條目reader.readEntries((entries) => {// 遞歸刪除所有條目const deleteEntry = (entry) => {if (entry.isFile) {entry.remove(() => {console.log(`文件 ${entry.name} 已刪除`);},(error) => {console.error(`刪除文件 ${entry.name} 時出錯:`, error);});} else if (entry.isDirectory) {entry.removeRecursively(() => {console.log(`目錄 ${entry.name} 已刪除`);},(error) => {console.error(`刪除目錄 ${entry.name} 時出錯:`, error);});}};// 遍歷并刪除所有條目entries.forEach(deleteEntry);// 檢查是否所有條目都已刪除const checkDirectory = () => {reader.readEntries((remainingEntries) => {if (remainingEntries.length === 0) {console.log(`目錄 ${dirName} 已清空`);} else {remainingEntries.forEach(deleteEntry);checkDirectory(); // 遞歸檢查}});};checkDirectory(); // 開始檢查},(error) => {console.error(`讀取目錄 ${dirName} 時出錯:`, error);});},(error) => {console.error(`獲取目錄 ${dirName} 時出錯:`, error);});},(error) => {console.error(`請求文件系統時出錯:`, error);});} catch (error) {console.error(`清空目錄時出錯:`, error);}
};
4. 調用清空方法
調用 handleExport
方法,例如在按鈕點擊事件中觸發。
clearDirectory("文件_exports");
注意事項
-
文件權限:確保應用已申請文件讀寫權限,否則可能會導致文件寫入失敗。
-
文件路徑:文件將保存到設備的公共下載目錄下的
文件_exports
文件夾中,用戶可以通過文件管理器訪問。 -
性能優化:分段寫入文件可以避免因數據量過大導致的性能問題,同時提高用戶體驗。
總結
通過上述方法,可以將長 JSON 數據分段導出到多個文件中,避免單個文件過大導致的性能問題。這種方法特別適用于處理大量數據,同時確保應用的性能和用戶體驗。