使用node.js从Google Drive读取二进制文件

7

我在使用API从Drive获取二进制文件时遇到了问题,我一直在打圈子。

这里是相关的代码片段:

// Load client secrets from a local file.
fs.readFile('client_secret.json', function processClientSecrets(err, content) {
  if (err) {
    console.log('Error loading client secret file: ' + err);
    return;
  }
  // Authorize a client with the loaded credentials, then call the
  // Drive API.
  oauth.authorize(JSON.parse(content), dasm.init, driveapi.getFile)
});

driveapi.getFile:

function getFile(auth, cb) {
  var service = google.drive('v3');
  service.files.get({
    auth: auth,
    pageSize: 20,
    fileId: "0B2h-dgPh8_5CZE9WZVM4a3BxV00",
    alt: 'media'
  }, function(err, response) {
    if (err) {
      console.log('The API returned an error: ' + err);
      return;
    }
    cb(response)
  });
}

现在,response 看起来是一个字符串。当我尝试将其转换为十六进制时,它变得很疯狂。有没有办法将 response 转换成 Buffer?或者当我从 service.files.get 获取它时,它已经损坏了吗?
所谓的“疯狂”,是指...
console.log(
        arrData[0].charCodeAt(0).toString(2),
        '-',
        arrData[1].charCodeAt(0).toString(2),
        '-',
        arrData[2].charCodeAt(0).toString(2),
        '-',
        arrData[3].charCodeAt(0).toString(2),
        '-',
        arrData[4].charCodeAt(0).toString(2)
    )

= 1001101 - 1011010 - 1111111111111101 - 0 - 11 (我使用二进制尝试查看有什么损坏)

正确的十六进制应为4D 5A 90 00 03

编辑:对于那些感到困惑的人,像我一样,关于如何使90变成fffd,这是在值不映射到ASCII字符时显示的Unicode替换字符

2个回答

5
最终我解决了这个问题。Google APIs使用request模块,你可以应用任何它接受的选项。作为参考,你需要设置[encoding: null]2,因为任何其他选项都会将响应传递给toString,如果你正在处理二进制数据,则会破坏它。
下面是可工作的代码:
function getFile(auth, cb) {
  var service = google.drive({
    version: 'v3', 
    encoding: null
  });
  service.files.get({
    auth: auth,
    fileId: "0B2h-dgPh8_5CZE9WZVM4a3BxV00",
    alt: 'media'
  }, function(err, response) {
    if (err) {
      console.log('The API returned an error: ' + err);
      return;
    }
    cb(response)
  });
}

0

此答案基于MDN的一篇文章,关于发送和接收二进制数据

function getFile(auth, cb) {
  var service = google.drive('v3');
  service.files.get({
  auth: auth,
  pageSize: 20,
  fileId: "0B2h-dgPh8_5CZE9WZVM4a3BxV00",
  alt: 'media'
 }, function(err, response) {
  if (err) {
    console.log('The API returned an error: ' + err);
    return;
  }
  var arrayBuffer = response; 
  if (arrayBuffer) {
    var byteArray = new Uint8Array(arrayBuffer);
    for (var i = 0; i < byteArray.byteLength; i++) {
      // do something with each byte in the array
    }
  }
 }

如果您没有获得字节数组,那么您必须使用以下代码将字符串转换为字节数组。
var bytes = [];
for (var i = 0, len = response.length; i < len; ++i) {
  bytes.push(str.charCodeAt(i));
}
var byteArray = new Uint8Array(bytes);
for (var i = 0; i < byteArray.byteLength; i++) {
   // do something with each byte in the array
}

这个例子似乎只在设置 responseType = "arraybuffer" 时才能工作,但是我似乎无法在 Drive API 中这样做。你的代码示例返回一个长度为零的通用对象。 - Drazisil

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接