Javascript 如何使用 node.js 将二进制数据写入文件?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7329128/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 01:49:58  来源:igfitidea点击:

How to write binary data to a file using node.js?

javascriptnode.jsfile-iopng

提问by Kantesh

I am trying to do toDataUrl()of canvas, and it gives base64data. I want to store it as a png. I can get the converted binary data from base64, but I cant write it to a file using NodeJs service.

我正在尝试做toDataUrl()画布,它提供base64数据。我想将它存储为png. 我可以从 base64 获取转换后的二进制数据,但我无法使用 NodeJs 服务将其写入文件。

If I write base64 data directly to the file, all data can be written, but it cannot be a pngright?. I want to store the binary data to be stored. How to do it?

如果我直接把base64数据写到文件里,所有的数据都可以写,但是不能apng对吧。我想存储要存储的二进制数据。怎么做?

Code snippet:

代码片段:

var strData = this.drawingCanvas.getContext().canvas.toDataURL();

var data = strData.replace(/^data:image\/\w+;base64,/, "");

var imgData = this.decode(data); // decode(data) is DEFINED BELOW

this.call({filePath:'<path>/image.png', data: imgData}, 
            {method:"writeFile"});`

`utf8decode : function (utftext) {
    var string = "";
    var i = 0;
    var c = c1 = c2 = 0;

    while ( i < utftext.length ) {

        c = utftext.charCodeAt(i);

        if (c < 128) {
            string += String.fromCharCode(c);
            i++;
        }
        else if((c > 191) && (c < 224)) {
            c2 = utftext.charCodeAt(i+1);
            string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
            i += 2;
        }
        else {
            c2 = utftext.charCodeAt(i+1);
            c3 = utftext.charCodeAt(i+2);
            string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
            i += 3;
        }

    }

    return string;
},`

`_keyStr : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",

decode : function (input) {
    var output = "";
    var chr1, chr2, chr3;
    var enc1, enc2, enc3, enc4;
    var i = 0;

    input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");

    while (i < input.length) {

        enc1 = this._keyStr.indexOf(input.charAt(i++));
        enc2 = this._keyStr.indexOf(input.charAt(i++));
        enc3 = this._keyStr.indexOf(input.charAt(i++));
        enc4 = this._keyStr.indexOf(input.charAt(i++));

        chr1 = (enc1 << 2) | (enc2 >> 4);
        chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
        chr3 = ((enc3 & 3) << 6) | enc4;

        output = output + String.fromCharCode(chr1);

        if (enc3 != 64) {
            output = output + String.fromCharCode(chr2);
        }
        if (enc4 != 64) {
            output = output + String.fromCharCode(chr3);
        }

    }

    output = this.utf8decode(output);

    return output;

},`

/**************************************************
wRITEfILEaaSSISTANT.JS
***************************************************/

var WriteFileAssistant = function(){};

WriteFileAssistant.prototype.run = function(future, subscription) {

var fs = IMPORTS.require('fs');
var filePath = this.controller.args.filePath;

var f = subscription.get();
f.result = {reply: data};

var fd =  fs.openSync('<path>/image.png', 'a+');
//var data = fs.writeSync(fd, g, null, encoding='utf8');

//this.controller.args.data - Image data (binary)
var buff = new Buffer(this.controller.args.data, 'binary');
//tried also with 'base64'

fs.write(fd, buff, 0, buff.length, 0, function(err,written){

});

var f = subscription.get();
f.result = {reply: data};

回答by loganfsmyth

You are making things much harder than they need to be. The node Buffer object takes base64 as input and does all of that decoding for you.

你让事情变得比他们需要的要困难得多。节点 Buffer 对象将 base64 作为输入并为您完成所有解码。

You can just strip the data:image... part from the base64 string and pass that data to your WriteFileAssistant.

您可以从 base64 字符串中去除 data:image... 部分并将该数据传递给您的 WriteFileAssistant。

var strData = this.drawingCanvas.getContext().canvas.toDataURL();
var imgData = strData.replace(/^data:image\/\w+;base64,/, "");
this.call(
  {
    filePath:'/media/internal/Collage/image.png',
    data: imgData
  },
  {
    method:"writeFile"
  }
);

The the WriteFileAssistant just needs to take the base64 string and pass that as an argument to the Buffer constructor. Also, having 'a+' on the openSync call will break things too.

WriteFileAssistant 只需要获取 base64 字符串并将其作为参数传递给 Buffer 构造函数。此外,在 openSync 调用中使用 'a+' 也会破坏事情。

var WriteFileAssistant = function(){};

WriteFileAssistant.prototype.run = function(future, subscription) {

  var fs = IMPORTS.require('fs');
  var filePath = this.controller.args.filePath;

  var fd =  fs.openSync('<path>/image.png', 'w');

  var buff = new Buffer(this.controller.args.data, 'base64');

  fs.write(fd, buff, 0, buff.length, 0, function(err,written){

  });
}

Buffer takes a string and an encoding, then it uses the encoding value to process the string into a series of bytes, so when you tell it that the string is base64, it will decode the base64 for you and create the proper decoded array of bytes to write to the file.

Buffer 接受一个字符串和一个编码,然后它使用编码值将字符串处理成一系列字节,所以当你告诉它字符串是 base64 时,它会为你解码 base64 并创建正确的解码字节数组写入文件。