欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JavaScript?讀取及寫入本地文件的操作方法

 更新時(shí)間:2025年03月04日 15:18:33   作者:隨筆寫  
文章介紹了在純前端JavaScript中如何讀取和寫入本地文件,瀏覽器環(huán)境限制了直接訪問(wèn)文件系統(tǒng),但提供了文件上傳和下載功能,對(duì)于文件讀取,可以使用FileReader?API,支持分片讀取和流式處理,感興趣的朋友一起看看吧

概述

在純前端 javaScript 中,瀏覽器環(huán)境壓根沒(méi)有直接提供操作文件系統(tǒng)的能力。它不能像 node.js 那樣使用 fs 模塊來(lái)刪除或者創(chuàng)建文件。 針對(duì)于瀏覽器出于安全性的考慮,不允許網(wǎng)頁(yè)隨意訪問(wèn)用戶的文件系統(tǒng),以防止?jié)撛诘膼阂庑袨椤?/p>

瀏覽器確實(shí)提供了一些有限的文件操作能力,主要是通過(guò)以下幾種方式:

文件上傳和下載:
文件上傳: 可以通過(guò) <input type=“file”> 元素讓用戶選擇文件,然后通過(guò) JavaScript 讀取文件內(nèi)容。
文件下載: 可以通過(guò)創(chuàng)建 Blob 對(duì)象和使用 a 標(biāo)簽的 download 屬性來(lái)觸發(fā)文件下載。

File API

File System Access API
File System Access API 是現(xiàn)代瀏覽器(主要是在 Chromium 內(nèi)核的瀏覽器)引入的一種新 API,它允許網(wǎng)頁(yè)直接與用戶的文件系統(tǒng)交互,創(chuàng)建、讀取、寫入和刪除文件。這是當(dāng)前瀏覽器提供的最接近文件系統(tǒng)操作的能力。

一:讀文件

(一)最簡(jiǎn)單方式

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>讀文件</title>
</head>
<body>
<input type="file" id="fileInput">
<button id="processButton">Process and Download</button>
<script>
    document.getElementById('processButton').addEventListener('click', function () {
        const fileInput = document.getElementById('fileInput');
        const file = fileInput.files[0];
        if (file) {
            const reader = new FileReader();
            reader.onload = function (e) {
                // 讀取文件內(nèi)容
                let content = e.target.result;
                console.log(content);
            };
            // 開始讀取文件
            reader.readAsText(file);
        } else {
            alert('Please select a file first!');
        }
    });
</script>
</body>
</html>

HTML 部分:

  • 創(chuàng)建了一個(gè)文件輸入框 (<input type=“file”>) 讓用戶選擇文件。

JavaScript 部分:

  • 創(chuàng)建了一個(gè) FileReader 對(duì)象來(lái)讀取選中的文件。
  • 使用reader.onload 指定成功讀取文件時(shí)要做什么。
  • 使用 reader.readAsText(file)開始以文本形式讀取文件。

(二)讀取大文件

在上面的代碼中,文件的讀取是通過(guò) FileReaderreadAsText() 方法完成的。這個(gè)方法確實(shí)會(huì)一次性將整個(gè)文件內(nèi)容加載到內(nèi)存中。對(duì)于小型文件來(lái)說(shuō)這沒(méi)有問(wèn)題,但如果文件非常大,可能會(huì)導(dǎo)致內(nèi)存占用過(guò)高,影響性能,甚至導(dǎo)致頁(yè)面崩潰。

1,分片讀取

使用 FileReaderreadAsArrayBuffer() 方法,然后使用 Blobslice() 方法來(lái)分塊讀取文件。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>讀文件</title>
</head>
<body>
<input type="file" id="fileInput">
<button id="processButton">Process</button>
<script>
    document.getElementById('processButton').addEventListener('click', function () {
        const fileInput = document.getElementById('fileInput');
        const file = fileInput.files[0];
        if (file) {
            const CHUNK_SIZE = 1024 * 1024; // 1MB 分塊大小
            let offset = 0;
            // 遞歸讀取文件的函數(shù)
            function readNextChunk() {
                // 檢查是否已經(jīng)讀取到文件末尾
                if (offset >= file.size) {
                    console.log("File processing complete.");
                    return;
                }
                // 讀取當(dāng)前塊
                const chunk = file.slice(offset, offset + CHUNK_SIZE);
                const reader = new FileReader();
                reader.onload = function (e) {
                    // 處理當(dāng)前塊的數(shù)據(jù)
                    let content = e.target.result;
                    console.log(`Processing chunk from ${offset} to ${offset + CHUNK_SIZE}`);
                    console.log(content); // 此處可以進(jìn)行更復(fù)雜的處理
                    // 更新偏移量,并讀取下一塊
                    offset += CHUNK_SIZE;
                    readNextChunk();
                };
                reader.onerror = function (e) {
                    console.error("Error reading file chunk:", e);
                };
                // 開始讀取當(dāng)前塊
                reader.readAsText(chunk);
            }
            // 開始讀取第一個(gè)塊
            readNextChunk();
        } else {
            alert('Please select a file first!');
        }
    });
</script>
</body>
</html>

由于文件讀取是異步操作,遞歸調(diào)用 readNextChunk() 在每塊數(shù)據(jù)處理完成后繼續(xù)下一塊處理。

2,使用 stream

使用 File API 的 stream() 方法(在較新的瀏覽器中支持),這允許你以流的方式讀取文件。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Stream Read File</title>
</head>
<body>
<input type="file" id="fileInput">
<button id="processButton">Process File Stream</button>
<script>
    document.getElementById('processButton').addEventListener('click', async function () {
        const fileInput = document.getElementById('fileInput');
        const file = fileInput.files[0];
        if (file) {
            const stream = file.stream();
            const reader = stream.getReader();
            // 讀取流數(shù)據(jù)
            async function read() {
                let result;
                while (!(result = await reader.read()).done) {
                    const chunk = result.value; // Uint8Array
                    const textChunk = new TextDecoder().decode(chunk); // 轉(zhuǎn)換為文本
                    console.log(textChunk); // 處理數(shù)據(jù)塊
                }
                console.log("File processing complete.");
            }
            // 開始讀取
            read().catch(error => console.error("Stream read error:", error));
        } else {
            alert('Please select a file first!');
        }
    });
</script>
</body>
</html>
  • file.stream(): 這是 File 對(duì)象的新方法,返回一個(gè) ReadableStream,用于讀取文件內(nèi)容。
  • stream.getReader(): 通過(guò)調(diào)用 stream.getReader() 獲取流的讀取器,返回ReadableStreamDefaultReader 對(duì)象。
  • reader.read(): 每次調(diào)用 reader .read() 方法,讀取流中的一個(gè)塊數(shù)據(jù),返回一個(gè) Promise,該 Promise 解析為一個(gè)對(duì)象,包含 donevalue 屬性。

   done: 如果為 true,表示流已讀取完畢。 
   value: 當(dāng)前讀取的數(shù)據(jù)塊,以 Uint8Array 的形式返回。

  • TextDecoder: 用于將 Uint8Array 數(shù)據(jù)塊轉(zhuǎn)換為可讀的文本。對(duì)于非文本數(shù)據(jù),可以根據(jù)需要進(jìn)行其他處理。
  • while 循環(huán): 通過(guò) while 循環(huán)不斷讀取文件流,直到流結(jié)束。
  • 通過(guò) async/awaitPromises 實(shí)現(xiàn)簡(jiǎn)潔的異步文件讀取邏輯。

(三)注意

1,安全性問(wèn)題

問(wèn)題: 瀏覽器出于安全考慮,限制了對(duì)用戶文件系統(tǒng)的直接訪問(wèn),以防止惡意腳本未經(jīng)用戶同意訪問(wèn)敏感文件或數(shù)據(jù)。前端代碼只能通過(guò)用戶明確選擇的方式訪問(wèn)文件,比如通過(guò) <input type="file">File System Access API。

處理方法:

用戶明確選擇: 必須通過(guò)文件選擇對(duì)話框(如 <input type="file">)讓用戶主動(dòng)選擇文件,而不是讓腳本直接訪問(wèn)。

<input type="file" id="fileInput">

文件處理的權(quán)限: 使用 File System Access API(如 showOpenFilePicker())時(shí),瀏覽器會(huì)明確向用戶請(qǐng)求權(quán)限。確保只在必要時(shí)請(qǐng)求最少的權(quán)限。

async function selectFile() {
  const [fileHandle] = await window.showOpenFilePicker();
  const file = await fileHandle.getFile();
  console.log(file.name);
}

保持權(quán)限范圍最小化: 只請(qǐng)求需要的文件或目錄,不嘗試訪問(wèn)整個(gè)文件系統(tǒng)。限制操作的范圍,例如只允許讀取,避免寫入或刪除操作。 2,隱私問(wèn)題

問(wèn)題: 用戶文件可能包含敏感信息,如個(gè)人數(shù)據(jù)、財(cái)務(wù)信息等。前端讀取文件時(shí),必須確保用戶的隱私不被泄露或?yàn)E用。

處理方法:

  • 透明度: 明確告知用戶文件將被讀取的內(nèi)容和目的,避免在用戶不知情的情況下讀取數(shù)據(jù)。
  • 本地處理: 盡量在本地處理文件內(nèi)容,避免將數(shù)據(jù)上傳到服務(wù)器或發(fā)送到第三方服務(wù),除非獲得用戶明確同意。
const reader = new FileReader();
reader.onload = function(e) {
  const content = e.target.result;
  // 只在本地處理數(shù)據(jù)
};
reader.readAsText(file);

數(shù)據(jù)清理: 如果需要將文件內(nèi)容傳輸?shù)椒?wù)器,確保對(duì)敏感數(shù)據(jù)進(jìn)行加密,并在處理完畢后清理不再需要的數(shù)據(jù)。

3,性能問(wèn)題

題: 在前端處理大文件時(shí),可能會(huì)導(dǎo)致瀏覽器內(nèi)存占用過(guò)高或卡頓,影響用戶體驗(yàn)。

處理方法:

分塊處理: 對(duì)于大文件,使用 File APIslice() 方法或 stream() 方法將文件分塊讀取,逐步處理文件內(nèi)容,避免一次性將整個(gè)文件加載到內(nèi)存中。

const CHUNK_SIZE = 1024 * 1024; // 1MB
let offset = 0;
function readChunk(file) {
  const chunk = file.slice(offset, offset + CHUNK_SIZE);
  const reader = new FileReader();
  reader.onload = function(e) {
    const content = e.target.result;
    console.log(content); // 處理數(shù)據(jù)塊
    offset += CHUNK_SIZE;
    if (offset < file.size) {
      readChunk(file); // 繼續(xù)讀取下一塊
    }
  };
  reader.readAsText(chunk);
}

異步操作: 使用 async/awaitPromises 處理文件讀取,以避免阻塞主線程,確保頁(yè)面保持響應(yīng)性。

4,兼容性問(wèn)題

并非所有瀏覽器都支持最新的 File System Access API 或某些高級(jí)文件處理功能。需要確保代碼在多個(gè)瀏覽器中都能正常工作,或者提供合理的回退機(jī)制。

問(wèn)題: 并非所有瀏覽器都支持最新的 File System Access API 或某些高級(jí)文件處理功能。需要確保代碼在多個(gè)瀏覽器中都能正常工作,或者提供合理的回退機(jī)制。

處理方法:

Feature Detection: 在使用某些文件 API 之前,檢查瀏覽器是否支持該功能。使用 if 語(yǔ)句檢查是否存在特定 API。

if (window.showOpenFilePicker) {
  // 使用 File System Access API
} else {
  // 回退到 <input type="file">
}

5,用戶體驗(yàn)問(wèn)題

問(wèn)題: 前端文件操作通常涉及用戶選擇文件、上傳文件、下載文件等操作,良好的用戶體驗(yàn)可以提升用戶的滿意度。

處理方法:

進(jìn)度指示: 在處理大文件時(shí),顯示進(jìn)度指示器(如進(jìn)度條),讓用戶了解文件處理進(jìn)度,避免用戶感覺(jué)應(yīng)用卡死。

<progress id="progressBar" value="0" max="100"></progress>	
// 在讀取文件塊時(shí)更新進(jìn)度條
progressBar.value = (offset / file.size) * 100;

錯(cuò)誤處理: 提供友好的錯(cuò)誤提示和處理機(jī)制,幫助用戶理解問(wèn)題并采取行動(dòng)(如重新選擇文件)。

reader.onerror = function(e) {
  alert('Error reading file: ' + e.target.error.message);
};

反饋和確認(rèn): 當(dāng)文件操作成功完成時(shí),給用戶反饋,例如提示文件處理完畢,或確認(rèn)下載已完成。

6,權(quán)限管理問(wèn)題

問(wèn)題: 文件操作可能涉及權(quán)限問(wèn)題,例如通過(guò) File System Access API 訪問(wèn)文件系統(tǒng)時(shí),權(quán)限可能會(huì)被撤銷。

處理方法:

權(quán)限檢查: 每次操作前,檢查是否仍有權(quán)限訪問(wèn)文件或目錄。如果權(quán)限被撤銷,提示用戶重新授權(quán)。

const permission = await fileHandle.queryPermission();
if (permission !== 'granted') {
  // 提示用戶重新授權(quán)
}

權(quán)限請(qǐng)求: 如果沒(méi)有權(quán)限,可以使用 requestPermission() 方法主動(dòng)請(qǐng)求權(quán)限。

const permission = await fileHandle.requestPermission();
if (permission === 'granted') {
  // 執(zhí)行文件操作
}

7,文件類型和內(nèi)容驗(yàn)證

問(wèn)題: 用戶可能會(huì)選擇錯(cuò)誤類型的文件,或上傳包含惡意內(nèi)容的文件。

處理方法:

文件類型過(guò)濾: 使用 <input type="file"> 元素的 accept 屬性限制用戶選擇的文件類型。例如,限制只選擇 .txt 文件。

<input type="file" accept=".txt">

內(nèi)容驗(yàn)證: 在處理文件內(nèi)容之前,驗(yàn)證文件的實(shí)際內(nèi)容格式。例如,如果文件是 JSON 格式,可以嘗試解析內(nèi)容并捕獲錯(cuò)誤。

try {
  const data = JSON.parse(fileContent);
} catch (e) {
  alert('Invalid JSON format');
}

8,文件大小限制

問(wèn)題: 處理非常大的文件可能會(huì)導(dǎo)致內(nèi)存溢出或性能問(wèn)題。

處理方法:

限制文件大小: 在前端代碼中設(shè)置文件大小限制,并在用戶選擇文件時(shí)進(jìn)行檢查。如果文件過(guò)大,給出提示。

const MAX_SIZE = 10 * 1024 * 1024; // 10MB
if (file.size > MAX_SIZE) {
  alert('File is too large!');
  return;
}

這里舉個(gè)例子??:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>文件處理</title>
</head>
<body>
<input type="file" id="fileInput" accept=".pdf">
<button id="processButton">Process</button>
<progress id="progressBar" value="0" max="100" style="display: none;"></progress>
<p id="percentage">0%</p>
<p id="statusMessage"></p>
<script>
    document.getElementById('processButton').addEventListener('click', function () {
        const fileInput = document.getElementById('fileInput');
        const file = fileInput.files[0];
        const MAX_SIZE = 300 * 1024 * 1024; // 最大300MB
        const progressBar = document.getElementById('progressBar');
        const percentageDisplay = document.getElementById('percentage');
        const statusMessage = document.getElementById('statusMessage');
        // 重置狀態(tài)
        progressBar.style.display = 'none';
        progressBar.value = 0;
        percentageDisplay.textContent = '0%';
        statusMessage.textContent = '';
        // 檢查是否選擇了文件
        if (!file) {
            alert('Please select a file first!');
            return;
        }
        // 檢查文件大小
        if (file.size > MAX_SIZE) {
            alert('File is too large! Please select a file under 300MB.');
            return;
        }
        console.log(`Selected file: ${file.name}, ${file.size} bytes, ${file.type}`);
        // // 檢查文件類型(假設(shè)只接受文本文件)
        // if (file.type !== "text/plain") {
        //     alert('Invalid file type! Please select a .pdf file.');
        //     return;
        // }
        const CHUNK_SIZE = 1024 * 1024; // 1MB 分塊大小
        let offset = 0;
        // 顯示進(jìn)度條
        progressBar.style.display = 'block';
        // 遞歸讀取文件的函數(shù)
        function readNextChunk() {
            // 檢查是否已經(jīng)讀取到文件末尾
            if (offset >= file.size) {
                statusMessage.textContent = "File processing complete.";
                progressBar.style.display = 'none';
                return;
            }
            // 讀取當(dāng)前塊
            const chunk = file.slice(offset, offset + CHUNK_SIZE);
            const reader = new FileReader();
            reader.onload = function (e) {
                // 處理當(dāng)前塊的數(shù)據(jù)
                let content = e.target.result;
                console.log(`Processing chunk from ${offset} to ${offset + CHUNK_SIZE}`);
                console.log(content); // 此處可以進(jìn)行更復(fù)雜的處理
                // 更新偏移量,并讀取下一塊
                offset += CHUNK_SIZE;
                // 計(jì)算百分比并更新顯示
                const percentage = Math.min((offset / file.size) * 100, 100).toFixed(2);
                progressBar.value = percentage;
                percentageDisplay.textContent = `${percentage}%`;
                readNextChunk();
            };
            reader.onerror = function (e) {
                console.error("Error reading file chunk:", e);
                statusMessage.textContent = "Error reading file!";
                progressBar.style.display = 'none';
            };
            // 開始讀取當(dāng)前塊
            reader.readAsText(chunk);
        }
        // 開始讀取第一個(gè)塊
        readNextChunk();
    });
</script>
</body>
</html>

二,寫文件

在前端代碼中將信息寫入本地文件是一個(gè)常見的需求,但由于瀏覽器的安全限制,這個(gè)過(guò)程并不像在后端那樣直接。我們有幾種方法可以實(shí)現(xiàn)這個(gè)功能,每種方法都有其優(yōu)缺點(diǎn)。

(一)最常用的方法

最常用的方法時(shí)使用 BlobURL.createObjectURL()

function saveToFile(content, filename) {
    const blob = new Blob([content], { type: 'text/plain' });
    const url = URL.createObjectURL(blob);
    const link = document.createElement('a');
    link.href = url;
    link.download = filename;    
    // 這行是必要的,用于在瀏覽器中觸發(fā)下載
    document.body.appendChild(link);    
    link.click();    
    // 清理并移除鏈接
    document.body.removeChild(link);
    URL.revokeObjectURL(url);
}
// 使用示例
saveToFile('Hello, World!', 'example.txt');

優(yōu)點(diǎn):

  • 廣泛支持,適用于大多數(shù)現(xiàn)代瀏覽器。
  • 可以處理大文件。
  • 可以保存各種類型的數(shù)據(jù)(不僅僅是文本)。

缺點(diǎn):

  • 用戶需要選擇保存位置,無(wú)法直接寫入特定位置。
  • 不能追加內(nèi)容到現(xiàn)有文件。

(二)使用 File System Access API

這是一個(gè)較新的API,提供了更強(qiáng)大的文件操作能力,但目前只有部分現(xiàn)代瀏覽器支持。

async function writeToFile(content) {
    if ('showSaveFilePicker' in window) {
        try {
            const handle = await window.showSaveFilePicker({
                types: [{
                    description: 'Text file',
                    accept: { 'text/plain': ['.txt'] },
                }],
            });
            const writable = await handle.createWritable();
            await writable.write(content);
            await writable.close();
            console.log('File saved successfully');
        } catch (err) {
            console.error('Error saving file:', err);
        }
    } else {
        console.error('File System Access API not supported');
    }
}
// 使用示例
writeToFile('Hello, World!');

優(yōu)點(diǎn):

  • 提供更強(qiáng)大的文件操作能力,包括讀取、寫入和修改文件。
  • 可以訪問(wèn)用戶選擇的文件或目錄。
  • 支持大文件和流式操作。

缺點(diǎn):

  • 瀏覽器支持有限,主要是新版Chrome和Edge。
  • 需要用戶明確授予權(quán)限。

(三)使用 LocalStorage 或 IndexedDB

這些方法不是直接將數(shù)據(jù)保存為文件,而是將數(shù)據(jù)存儲(chǔ)在瀏覽器的本地存儲(chǔ)中。

對(duì)于 LocalStorage:

function saveToLocalStorage(key, value) {
    localStorage.setItem(key, value);
}
// 使用示例
saveToLocalStorage('myData', 'Hello, World!');

對(duì)于 IndexedDB,代碼會(huì)相對(duì)復(fù)雜一些,這里是一個(gè)簡(jiǎn)化的例子:

let db;
const dbName = "MyDatabase";
const request = indexedDB.open(dbName, 1);
request.onerror = function(event) {
    console.error("Database error: " + event.target.error);
};
request.onsuccess = function(event) {
    db = event.target.result;
    console.log("Database opened successfully");
};
request.onupgradeneeded = function(event) {
    db = event.target.result;
    const objectStore = db.createObjectStore("files", { keyPath: "id" });
};
function saveToIndexedDB(id, content) {
    const transaction = db.transaction(["files"], "readwrite");
    const objectStore = transaction.objectStore("files");
    const request = objectStore.put({ id: id, content: content });  
    request.onerror = function(event) {
        console.error("Error saving data: " + event.target.error);
    };    
    request.onsuccess = function(event) {
        console.log("Data saved successfully");
    };
}
// 使用示例(需要在數(shù)據(jù)庫(kù)打開后調(diào)用)
saveToIndexedDB('file1', 'Hello, World!');

優(yōu)點(diǎn):

  • 不需要用戶交互就能保存數(shù)據(jù)。
  • 數(shù)據(jù)持久化存儲(chǔ)在瀏覽器中。
  • 適用于存儲(chǔ)應(yīng)用程序狀態(tài)或小型數(shù)據(jù)集。

缺點(diǎn):

  • 存儲(chǔ)容量有限(LocalStorage通常限制為5MB左右)。
  • 數(shù)據(jù)只存儲(chǔ)在瀏覽器中,不是真正的文件。
  • 用戶清除瀏覽器數(shù)據(jù)時(shí)會(huì)丟失。

一個(gè)完整的示例??:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>文件保存示例</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            max-width: 800px;
            margin: 0 auto;
            padding: 20px;
        }
        textarea {
            width: 100%;
            height: 100px;
            margin-bottom: 10px;
        }
        button {
            margin-right: 10px;
            margin-bottom: 10px;
        }
    </style>
</head>
<body>
<h1>文件保存示例</h1>
<textarea id="content" placeholder="在此輸入要保存的內(nèi)容"></textarea>
<div>
    <button onclick="saveUsingBlob()">使用Blob下載</button>
    <button onclick="saveUsingFileSystem()">使用File System API保存</button>
    <button onclick="saveToLocalStorage()">保存到LocalStorage</button>
    <button onclick="saveToIndexedDB()">保存到IndexedDB</button>
</div>
<div id="status"></div>
<script>
    // 使用Blob和URL.createObjectURL()方法
    function saveUsingBlob() {
        const content = document.getElementById('content').value;
        const blob = new Blob([content], {type: 'text/plain'});
        const url = URL.createObjectURL(blob);
        const link = document.createElement('a');
        link.href = url;
        link.download = 'example.txt';
        document.body.appendChild(link);
        link.click();
        document.body.removeChild(link);
        URL.revokeObjectURL(url);
        updateStatus('文件已準(zhǔn)備下載');
    }
    // 使用File System Access API
    async function saveUsingFileSystem() {
        const content = document.getElementById('content').value;
        if ('showSaveFilePicker' in window) {
            try {
                const handle = await window.showSaveFilePicker({
                    types: [{
                        description: 'Text file',
                        accept: {'text/plain': ['.txt']},
                    }],
                });
                const writable = await handle.createWritable();
                await writable.write(content);
                await writable.close();
                updateStatus('文件保存成功');
            } catch (err) {
                updateStatus('保存文件時(shí)出錯(cuò): ' + err);
            }
        } else {
            updateStatus('此瀏覽器不支持File System Access API');
        }
    }
    // 使用LocalStorage
    function saveToLocalStorage() {
        const content = document.getElementById('content').value;
        try {
            localStorage.setItem('savedContent', content);
            updateStatus('內(nèi)容已保存到LocalStorage');
        } catch (err) {
            updateStatus('保存到LocalStorage時(shí)出錯(cuò): ' + err);
        }
    }
    // 使用IndexedDB
    let db;
    const dbName = "MyDatabase";
    const dbVersion = 1;
    const request = indexedDB.open(dbName, dbVersion);    request.onerror = function (event) {
        updateStatus("打開數(shù)據(jù)庫(kù)時(shí)出錯(cuò): " + event.target.error);
    };
    request.onsuccess = function (event) {
        db = event.target.result;
        updateStatus("數(shù)據(jù)庫(kù)已成功打開");
    };
    request.onupgradeneeded = function (event) {
        db = event.target.result;
        const objectStore = db.createObjectStore("files", {keyPath: "id"});
        updateStatus("數(shù)據(jù)庫(kù)已創(chuàng)建");
    };
    function saveToIndexedDB() {
        const content = document.getElementById('content').value;
        if (!db) {
            updateStatus("數(shù)據(jù)庫(kù)未準(zhǔn)備好");
            return;
        }
        const transaction = db.transaction(["files"], "readwrite");
        const objectStore = transaction.objectStore("files");
        const request = objectStore.put({id: "file1", content: content});
        request.onerror = function (event) {
            updateStatus("保存到IndexedDB時(shí)出錯(cuò): " + event.target.error);
        };
        request.onsuccess = function (event) {
            updateStatus("內(nèi)容已成功保存到IndexedDB");
        };
    }
    function updateStatus(message) {
        document.getElementById('status').textContent = message;
    }
</script>
</body>
</html>

本人也是記錄一下,方便以后用到。附上原文地址,尊重原創(chuàng)!

到此這篇關(guān)于JavaScript 讀取及寫入本地文件的文章就介紹到這了,更多相關(guān)JavaScript 讀取及寫入本地文件內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • uniapp中使用vuex并持久化的方法示例

    uniapp中使用vuex并持久化的方法示例

    vuex是基于vuex.js的狀態(tài)管理工具,可以把它理解為一個(gè)倉(cāng)庫(kù),下面這篇文章主要給大家介紹了關(guān)于uniapp中如何使用vuex并持久化的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-06-06
  • JavaScript實(shí)現(xiàn)網(wǎng)頁(yè)版五子棋游戲

    JavaScript實(shí)現(xiàn)網(wǎng)頁(yè)版五子棋游戲

    這篇文章主要為大家詳細(xì)介紹了JavaScript實(shí)現(xiàn)網(wǎng)頁(yè)版五子棋游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-07-07
  • 微信小程序常用賦值方法小結(jié)

    微信小程序常用賦值方法小結(jié)

    這篇文章主要介紹了微信小程序常用賦值方法,結(jié)合實(shí)例形式總結(jié)了微信小程序局部變量、全局變量及data對(duì)象屬性賦值相關(guān)操作技巧,需要的朋友可以參考下
    2019-04-04
  • js獲取頁(yè)面?zhèn)鱽?lái)參數(shù)的方法

    js獲取頁(yè)面?zhèn)鱽?lái)參數(shù)的方法

    這篇文章主要介紹了通過(guò)window.location.search來(lái)獲取頁(yè)面?zhèn)鱽?lái)的參數(shù),經(jīng)測(cè)試是OK的
    2014-09-09
  • js 顯示日期時(shí)間的實(shí)例(時(shí)間過(guò)一秒加1)

    js 顯示日期時(shí)間的實(shí)例(時(shí)間過(guò)一秒加1)

    下面小編就為大家?guī)?lái)一篇js 顯示日期時(shí)間的實(shí)例(時(shí)間過(guò)一秒加1)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-10-10
  • 分析uniapp如何動(dòng)態(tài)獲取接口域名

    分析uniapp如何動(dòng)態(tài)獲取接口域名

    本文主要介紹了uniapp如何動(dòng)態(tài)獲取接口域名,感興趣的同學(xué),可以參考下,并且試驗(yàn)一下。
    2021-06-06
  • JavaScript的parseInt 取整使用

    JavaScript的parseInt 取整使用

    JavaScript 是弱類型語(yǔ)言, 為了保證數(shù)值的有效性, 在處理數(shù)值的時(shí)候, 我們可以對(duì)數(shù)值字符串進(jìn)行強(qiáng)行轉(zhuǎn)換. 如 parseInt 取整和 parseFloat 取浮點(diǎn)數(shù)
    2011-05-05
  • asp.net HttpHandler實(shí)現(xiàn)圖片防盜鏈

    asp.net HttpHandler實(shí)現(xiàn)圖片防盜鏈

    這個(gè)例子來(lái)自于《Maximizing ASP.NET Real World, Object-Oriented Development》一書, 需要的朋友可以參考下。
    2009-11-11
  • 不同Jquery版本引發(fā)的問(wèn)題解決

    不同Jquery版本引發(fā)的問(wèn)題解決

    用JS實(shí)現(xiàn)了一個(gè)拖拽排序,可因Jquery版本不同導(dǎo)致瀏覽器訪問(wèn)時(shí)存在很多的問(wèn)題,下面為大家介紹下具體的解決方法,感興趣的朋友可以參考下
    2013-10-10
  • 使用JavaScriptCore實(shí)現(xiàn)OC和JS交互詳解

    使用JavaScriptCore實(shí)現(xiàn)OC和JS交互詳解

    JavaScriptCore是webkit的一個(gè)重要組成部分,主要是對(duì)JS進(jìn)行解析和提供執(zhí)行環(huán)境。下面這篇文章主要給大家介紹了使用JavaScriptCore實(shí)現(xiàn)OC和JS交互的相關(guān)資料,文中介紹的非常詳細(xì),需要的朋友可以參考學(xué)習(xí),下面來(lái)一起看看吧。
    2017-03-03

最新評(píng)論