首页
学习
活动
专区
圈层
工具
发布

将文件和文件夹信息保存到localStorage

将文件和文件夹信息保存到localStorage

基础概念

localStorage是Web Storage API的一部分,它允许在用户的浏览器中存储键值对数据,具有以下特点:

  • 数据持久化存储(除非手动清除)
  • 存储容量通常为5MB左右(不同浏览器可能不同)
  • 仅支持字符串类型的数据存储
  • 同源策略限制(只能访问同域名下的数据)

实现方法

1. 基本存储方法

代码语言:txt
复制
// 存储文件或文件夹信息
function saveToLocalStorage(key, data) {
  try {
    const jsonString = JSON.stringify(data);
    localStorage.setItem(key, jsonString);
    return true;
  } catch (e) {
    console.error('存储失败:', e);
    return false;
  }
}

// 读取文件或文件夹信息
function getFromLocalStorage(key) {
  try {
    const jsonString = localStorage.getItem(key);
    return jsonString ? JSON.parse(jsonString) : null;
  } catch (e) {
    console.error('读取失败:', e);
    return null;
  }
}

2. 存储文件信息示例

代码语言:txt
复制
// 文件对象结构示例
const fileInfo = {
  name: 'example.txt',
  type: 'text/plain',
  size: 1024, // 字节
  lastModified: Date.now(),
  content: '这是文件内容...' // 或者存储Base64编码的内容
};

// 存储文件
saveToLocalStorage('file_example', fileInfo);

// 读取文件
const retrievedFile = getFromLocalStorage('file_example');
console.log(retrievedFile);

3. 存储文件夹结构示例

代码语言:txt
复制
// 文件夹结构示例
const folderStructure = {
  name: 'My Documents',
  type: 'folder',
  children: [
    {
      name: 'Work',
      type: 'folder',
      children: [
        {
          name: 'report.pdf',
          type: 'application/pdf',
          size: 204800
        }
      ]
    },
    {
      name: 'Personal',
      type: 'folder',
      children: [
        {
          name: 'photo.jpg',
          type: 'image/jpeg',
          size: 153600
        }
      ]
    }
  ]
};

// 存储文件夹结构
saveToLocalStorage('folder_structure', folderStructure);

// 读取文件夹结构
const retrievedFolder = getFromLocalStorage('folder_structure');
console.log(retrievedFolder);

优势

  1. 无需服务器:完全在客户端完成数据存储
  2. 快速访问:比从服务器请求数据更快
  3. 离线可用:即使没有网络连接也能访问数据
  4. 简单易用:API简单直观

局限性

  1. 存储容量有限:不适合存储大量文件或大文件
  2. 仅限字符串:需要手动序列化和反序列化复杂数据
  3. 同源限制:不能跨域名共享数据
  4. 安全性:不适合存储敏感信息

应用场景

  1. 浏览器应用的本地配置存储
  2. 小型离线应用的简单数据存储
  3. 用户偏好设置保存
  4. 表单数据的临时保存
  5. 轻量级Web应用的缓存机制

常见问题及解决方案

问题1:存储空间不足

原因:localStorage有大小限制(通常5MB)

解决方案

  • 压缩数据后再存储
  • 使用IndexedDB替代localStorage
  • 清理不必要的数据
代码语言:txt
复制
// 检查剩余空间
function getRemainingSpace() {
  let total = '';
  for (let i = 0; i < 1024; i++) {
    total += '01234567890123456789012345678901234567890';
  }
  total += '1234567890123456789012345678901234567890';
  
  try {
    localStorage.removeItem('test');
    localStorage.setItem('test', total);
  } catch (e) {
    const max = 1024 * 50 + 40;
    return (max - total.length) / 1024;
  }
  
  return Infinity;
}

问题2:存储复杂对象失败

原因:localStorage只能存储字符串

解决方案:使用JSON序列化和反序列化

代码语言:txt
复制
// 安全地存储和读取
function safeSet(key, value) {
  try {
    localStorage.setItem(key, JSON.stringify(value));
    return true;
  } catch (e) {
    return false;
  }
}

function safeGet(key) {
  try {
    return JSON.parse(localStorage.getItem(key));
  } catch (e) {
    return null;
  }
}

问题3:跨标签页数据同步

原因:localStorage变化不会自动同步到其他标签页

解决方案:监听storage事件

代码语言:txt
复制
// 在其他标签页监听变化
window.addEventListener('storage', function(event) {
  console.log('存储变化:', event.key, '从', event.oldValue, '变为', event.newValue);
});

进阶技巧

1. 存储文件内容(小文件)

代码语言:txt
复制
// 读取文件并存储
function readAndStoreFile(file) {
  return new Promise((resolve, reject) => {
    if (file.size > 1 * 1024 * 1024) { // 限制1MB
      reject(new Error('文件太大'));
      return;
    }
    
    const reader = new FileReader();
    reader.onload = function(e) {
      const fileData = {
        name: file.name,
        type: file.type,
        size: file.size,
        lastModified: file.lastModified,
        content: e.target.result
      };
      
      if (saveToLocalStorage('file_' + file.name, fileData)) {
        resolve();
      } else {
        reject(new Error('存储失败'));
      }
    };
    reader.onerror = reject;
    reader.readAsDataURL(file); // 或者使用readAsText/text
  });
}

2. 存储整个目录结构

代码语言:txt
复制
// 递归处理文件夹结构
async function processDirectory(entry, parentPath = '') {
  const path = parentPath ? `${parentPath}/${entry.name}` : entry.name;
  
  if (entry.isFile) {
    return new Promise(resolve => {
      entry.file(file => {
        resolve({
          name: file.name,
          type: file.type,
          size: file.size,
          lastModified: file.lastModified,
          path: path
        });
      });
    });
  } else if (entry.isDirectory) {
    const dirReader = entry.createReader();
    const entries = await new Promise(resolve => {
      dirReader.readEntries(resolve);
    });
    
    const children = await Promise.all(
      entries.map(child => processDirectory(child, path))
    );
    
    return {
      name: entry.name,
      type: 'directory',
      path: path,
      children: children
    };
  }
}

// 使用示例(需要用户通过文件选择器选择目录)
document.getElementById('dir-selector').addEventListener('change', async function(e) {
  const entries = e.target.files;
  if (entries.length) {
    const structure = await processDirectory(entries[0]);
    saveToLocalStorage('directory_structure', structure);
  }
});

3. 使用LRU缓存策略

代码语言:txt
复制
// 实现简单的LRU缓存
class LocalStorageLRU {
  constructor(maxSize = 5 * 1024 * 1024) {
    this.maxSize = maxSize;
    this.keys = JSON.parse(localStorage.getItem('_lru_keys') || '[]');
  }
  
  setItem(key, value) {
    // 计算新数据大小
    const newItemSize = JSON.stringify({key, value}).length;
    
    // 检查并清理空间
    this._makeSpace(newItemSize);
    
    // 存储数据
    localStorage.setItem(key, JSON.stringify(value));
    
    // 更新LRU列表
    this._updateKeyAccess(key);
  }
  
  getItem(key) {
    const value = JSON.parse(localStorage.getItem(key));
    if (value !== null) {
      this._updateKeyAccess(key);
    }
    return value;
  }
  
  _updateKeyAccess(key) {
    // 移除现有key(如果存在)
    this.keys = this.keys.filter(k => k !== key);
    // 添加到最前面
    this.keys.unshift(key);
    // 保存keys列表
    localStorage.setItem('_lru_keys', JSON.stringify(this.keys));
  }
  
  _makeSpace(requiredSize) {
    let currentSize = this._calculateTotalSize();
    
    // 从最久未使用的开始删除
    while (currentSize + requiredSize > this.maxSize && this.keys.length > 0) {
      const oldestKey = this.keys.pop();
      const itemSize = localStorage.getItem(oldestKey).length;
      localStorage.removeItem(oldestKey);
      currentSize -= itemSize;
    }
    
    localStorage.setItem('_lru_keys', JSON.stringify(this.keys));
  }
  
  _calculateTotalSize() {
    return Object.keys(localStorage).reduce((total, key) => {
      if (key !== '_lru_keys') {
        total += localStorage.getItem(key).length;
      }
      return total;
    }, 0);
  }
}

// 使用示例
const lruCache = new LocalStorageLRU(2 * 1024 * 1024); // 2MB限制
lruCache.setItem('file1', fileInfo1);
lruCache.setItem('file2', fileInfo2);
const file = lruCache.getItem('file1');

总结

使用localStorage存储文件和文件夹信息是一种简单有效的客户端数据持久化方案,适合小型应用和临时数据存储。对于更复杂的需求或更大的数据量,建议考虑IndexedDB或其他客户端存储方案。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

将文件夹中的文件信息统计写入到csv中

今天在整理一些资料,将图片的名字信息保存到表格中,由于数据有些多所以就写了一个小程序用来自动将相应的文件夹下的文件名字信息全部写入到csv文件中,一秒钟搞定文件信息的保存,省时省力!...下面是源代码,和大家一起共享探讨: import os import csv #要读取的文件的根目录 root_path=r'C:\Users\zjk\Desktop\XXX' # 获取当前目录下的所有目录信息并放到列表中...for dir in dirs: path_lists.append(os.path.join(root_path, dir)) return path_lists #将所有目录下的文件信息放到列表中...def get_Write_file_infos(path_lists): # 文件信息列表 file_infos_list=[] for path in path_lists...: # 遍历并写入文件信息 for root, dirnames, filenames in os.walk(path): for filename

11.2K20
  • WMI技术介绍和应用——查询文件夹信息

    本文使用了《WMI技术介绍和应用——使用VC编写一个半同步查询WMI服务的类》中代码做为基础。本节只是列出了WQL语句,具体使用参看前面的例子。        ...通过该类我们将可以获得部分常用的文件夹信息。在该类中,有属性Name,该属性标志文件的路径。由于尝试枚举文件夹是非常耗时的。本文将介绍如何获取指定文件夹的信息。...如果这个文件夹被加上了这个属性,那么本机的其他用户将无法访问该文件夹。如果我们把这个文件夹拷贝到另外一台电脑上,除非在有证书的情况下,否则无法打开这个文件夹。...一般,如果我们发现我们电脑上某个文件或者文件夹的名字是蓝色的,那它往往就是被压缩或者被加密的文件或文件夹。 如何使用WMI获取指定文件夹的创建时间?...工程源码见《WMI技术介绍和应用——WMI概述》结尾。

    1.4K10

    将MP3和PDF按名字分类归档到各自文件夹

    测试结果 文本提示: 将注释去掉: 1.问题引出 我下载了一些英语资料,这些资料的命名还好,但是就是没有用文件夹归档,整体感觉很乱,所以打算要将他们用文件夹分类。...计划是这样的: 查找所有pdf用pdf名字创建文件夹,并将对应的pdf文件,移入文件夹中; 查找与pdf名字最接近的MP3文件,并将其移入对应的文件夹中。...现在把这个问题的解决流程写出来: Step0.寻找目录中所有的MP3和PDF Step1.将PDF的文件名提取出来 Step2.用PDF的文件名创建目录 Step3.将PDF移动到新建的目录中 Step4...将匹配的MP3文件移动到对应的文件夹中 ? 2. 源码及测试结果 2.1....:param path: "文件夹"和"文件"所在的路径 :return: (list_folders, list_files) :list_folders: 文件夹

    98920

    关于发版后如何自动清理缓存

    服务端 我们知道,由 vue-cli 生成的项目中带有 public 文件夹,该文件夹下的文件不会被 webpack 处理,于是我们在该目录下新建一个 config.json 来存放我们的版本号: 这个...json 文件中大致是这个样: { "version": "" } 有了这个文件后我们在vue.config.js里配置一些东西,我们在每次打包后都会生成一个版本号存到config.json中的...这里我使用了git-revision-webpack-plugin这个插件,他可以获取到 git分支 + commit hash 等一些提交信息,利用这些信息我们组装成一个唯一的版本号: // vue.config.js...之后将版本号存在localStorage中,来更新版本号。等下次发版时再取出本地的版本号与服务器上的对比即可。...(); localStorage.setItem("version", newVersion ); window.location.reload(true); // do something

    2K20

    保存用户信息到本地存储

    启发来自obaby的《WordPress cookie保存用户信息失败–战五渣抓虫记》一文,怎么能少得了我呢。当然了,你在下次评论时会自动填充信息表单,效率是不是很快?...定义保存数据函数:saveData函数会从输入框中获取值,并使用localStorage.setItem方法将值保存到本地存储中。...监听输入框输入事件:通过addEventListener方法,将saveData函数绑定到name、email和weburl输入框的input事件上,当输入框中输入信息时自动保存数据。...注意:下面这段代码只是前端jаvascript脚本的一部分,需要在HTML文档中正确引入和调用。...当输入内容时,saveData() 函数会被触发,并将输入框的值保存到本地存储中。同时,通过在代码中添加console.log()语句,将保存成功的消息输出到控制台。

    39910

    vue权限项目(一)创建vue项目,实现登录功能,登录页面的代码的介绍

    创建路由 // @ 这个自动会到src文件夹下 在vue项目里面 @ 代表的就是src目录 ? 以上写完,启动项目,就可以到这个登录页面了 ?...开始写公共的样式,在这个文件夹下写样式 ? 只是写了公共的样式,如何让所有的vue页面都使用,在main.js里面进行导入 ? // 导入全局样式 import '....// 1、将登陆成功之后的token, 保存到客户端的sessionStorage中; localStorage中是持久化的保存 // 1.1 项目中出现了登录之外的其他API接口,...必须在登陆之后才能访问 // 1.2 token 只应在当前网站打开期间生效,所以将token保存在sessionStorage中 window.sessionStorage.setItem...$http.post('login', this.loginForm) console.log(res) const {} 这个写法就是接受后端传到前段的数据,里面的写法和后端的格式一样

    85910

    保存用户信息到本地存储

    一起来看看: 获取表单元素:通过getElementById方法获取name、email和weburl输入框的DOM元素。...定义保存数据函数:saveData函数会从输入框中获取值,并使用localStorage.setItem方法将值保存到本地存储中。...监听输入框输入事件:通过addEventListener方法,将saveData函数绑定到name、email和weburl输入框的input事件上,当输入框中输入信息时自动保存数据。...注意:下面这段代码只是前端jаvascript脚本的一部分,需要在HTML文档中正确引入和调用。...当输入内容时,saveData() 函数会被触发,并将输入框的值保存到本地存储中。同时,通过在代码中添加console.log()语句,将保存成功的消息输出到控制台。

    61840

    localStorage 还能这么用

    Web Storage 提供了两个存储对象:localStorage 和 sessionStorage。...使用 localStorage 控制文件缓存的方式有两种: 使用 Loader 加载静态文件 借助服务器端将静态文件 inline 化 这两种方式一般都会提前做好缓存过期策略,通常是使用版本号来控制,下面还会细讲...大致流程如下: 查看请求的文件 url 是否有缓存到 localStorage 过期或不匹配,到第 2 大步 文件内容有效,到第 4 大步 如果没有,到第 2 大步 如果有,判断文件是否过期或版本号是否匹配...借助服务器端将静态文件 inline 化 这个方式比上面那种更进一步,在第一次响应时把需要放入 localStorage 的文件都内联进 html 中,后面每次响应只要文件版本没有变化,都是渲染一段从...那浏览器崩溃呢,将数据变更实时保存到后台,这样似乎开销很大,实时保存到 localStorage 是个不错的解决方案,真巧,也有一个开源实现:simsalabim/sisyphus 总结 文件缓存现在有更好的解决方案

    1K40

    HTML5(三)——Web 本地存储

    WebStorage的目的是克服由cookie所带来的一些限制,当数据需要被严格控制在客户端时,不需要持续的将数据发回服务器。...web存储更加安全与快速,这些数据还不会保存到服务器,还可以存储大量数据而不影响网站性能。 web 存储类型 localStorage - 用于长久保存数据,没有有效期,直到手动清除。...web存储数据应用 应用1:取出本地存储的所有数据,以localStorage为例。 localStorage和sessionStorage是两个对象,类似json。...记住用户登录信息、存草稿、存邮件等经常会使用 localStorage,我们介绍下几种存储方式的区别,可以更好地根据需求选择存储方式。...和localStorage能够支持任何类型的对象存储。

    1.3K10

    构建一个即时消息应用(七):Access 页面

    我将采用单页应用程序方案。 首先,我们创建一个 static/index.html 文件,内容如下。 <!...路由器 在 index.html 中我们加载了两个文件:styles.css 和 main.js。我把样式留给你自由发挥。 让我们移动到 main.js。...我们告诉路由器将结果渲染为文档主体,并在离开之前向每个页面调度一个 disconnect 事件。 我们将每个页面放在不同的文件中,并使用新的动态 import() 函数导入它们。...getAuthUser() 从 localStorage 中获取经过身份验证的用户。 当我们登录时,我们会将所有的数据保存到 localStorage,这样才有意义。...这是一个异步函数,它使用 URL 查询字符串中的 token 向 /api/auth_user 发出 GET 请求,并将所有数据保存到 localStorage。 然后重定向到 /。

    1.6K30

    HTML5(三)——Web 本地存储

    WebStorage的目的是克服由cookie所带来的一些限制,当数据需要被严格控制在客户端时,不需要持续的将数据发回服务器。...web存储更加安全与快速,这些数据还不会保存到服务器,还可以存储大量数据而不影响网站性能。 web 存储类型 localStorage - 用于长久保存数据,没有有效期,直到手动清除。...web存储数据应用 应用1:取出本地存储的所有数据,以localStorage为例。 localStorage和sessionStorage是两个对象,类似json。...记住用户登录信息、存草稿、存邮件等经常会使用 localStorage,我们介绍下几种存储方式的区别,可以更好地根据需求选择存储方式。...和localStorage能够支持任何类型的对象存储。

    1.2K20

    借助工具优化开发流程,提升开发体验

    改造前 改造前,每次修改文件保存后都要刷新一下浏览器。 如果只是短时间,每次修改后手动刷新浏览器也还行。主要是这个demo要做好几天,甚至几个星期。每次修改保存后都要手动刷新,难免会让人有点烦躁。...改造后,使用了browser-sync 这个库,记住socket支持多端热更新,并且也支持将当前目录或当前目录的特定文件 放到web server中 启动。 支持https访问。...将第一次选择的串口信息保存到本地,下次进入程序,自动链接不就得了嘛。 稍微改造一下。...// 将第一次链接的串口信息保存到本地 port = await navigator.serial.requestPort(); const portInfo = { name: port.getInfo...().usbVendorId }; // 使用getInfo()来获取信息 localStorage.setItem('lastUsedPort', JSON.stringify(portInfo))

    13000
    领券