最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • Node - fs模块下的文件系统(五)

    正文概述 掘金(橙某人)   2020-12-08   413

    “Node.js® is a JavaScript runtime built on Chrome's V8 JavaScript engine”官网的一句介绍大致是说“Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行时”,简单来说就是一个能让JS运行在服务端的环境。

    前言

    最近公司事比较多,有点耽搁了,但依旧坚持着周更,不管写得如何,不放弃继续努力~

    今天主题讲点有用的,前端上传文件应该是个比较常见的事情了,那么后端要如何接收呢?今天就来玩玩这个事情吧。

    Node.js 提供一组类似 UNIX(POSIX)标准的文件操作API。(这句话可不是我说的,官方话语,反正其实就是让我们学习fs模块就对了,管那么多。。。)

    相关API罗列

    Node中和文件系统相关的API基本都有其同步与异步方法对应。

    文件-读与写

    既然是对文件的操作,那我们先来聊聊对一个已存在的文件的读写操作吧,话不多说,直接上代码,太 easy 了,多说你们又说我划水了。

    我们创建 1.txt 文件

    Hello, World.
    你好, 世界.
    

    创建 test.js 文件

    const fs = require('fs');
    fs.readFile('./1.txt', 'utf8', (err, data) => {
      console.log(data); // Hello, World  你好, 世界
    });
    

    在cmd中执行 node test.js 我们就简单的读取到了一个文件了, 如此简单就不必多说了,我们接下来往这个 1.txt 文件写入东西吧。

    Node - fs模块下的文件系统(五)

    我们稍微修改一下 test.js的代码

    const fs = require('fs');
    fs.writeFile('./1.txt', '我是写入的数据', err => {
      if(err) {
        console.log('读取文件失败')
      }else {
        console.log('写入成功') // 写入成功
      }
    })
    

    再次执行node test.js 查看 1.txt 文件

    Node - fs模块下的文件系统(五)

    同步方法:

    // 同步写入文件
    var str = '我是写进来的';
    fs.writeFileSync('./1.txt', '我是写入的数据', err => {
      console.log('写入文件失败') // 错误回调
    })
    
    // 同步读取文件
    try{
      var data = fs.readFileSync('./1.txt', 'utf-8');
      console.log(data)
    }catch (e) {
      console.log('读取文件失败')
    }
    

    文件-内容追加

    细心的铁子可能发现了,我们在给文件写入数据的时候,是以覆盖的形式写入的,那么如何用追加的形式的,Node自然也是提供了相关API了。

    再改 test.js 文件

    const fs = require('fs');
    fs.appendFile('./1.txt', '*** 我是追加进来的数据 ***', err => {
      if(err) console.log('追加数据失败')
    })
    

    查看 1.txt 文件

    Node - fs模块下的文件系统(五)

    同步方法:

    const fs = require('fs');
    fs.appendFileSync('./1.txt', '*** 我是追加进来的数据 ***')
    

    文件-创建

    Node并没有直接提供创建文件的相关API,我们能直接利用写入的API来完成,默认写入的API如果所填写的文件不存在,则会帮忙创建

    const fs = require('fs');
    fs.writeFile('./111.txt', '我是写入的数据', err => {
      if(err) {
        console.log('读取文件失败')
      }else {
        console.log('写入成功') // 写入成功
      }
    })
    

    文件-删除

    const fs = require('fs');
    fs.unlink('./1.txt', err => {
      if(err) console.log('删除文件失败')
    })
    

    同步方法:

    const fs = require('fs');
    fs.unlinkSync('./1.txt')
    

    目录-创建

    如果是已经存在的目录,不会重复创建

    const fs = require('fs');
    fs.mkdir('./public', err => {
      if(err) console.log('创建目录失败')
    })
    

    同步方法:

    const fs = require('fs');
    fs.mkdirSync('./public')
    

    目录-读取

    我们在 public 目录下新建 2.txt 文件与 newPublic 目录

    const fs = require('fs');
    fs.readdir('./public', (err, files) => {
      console.log(files); // [ '2.txt', 'newPublic' ]
    })
    

    同步方法:

    const fs = require('fs');
    console.log(fs.readdirSync('./public')); // [ '2.txt', 'newPublic' ]
    

    目录-删除

    目录下有文件/目录的话无法删除,只能删除空目录

    const fs = require('fs');
    fs.rmdir('./public', err => {
      if(err) console.log('删除目录失败')
    })
    

    同步方法:

    const fs = require('fs');
    fs.rmdirSync('./public')
    

    文件/目录-获取信息

    const fs = require('fs');
    fs.stat('./1.txt', (err, stats) => {
      if (err) {
        return console.log('获取文件信息失败');
      }
      console.log(stats);
      console.log("是否为一个文件:" + stats.isFile());
      console.log("是否为一个目录:" + stats.isDirectory());
    });
    

    Node - fs模块下的文件系统(五)

    方法描述
    stats.isFile()如果是文件返回 true,否则返回 false。stats.isDirectory()如果是目录返回 true,否则返回 false。stats.isBlockDevice()如果是块设备返回 true,否则返回 false。stats.isCharacterDevice()如果是字符设备返回 true,否则返回 false。stats.isSymbolicLink()如果是软链接返回 true,否则返回 false。stats.isFIFO()如果是FIFO,返回true,否则返回 false。FIFO是UNIX中的一种特殊类型的命令管道。stats.isSocket()如果是 Socket 返回 true,否则返回 false。

    同步方法:

    const fs = require('fs');
    const stat = fs.statSync('./1.txt')
    console.log(stat)
    

    文件/目录-是否存在

    const fs = require('fs');
    fs.exists('./1.txt', res => {
      console.log('文件/目录存在:' + res); // 文件/目录存在:true
    })
    

    同步方法:

    console.log('文件/目录存在:' + fs.existsSync('./1.txt')); // 文件/目录存在:true
    

    文件/目录-重命名与移动

    我们直接给文件/目录改名字

    const fs = require('fs');
    fs.rename('./1.txt', './2.txt', err => {
      console.log(err)
    })
    fs.rename('./public', './newPublic', err => {
      console.log(err)
    })
    

    也可以利用该API实现文件位置的移动

    fs.rename('./2.txt', './public/1.txt', err => {
      console.log(err)
    })
    

    同步方法:

    const fs = require('fs');
    fs.renameSync('./public/1.txt', './2.txt') // 我们把文件移动回来
    

    接收前端的上传的图片

    我们简单来实现一下前端上传图片(FormData形式)的时候,原生Node是需要如何来处理的。

    • 新建index.html
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>文件上传</title>
    </head>
    <script src="https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
    <body>
    <input type="file" id="file" name="myfile" />
    <button>点击</button>
    
    <script>
      $("button").click(() => {
        var file = document.getElementById("file").files[0];
        var form = new FormData();
        form.append("file", file);
        form.append('username', 'username');
        form.append('password', 'password');
        $.ajax({
          url: 'http://localhost:8888',
          type: "POST",
          data: form,
          async: false, //异步
          processData: false, // 让jq不对formData对象进行处理
          contentType: false, // 自动加上对应的contentType
          success: (result) => {
            console.log(result)
          }
        });
      });
    </script>
    </body>
    </html>
    
    • 服务端处理
    const fs = require('fs');
    const http = require('http');
    
    http.createServer((req, res) =>{
      // 允许跨域(不急, 后面跨域会专门来说)
      res.setHeader("Access-Control-Allow-Origin", "*");
      res.setHeader("Access-Control-Allow-Headers", "Content-Type, Content-Length, Authorization, Accept, X-Requested-With , yourHeaderFeild");
      res.setHeader("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS");
      res.setHeader("X-Powered-By","3.2.1");
      res.setHeader("Content-Type", "application/json;charset=utf-8");
    
      let chunks = [];
      let size = 0;
      let buffer = null;
      let offsets = [];
      req.on('data', (chunk) => {
        // chunk默认为一个二进制数据流, 该方法会执行多次, 需要我们手动累加二进制数据
        chunks.push(chunk);
        size = chunk.length; // 获取相关Buffer流的大小
      });
    
      req.on('end',() => {
        // 合并相关Buffer流
        buffer = Buffer.concat(chunks, size);
        for(let i = 0;i < buffer.length; i++){
          if(buffer[i].toString() == 13 && buffer[i+1].toString() == 10){
            offsets.push(i);
          }
        }
        // 获取文件名
        let name = buffer.slice(offsets[0], offsets[1]).toString().split(';')[2].split('=')[1];
        let filename = name.split("\"");
        // 写出文件
        let data = buffer.slice(offsets[3] + 2, offsets[offsets.length - 2]);
        fs.writeFileSync('./' + filename[1], data);
      });
    
      res.end('文件上传成功');
    }).listen('8888');
    console.log('Server running at http://localhost:8888');
    

    执行后的结果,当前目录下就有上传的图片了。。。nice Node - fs模块下的文件系统(五)

    • 关于Buffer类型,在JavaScript语言自身只有字符串数据类型, 没有二进制数据类型。但在处理像TCP流或文件流时,必须使用到二进制数据。因此在Node中,定义了一个Buffer类,该类用来创建一个专门存放二进制数据的缓存区。 www.runoob.com/nodejs/node…
    • 关于offsets偏移量,我们把buffer流toString()打印一下,在控制台大概能看到一大堆乱七八糟的东西,但是我们真正要取的只有 PNG 下面那部分,所以需要搞点偏移量,取到图片就行。包括文件的名字也能从中获取。Node - fs模块下的文件系统(五)Node - fs模块下的文件系统(五)
    • 最后说一下,其实Node来处理文件上传已经有很多npm包能快速、方便的上传了,这里简单讲一下,就是希望对这其中有个大概的了解,就这样子吧,嘿嘿~

    Node - fs模块下的文件系统(五)


    起源地下载网 » Node - fs模块下的文件系统(五)

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元