I am using node.js to create file service for Azure File storage. I am using azure-storage-node (http://azure.github.io/azure-storage-node/)
for this.
我用节点。为Azure文件存储创建文件服务。我使用的是azure.github. io/az-storage -node/)节点。
I am trying to download a file from Azure file storage. Below is my code snippet
我正在尝试从Azure file storage下载一个文件。下面是我的代码片段
// Download a file from Share
exports.get = function(request, response){
var shareName = request.headers.sharename;
var dirPath = request.headers.directorypath;
var fileName = request.headers.filename;
var fileService = azure.createFileService();
var readStream = fileService.createReadStream(shareName, dirPath, fileName);
var dataLength = 0;
var body = '';
readStream.on('data', function (chunk) {
dataLength += chunk.length;
})
readStream.on('end', function(){
console.log('The length was:', dataLength);
});
response.setHeader('Content-Type', 'application/json');
response.send(statusCodes.OK, JSON.stringify("Success!"));
}
I able to get the stream of data. But how can I sent the stream in the response so that we can get it in the rest call.
我能得到数据流。但是我如何在响应中发送流以便在rest调用中获得它。
I tried readStream.pipe(response);
and
我试着readStream.pipe(响应);和
response.write(typeof chunk);
response.end() but it doesnt work;
I am new to node.js. Please help me on this.
我是新手。请在这方面帮助我。
Updated:
更新:
I tried the following.
我试着以下。
response.writeHead(200, {'Content-Type': 'application/json'});
var readStream = fileService.createReadStream(shareName, dirPath, fileName);
readStream.pipe(response);
But its throwing follwing error.
但它犯了一个错误。
ERROR
An unhandled exception occurred. Error: Can't set headers after they are sent.
at ServerResponse.OutgoingMessage.setHeader (http.js:679:11)
at ServerResponse.res.setHeader (D:\home\site\wwwroot\node_modules\express\node_modules\connect\lib\patch.js:59:22)
at ServerResponse.res.set.res.header (D:\home\site\wwwroot\node_modules\express\lib\response.js:518:10)
at addDefaultHeaders (D:\home\site\wwwroot\runtime\request\requesthandler.js:582:9)
at ServerResponse.<anonymous> (D:\home\site\wwwroot\runtime\request\requesthandler.js:291:13)
at ServerResponse._.wrap [as end] (D:\home\site\wwwroot\node_modules\underscore\underscore.js:692:22)
at ChunkStream.onend (stream.js:66:10)
at ChunkStream.EventEmitter.emit (events.js:126:20)
at ChunkStream.end (D:\home\site\wwwroot\App_Data\config\scripts\node_modules\azure-storage\lib\common\streams\chunkstream.js:90:8)
at Request.onend (stream.js:66:10)
The return datatype of fileService.createReadStream(shareName, dirPath, fileName);
is ChunkStream
fileService的返回数据类型。createReadStream(shareName dirPath,文件名);是ChunkStream
Updated:
更新:
This is my updated code which works.
这是我更新过的代码。
var option = new Object();
option.disableContentMD5Validation = true;
option.maximumExecutionTimeInMs = 20 * 60000;
option.timeoutIntervalInMs = 20 * 6000;
fileService.getFileToStream(shareName, dirPath, fileName, response, option, function(error, result, res) {
if(!error) {
if(res.isSuccessful) {
console.log(result);
console.log(res);
console.log("Success!");
}
}
});
But more frequently I am getting below error.
但更常见的是,我在错误以下。
ERROR
An unhandled exception occurred. Error: Can't set headers after they are sent.
at ServerResponse.OutgoingMessage.setHeader (http.js:679:11)
at ServerResponse.res.setHeader (D:\home\site\wwwroot\node_modules\express\node_modules\connect\lib\patch.js:59:22)
at ServerResponse.res.set.res.header (D:\home\site\wwwroot\node_modules\express\lib\response.js:518:10)
at addDefaultHeaders (D:\home\site\wwwroot\node_modules\azure-mobile-services\runtime\request\requesthandler.js:590:9)
at ServerResponse. (D:\home\site\wwwroot\node_modules\azure-mobile-services\runtime\request\requesthandler.js:299:13)
at ServerResponse._.wrap as end
at Request.onend (stream.js:66:10)
at Request.EventEmitter.emit (events.js:126:20)
at IncomingMessage.Request.onRequestResponse.strings (D:\home\site\wwwroot\App_Data\config\scripts\node_modules\azure-storage\node_modules\request\request.js:1153:12)
at IncomingMessage.EventEmitter.emit (events.js:126:20)
2 个解决方案
#1
3
The NodeJS Class http.ServerResponse
implements the Writable Stream
interface, please refer to the NodeJS API https://nodejs.org/api/http.html#http_class_http_serverresponse and https://nodejs.org/api/stream.html#stream_class_stream_writable_1.
NodeJS类http。服务器响应实现了可写流接口,请参考NodeJS API https://nodejs.org/api/http.html#http_class_http_serverresponse和https://nodejs.org/api/stream.html# stream_class_writable_1。
So you just need to use the object response
instead of the stream writer fs.createStreamWriter(...)
in the sample code "getFileToStream" http://azure.github.io/azure-storage-node/#toc8 when you send data stream into response for NodeJS.
因此,您只需要在示例代码“getFileToStream”http://azure.github中使用对象响应而不是流编写器fs.createStreamWriter(…)。当您将数据流发送到NodeJS的响应中时,io/ az-storage -node/#toc8。
This is my sample code as below:
这是我的示例代码如下:
var http = require('http');
var azure = require('azure-storage');
var fileService = azure.createFileService('<storage_key_name>','<storage_access_key>');
http.createServer(function (request, response) {
var shareName = request.headers.sharename;
var dirPath = request.headers.directorypath;
var fileName = request.headers.filename;
response.setHeader('Content-Type', 'application/json');
fileService.getFileToStream(shareName, dirPath, fileName, response, {disableContentMD5Validation: true}, function(error, result, response) {
if(!error) {
//console.log(result);
//console.log(response);
if(response.isSuccessful) {
console.log("Success!");
}
}
});
}).listen(1337, "127.0.0.1");
console.log('Server running at http://127.0.0.1:1337/');
Best Regards.
致以最亲切的问候。
For getting File greater than 4MB from Azure File Storage, there is a request header x-ms-range-get-content-md5
that it will cause the status code 400
(Bad Request) error, please refer to the Get File
REST API doc of Azure File Storage https://msdn.microsoft.com/en-us/library/azure/dn194274.aspx, see below:
对于从Azure文件存储中获取大于4MB的文件,有一个请求头x-ms-range-get-content-md5会导致状态码400(错误请求)错误,请参阅Azure文件存储的Get File REST API doc https://msdn.microsoft.com/en- us/library/azure/azure/dn1944.aspx,参见下面:
So I reviewed the source of Azure File Storage SDK for Node (https://github.com/Azure/azure-storage-node/blob/master/lib/services/file/fileservice.js). For the function getFileToText
, getFileToLocalFile
, createReadStream
and getFileToStream
, you need to set the options.disableContentMD5Validation
attribute to avoid the error, see below.
因此,我回顾了Node的Azure文件存储SDK的源代码(https://github.com/Azure/azure-storage-node/blob/master/lib/services/file/fileservice.js)。对于函数getFileToText、getFileToLocalFile、createReadStream和getFileToStream,您需要设置选项。为了避免错误,请参见下面的内容。
- @param {boolean} [options.disableContentMD5Validation] When set to true, MD5 validation will be disabled when downloading files.
- @param {布尔}[选项。当设置为true时,在下载文件时将禁用MD5验证。
And refer to the source of getFileToStream
as example:
并以getFileToStream的源代码为例:
In my sample code, need to add the code {disableContentMD5Validation: true}
as options at the front of invoking the function getFileToStream
.
在我的示例代码中,需要在调用函数getFileToStream之前添加代码{disableContentMD5Validation: true}作为选项。
#2
1
You might want to try in this way:
你可能想这样尝试:
exports.get = function(request, response) {
var shareName = request.headers.sharename;
var dirPath = request.headers.directorypath;
var fileName = request.headers.filename;
var fileService = azure.createFileService();
var readStream = fileService.createReadStream(shareName, dirPath, fileName);
var dataLength = 0;
readStream.on('data', function (chunk) {
dataLength += chunk.length;
})
readStream.on('end', function(){
response.setHeader('Content-Type', 'application/json');
response.setHeader('Content-Length', dataLength);
});
readStream.pipe(response);
response.on('finish', function (chunk) {
response.send(statusCodes.OK, JSON.stringify("Success!"));
})
}
#1
3
The NodeJS Class http.ServerResponse
implements the Writable Stream
interface, please refer to the NodeJS API https://nodejs.org/api/http.html#http_class_http_serverresponse and https://nodejs.org/api/stream.html#stream_class_stream_writable_1.
NodeJS类http。服务器响应实现了可写流接口,请参考NodeJS API https://nodejs.org/api/http.html#http_class_http_serverresponse和https://nodejs.org/api/stream.html# stream_class_writable_1。
So you just need to use the object response
instead of the stream writer fs.createStreamWriter(...)
in the sample code "getFileToStream" http://azure.github.io/azure-storage-node/#toc8 when you send data stream into response for NodeJS.
因此,您只需要在示例代码“getFileToStream”http://azure.github中使用对象响应而不是流编写器fs.createStreamWriter(…)。当您将数据流发送到NodeJS的响应中时,io/ az-storage -node/#toc8。
This is my sample code as below:
这是我的示例代码如下:
var http = require('http');
var azure = require('azure-storage');
var fileService = azure.createFileService('<storage_key_name>','<storage_access_key>');
http.createServer(function (request, response) {
var shareName = request.headers.sharename;
var dirPath = request.headers.directorypath;
var fileName = request.headers.filename;
response.setHeader('Content-Type', 'application/json');
fileService.getFileToStream(shareName, dirPath, fileName, response, {disableContentMD5Validation: true}, function(error, result, response) {
if(!error) {
//console.log(result);
//console.log(response);
if(response.isSuccessful) {
console.log("Success!");
}
}
});
}).listen(1337, "127.0.0.1");
console.log('Server running at http://127.0.0.1:1337/');
Best Regards.
致以最亲切的问候。
For getting File greater than 4MB from Azure File Storage, there is a request header x-ms-range-get-content-md5
that it will cause the status code 400
(Bad Request) error, please refer to the Get File
REST API doc of Azure File Storage https://msdn.microsoft.com/en-us/library/azure/dn194274.aspx, see below:
对于从Azure文件存储中获取大于4MB的文件,有一个请求头x-ms-range-get-content-md5会导致状态码400(错误请求)错误,请参阅Azure文件存储的Get File REST API doc https://msdn.microsoft.com/en- us/library/azure/azure/dn1944.aspx,参见下面:
So I reviewed the source of Azure File Storage SDK for Node (https://github.com/Azure/azure-storage-node/blob/master/lib/services/file/fileservice.js). For the function getFileToText
, getFileToLocalFile
, createReadStream
and getFileToStream
, you need to set the options.disableContentMD5Validation
attribute to avoid the error, see below.
因此,我回顾了Node的Azure文件存储SDK的源代码(https://github.com/Azure/azure-storage-node/blob/master/lib/services/file/fileservice.js)。对于函数getFileToText、getFileToLocalFile、createReadStream和getFileToStream,您需要设置选项。为了避免错误,请参见下面的内容。
- @param {boolean} [options.disableContentMD5Validation] When set to true, MD5 validation will be disabled when downloading files.
- @param {布尔}[选项。当设置为true时,在下载文件时将禁用MD5验证。
And refer to the source of getFileToStream
as example:
并以getFileToStream的源代码为例:
In my sample code, need to add the code {disableContentMD5Validation: true}
as options at the front of invoking the function getFileToStream
.
在我的示例代码中,需要在调用函数getFileToStream之前添加代码{disableContentMD5Validation: true}作为选项。
#2
1
You might want to try in this way:
你可能想这样尝试:
exports.get = function(request, response) {
var shareName = request.headers.sharename;
var dirPath = request.headers.directorypath;
var fileName = request.headers.filename;
var fileService = azure.createFileService();
var readStream = fileService.createReadStream(shareName, dirPath, fileName);
var dataLength = 0;
readStream.on('data', function (chunk) {
dataLength += chunk.length;
})
readStream.on('end', function(){
response.setHeader('Content-Type', 'application/json');
response.setHeader('Content-Length', dataLength);
});
readStream.pipe(response);
response.on('finish', function (chunk) {
response.send(statusCodes.OK, JSON.stringify("Success!"));
})
}