在没有文件系统 API 之前,JS 是不能对磁盘中的文件进行修改 写入磁盘的,有了File System API
之后,就能对电脑设备磁盘中的文件进行修改,删除,创建(为了安全只能对非系统文件进行操作,且必须得到用户授权)
文件系统 API(File System API)——以及通过文件系统访问 API(File System Access API)提供的方法来访问设备中的文件或者文件夹,并可以对文件,文件夹进行创建,修改,等操作
注意:仅在部分浏览器支持。
使用说明:
大多数与文件和目录的交互都通过句柄来完成。通过调用全局方法来让用户选择文件,或者选择文件夹。之后就能得到这些 文件句柄对象,目录句柄对象,最后通过这些句柄对象来操作文件或目录。
全局方法
打开文件对话框
方法window.showOpenFilePicker()
用于打开一个文件选择器对话框,允许用户选择一个或者多个文件并返回这些文件的句柄
示例:
const pickerOpts = { types: [ { description: "Images", accept: { "image/*": [".png", ".gif", ".jpeg", ".jpg"], }, }, ], excludeAcceptAllOption: true, // 是否开启过滤器 multiple: false, // 是否可多选文件 startIn: 'desktop' // ("desktop"、"documents"、"downloads"、"music"、"pictures" 或 "videos")以指定打开选择器的起始目录 }; async function getFile() { // 打开文件选择器,得到文件句柄列表数组 const fileHandles = await window.showOpenFilePicker(pickerOpts); // 操作 fileHandle 的后续代码,具体看文件句柄章节 }
打开文件保存对话框
方法 window.showSaveFilePicker()
方法用于打开一个文件选择器,以允许用户保存一个文件。可以选择一个已有文件覆盖保存,也可以输入名字新建一个文件。
示例:
async function getNewFileHandle() { const opts = { types: [ { description: "Text file", // 默认文件名 accept: { "text/plain": [".txt"] }, }, ], excludeAcceptAllOption: true, // 是否开启过滤器 multiple: false, // 是否可多选文件 startIn: 'desktop' // ("desktop"、"documents"、"downloads"、"music"、"pictures" 或 "videos")以指定打开选择器的起始目录 }; // 保存后得到文件句柄,之后可通过该文件句柄来写入数据,具体看文件句柄章节 const fileHandle await window.showSaveFilePicker(opts); return fileHandle }
打开目录对话框
方法window.showDirectoryPicker()
方法用于打开一个目录选择器,以允许用户选择一个目录。之后得到该目录的句柄,通过这个句柄,可对该文件夹内的文件进行,删除,修改,创建新文件
示例:
const option = { mode: "readwrite", // 默认为 "read",用于只读访问,或 "readwrite" 用于读写访问 startIn: 'desktop' // 默认起始目录 } async function getDir() { // 得到目录句柄 const dirHandle = await window.showDirectoryPicker(option); // 通过句柄,可对文件夹内文件进行 增删改查 }
拖拽接收文件或目录
通过 drop 事件对象,调用getAsFileSystemHandle
方法,得到一个 FileSystemFileHandle 文件对象句柄
(若拖动的项目是文件)或 FileSystemDirectoryHandle 目录对象句柄
(若拖动的项目是一个目录)。
elem.addEventListener("dragover", (e) => { e.preventDefault(); // 阻止导航 }); elem.addEventListener("drop", async (e) => { e.preventDefault(); // 阻止导航 // 处理所有条目 for (const item of e.dataTransfer.items) { // 对于文件/目录条目,kind 将是“file” if (item.kind === "file") { // 得到文件句柄,或者 目录句柄 const entry = await item.getAsFileSystemHandle(); if (entry.kind === "file") { // 收到的是文件 } else if (entry.kind === "directory") { // 收到的是目录 } } } });
对象句柄
对象句柄由全局方法调用得到的,通过句柄对象能对文件或者目录进行一些操作
文件对象句柄
文件对象句柄FileSystemFileHandle
接口表示一个指向文件的句柄。可通过 window.showOpenFilePicker()
方法(链接)来得到文件对象句柄。
方法
以下方法基本都是得到一个 Promise 对象。
读取文件
getFile()
返回一个File对象。可读取文件内容。
// 打开文件选择器 const [fileHandle] = await window.showOpenFilePicker(); // 获取文件内容 const fileData = await fileHandle.getFile(); fileData.text() // 得到文本内容
写入文件内容
createWritable()
返回的是 FileSystemWritableFileStream 文件流对象,可用于写入文件。
// 打开文件选择器 const [fileHandle] = await window.showOpenFilePicker(); // 创建一个 FileSystemWritableFileStream 用来写入。 const writable = await fileHandle.createWritable(); // 将文件内容写入到流中。 await writable.write("要写入的内容"); // 关闭文件 await writable.close();
文件流对象句柄
FileSystemWritableFileStream
对象是对单个文件进行编辑的一些功能。
方法
写入内容
write()
,向此文件写入内容,写入到当前指针偏移处。
// 创建一个新句柄,得到文件句柄 const newHandle = await window.showSaveFilePicker(); // 创建一个 FileSystemWritableFileStream 用于写入 const writableStream = await newHandle.createWritable(); // 写入内容,支持 ArrayBuffer、TypedArray、DataView、Blob 或字符串 await writableStream.write("This is my file content"); // 关闭文件并将内容写入磁盘 await writableStream.close();
移动指针位置
seek()
移动指针位置,以字节为单位。
await writableStream.seek(100s)
修改文件为指定字节大小
truncate()
将与流相关的文件修改为指定的字节大小。
await writableStream.truncate(1024);
目录对象句柄
目录对象句柄FileSystemDirectoryHandle
,可对目录内的文件进行删除,读取,创建新文件。该句柄可通过 window.showDirectoryPicker()全局方法获得
方法
获取目录内某个子目录的句柄
getDirectoryHandle()
返回的是FileSystemDirectoryHandle
目录对象句柄。
const dirName = "pic" // 子目录名称 // create 代表,当目录不存在时,自动创建该目录。最后返回该目录的句柄 const dirHandle = currentDirHandle.getDirectoryHandle(dirName, { create: true })
获取目录内某个文件句柄
getFileHandle()
方法返回的是FileSystemFileHandle
文件对象句柄。
const dirName = "123.txt" // 文件名称 // create 代表,当目录不存在时,自动创建该文件。最后返回该文件的句柄 const fileHandle = await dirHandle.getFileHandle(name, { create: true });
删除文件或者删除目录
removeEntry()
// 默认不允许直接删除有文件的文件夹,recursive 设置 true,代表递归删除子文件 dirHandle.removeEntry('text.txt', { recursive: true });
获取目录内所有子文件句柄
values()
const dirHandle = await window.showDirectoryPicker(); // 全局方法得到目录句柄 // 迭代获取每个文件句柄 for await (const value of dirHandle.values()) { console.log(value); }
例子 demo
读取文件内容
const dirHandle = await window.showDirectoryPicker({ readwrite: true, startIn: 'desktop' }); // 打开一个目录,之后可对该目录内所有文件进行操作读取 // 读取该目录中的 text.txt 文件的内容 const fileBlob = await getFileContents(dirHandle, 'text.txt') async function getFileContents(dirHandle, name) { const fileHandle = await dirHandle.getFileHandle(name); const fileBlob = await fileHandle.getFile(); const text = fileBlob.text(); return text; }
创建文件写入内容
const dirHandle = await window.showDirectoryPicker({ readwrite: true, startIn: 'desktop' }); // 打开一个目录,之后可对该目录内所有文件进行操作读取 // 创建文件,写入内容 await createFile(dirHandle, 'text1.txt', "hello word"); async function createFile(dirHandle, name, contents) { const newFileHandle = await dirHandle.getFileHandle(name, { create: true }); const writable = await newFileHandle.createWritable(); await writable.write(contents); await writable.close(); }
重命名文件名
文件系统 API 本身并未提供修改文件名的方法,但是可以通过一些思路来实现
- 读取该文件内的内容
- 创建一个新的文件,设置新的文件名,然后将原来的内容写入,最后保存
- 删除原来的文件
// 重命名文件 async function renameFile() { // 打开目录,会弹窗用户授权 const dirHandle = await window.showDirectoryPicker({ readwrite: true, startIn: 'desktop' }); const originName = "text.txt" // 原文件名 const newName = "text-ok.txt" // 新文件名 // 读取源文件内容 const fileBlob = await getFileContents(dirHandle, originName) // 创建新文件,按新文件名保存 await createFile(dirHandle, newName, fileBlob); // 删除源文件 dirHandle.removeEntry(originName, { recursive: true }); } // 创建新文件并写入内容 async function createFile(dirHandle, name, contents) { const newFileHandle = await dirHandle.getFileHandle(name, { create: true }); const writable = await newFileHandle.createWritable(); await writable.write(contents); await writable.close(); } // 读取文件内容 blob async function getFileContents(dirHandle, name) { const fileHandle = await dirHandle.getFileHandle(name); const fileBlob = await fileHandle.getFile(); return fileBlob; }
以上就是 JS File System API 前端文件系统 API 的全部内容,更多请关注其它相关文章!
原文:点击这里