」工欲善其事,必先利其器。「—孔子《論語.錄靈公》
首頁 > 程式設計 > 在瀏覽器中進行文件操作

在瀏覽器中進行文件操作

發佈於2024-11-02
瀏覽:932

在浏览器中进行文件操作

在開發WebApp 時可能會遇到文件相關的操作,例如上傳文件到伺服器、下載文件到本地、快取文件等,下面會介紹幾種不同的方式進行文件操作。

基於標籤的上傳和下載

最常用的檔案上傳方式應該是使用 input 標籤,透過設定 input 標籤的 type=”file” 可以允許使用者從本機選擇檔案進行上傳。

function InputFile() {
    const [file, setFile] = useState(null);
    const handleChange = (e: React.ChangeEvent) => {
    const file = e.target.files?.[0];
    if (!file) return;
    setFile(file);
  };
    return 
}

檔案存取 API

檔案系統存取 API(File System Access API)屬於檔案系統 API 的一部分,可以透過使用 API 在使用者的操作下完成檔案的讀寫。

在使用此 API 進行檔案操作時會使用下列介面

  • showOpenFilePicker:用於顯示一個文件選擇器並允許使用者選擇一個或多個文件,然後傳回這些文件的句柄;
export function PickerFS() {
    const [file, setFile] = useState(null);
    const handleChooseFile = async () => {
    const fileHandles = await window.showOpenFilePicker();
    const file = await fileHandles[0].getFile();
    setFile(file);
  };
  return 
}
  • showSaveFilePicker:用於顯示一個檔案選擇器並允許使用者保存一個檔案(覆蓋或新建);
export function PickerFS() {
    const handleChooseFile = async () => {
    const directoryHandle = await window.showDirectoryPicker();
    const keys = directoryHandle.keys();
    // 打印该目录下所有文件的名字
    for await (const key of keys) {
      console.log(key);
    }
  };
  return 
}
  • showDirectoryPicker:用於顯示一個目錄選擇器並允許使用者選擇一個目錄;
export function PickerFS() {
    const [file, setFile] = useState(null);
    const handleDownloadFile= async () => {
    const opts = {
      suggestedName: "test.txt",
      types: [
        {
          description: "Text file",
          accept: { "text/plain": [".txt"] },
        },
      ],
    };

    const fileHandle = await window.showSaveFilePicker(opts);
    const writable = await fileHandle.createWritable();
    await writable.write("Hello, world!");
    await writable.close();
  };
  return 
}

來源私有檔案系統

來源私有檔案系統跟上面的檔案存取系統類似,都是檔案系統 API 的一部分,但是它們有個最直接的差異就是是否對使用者可見。 showXXX 介面都需要開啟檔案(目錄)選擇器,並且需要使用者主動選擇檔案(目錄),儲存的檔案也是需要儲存到使用者指定的路徑,但是來源私有檔案系統的互動不會對使用者可見,並且儲存的文件是經過處理的數據,使用者無法看到原始數據。

export function OpFs() {
  const handleChooseFile = async (event: React.ChangeEvent) => {
    const fileList = event.target.files;
    const file = fileList && fileList[0];
    if (!file) return;

    const opfsRoot = await navigator.storage.getDi rectory();
    const fileHandle = await opfsRoot.getFileHandle(file.name, { create: true });
    const writable = await fileHandle.createWritable();
    await writable.write(file);
    await writable.close();
  };

  return ;
}

await navigator.storage.getDirectory() 傳回一個表示使用者本機檔案系統根目錄的檔案句柄,然後透過getFileHandle 取得指定檔案的句柄,create 為true 表示如果沒有該檔案的話就會建立一個,接著使用createWritable建立可寫流,開發者可以透過這個可寫入流向指定檔案寫入數據,最後關閉可寫流。

注意事項

? 檔案存取系統和來源檔案系統在使用上很相似,對特定檔案或目錄的存取都需要透過檔案句柄(FileSystemFileHandle)或資料夾句柄(FileSystemDirectoryHandle)。

句柄可以理解為是對檔案本身的包裝,透過句柄的介面對檔案進行讀取(getFile)寫入(createWritable)操作。

參見

  • https://web.dev/articles/origin-private-file-system?hl=zh-cn#specifics_of_the_origin_private_file_system
  • https://developer.chrome.com/docs/capabilities/web-apis/file-system-access?hl=zh-cn
  • https://gine.me/posts/70f8e931bc17426fb54127948bcf4a0e
  • https://hughfenghen.github.io/posts/2024/03/14/web-storage-and-opfs/
版本聲明 本文轉載於:https://dev.to/yukiniro/zai-liu-lan-qi-zhong-jin-xing-wen-jian-cao-zuo-3nk1?1如有侵犯,請聯絡[email protected]刪除
最新教學 更多>
  • 如何限制動態大小的父元素中元素的滾動範圍?
    如何限制動態大小的父元素中元素的滾動範圍?
    在交互式接口中實現垂直滾動元素的CSS高度限制問題:考慮一個佈局,其中我們具有與用戶垂直滾動一起移動的可滾動地圖div,同時與固定的固定sidebar保持一致。但是,地圖的滾動無限期擴展,超過了視口的高度,阻止用戶訪問頁面頁腳。 映射{} 因此。我們不使用jQuery的“ .aimimate...
    程式設計 發佈於2025-03-16
  • 如何使用不同數量列的聯合數據庫表?
    如何使用不同數量列的聯合數據庫表?
    合併列數不同的表 當嘗試合併列數不同的數據庫表時,可能會遇到挑戰。一種直接的方法是在列數較少的表中,為缺失的列追加空值。 例如,考慮兩個表,表 A 和表 B,其中表 A 的列數多於表 B。為了合併這些表,同時處理表 B 中缺失的列,請按照以下步驟操作: 確定表 B 中缺失的列,並將它們添加到表的...
    程式設計 發佈於2025-03-16
  • 為什麼我的CSS背景圖像出現?
    為什麼我的CSS背景圖像出現?
    故障排除:CSS背景圖像未出現 ,您的背景圖像儘管遵循教程說明,但您的背景圖像仍未加載。圖像和样式表位於相同的目錄中,但背景仍然是空白的白色帆布。 而不是不棄用的,您已經使用了CSS樣式: bockent {背景:封閉圖像文件名:背景圖:url(nickcage.jpg); 如果您的html,cs...
    程式設計 發佈於2025-03-16
  • PHP陣列鍵值異常:了解07和08的好奇情況
    PHP陣列鍵值異常:了解07和08的好奇情況
    PHP數組鍵值問題,使用07&08 在給定數月的數組中,鍵值07和08呈現令人困惑的行為時,就會出現一個不尋常的問題。運行print_r($月份)返回意外結果:鍵“ 07”丟失,而鍵“ 08”分配給了9月的值。 此問題源於PHP對領先零的解釋。當一個數字帶有0(例如07或08)的前綴時,PHP...
    程式設計 發佈於2025-03-16
  • 如何修復\“常規錯誤:2006 MySQL Server在插入數據時已經消失\”?
    如何修復\“常規錯誤:2006 MySQL Server在插入數據時已經消失\”?
    How to Resolve "General error: 2006 MySQL server has gone away" While Inserting RecordsIntroduction:Inserting data into a MySQL database can...
    程式設計 發佈於2025-03-16
  • 我可以將加密從McRypt遷移到OpenSSL,並使用OpenSSL遷移MCRYPT加密數據?
    我可以將加密從McRypt遷移到OpenSSL,並使用OpenSSL遷移MCRYPT加密數據?
    將我的加密庫從mcrypt升級到openssl 問題:是否可以將我的加密庫從McRypt升級到OpenSSL?如果是這樣,如何? 答案:是的,可以將您的Encryption庫從McRypt升級到OpenSSL。 可以使用openssl。 附加說明: [openssl_decrypt()函數要求...
    程式設計 發佈於2025-03-16
  • 為什麼儘管有效代碼,為什麼在PHP中捕獲輸入?
    為什麼儘管有效代碼,為什麼在PHP中捕獲輸入?
    在php ;?>" method="post">The intention is to capture the input from the text box and display it when the submit button is clicked.但是,輸出...
    程式設計 發佈於2025-03-16
  • 為什麼我會收到MySQL錯誤#1089:錯誤的前綴密鑰?
    為什麼我會收到MySQL錯誤#1089:錯誤的前綴密鑰?
    mySQL錯誤#1089:錯誤的前綴鍵錯誤descript [#1089-不正確的前綴鍵在嘗試在表中創建一個prefix鍵時會出現。前綴鍵旨在索引字符串列的特定前綴長度長度,可以更快地搜索這些前綴。 了解prefix keys `這將在整個Movie_ID列上創建標準主鍵。主密鑰對於唯一識...
    程式設計 發佈於2025-03-16
  • 在Java中使用for-to-loop和迭代器進行收集遍歷之間是否存在性能差異?
    在Java中使用for-to-loop和迭代器進行收集遍歷之間是否存在性能差異?
    For Each Loop vs. Iterator: Efficiency in Collection TraversalIntroductionWhen traversing a collection in Java, the choice arises between using a for-...
    程式設計 發佈於2025-03-16
  • 版本5.6.5之前,使用current_timestamp與時間戳列的current_timestamp與時間戳列有什麼限制?
    版本5.6.5之前,使用current_timestamp與時間戳列的current_timestamp與時間戳列有什麼限制?
    在時間戳列上使用current_timestamp或MySQL版本中的current_timestamp或在5.6.5 此限制源於遺留實現的關注,這些限制需要對當前的_timestamp功能進行特定的實現。 創建表`foo`( `Productid` int(10)unsigned not ...
    程式設計 發佈於2025-03-16
  • 大批
    大批
    [2 數組是對象,因此它們在JS中也具有方法。 切片(開始):在新數組中提取部分數組,而無需突變原始數組。 令ARR = ['a','b','c','d','e']; // USECASE:提取直到索引作...
    程式設計 發佈於2025-03-16
  • 如何使用組在MySQL中旋轉數據?
    如何使用組在MySQL中旋轉數據?
    在關係數據庫中使用mySQL組使用mySQL組進行查詢結果,在關係數據庫中使用MySQL組,轉移數據的數據是指重新排列的行和列的重排以增強數據可視化。在這裡,我們面對一個共同的挑戰:使用組的組將數據從基於行的基於列的轉換為基於列。 Let's consider the following ...
    程式設計 發佈於2025-03-16
  • 如何在Java字符串中有效替換多個子字符串?
    如何在Java字符串中有效替換多個子字符串?
    在java 中有效地替換多個substring,需要在需要替換一個字符串中的多個substring的情況下,很容易求助於重複應用字符串的刺激力量。 However, this can be inefficient for large strings or when working with nu...
    程式設計 發佈於2025-03-16
  • Java是否允許多種返回類型:仔細研究通用方法?
    Java是否允許多種返回類型:仔細研究通用方法?
    在Java中的多個返回類型:一種誤解類型:在Java編程中揭示,在Java編程中,Peculiar方法簽名可能會出現,可能會出現,使開發人員陷入困境,使開發人員陷入困境。 getResult(string s); ,其中foo是自定義類。該方法聲明似乎擁有兩種返回類型:列表和E。但這確實是如此嗎...
    程式設計 發佈於2025-03-16
  • 為什麼使用Firefox後退按鈕時JavaScript執行停止?
    為什麼使用Firefox後退按鈕時JavaScript執行停止?
    導航歷史記錄問題:JavaScript使用Firefox Back Back 此行為是由瀏覽器緩存JavaScript資源引起的。要解決此問題並確保在後續頁面訪問中執行腳本,Firefox用戶應設置一個空功能。 警報'); }; alert('inline Alert')...
    程式設計 發佈於2025-03-16

免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。

Copyright© 2022 湘ICP备2022001581号-3