1

我们正在尝试使用 Azure 中的 node.js 创建服务以进行下载。我们正在发送 writeStream 作为响应。

更新:

var option = new Object();
option.disableContentMD5Validation = true;
option.maximumExecutionTimeInMs = 20 * 60000;
fileService.getFileToStream(shareName, dirPath, fileName, response, option, function (error, result, response) {
    if(!error) {
        if(response.isSuccessful) {
      console.log("Success!");
  }
    }
});

在下载小于 4MB 的文件时,它工作正常。但是当下载超过 4MB 时,它给出了错误。

java.net.SocketException: Connection reset
at java.net.SocketInputStream.read(Unknown Source)
at java.net.SocketInputStream.read(Unknown Source)
at sun.security.ssl.InputRecord.readFully(Unknown Source)
at sun.security.ssl.InputRecord.read(Unknown Source)
at sun.security.ssl.SSLSocketImpl.readRecord(Unknown Source)
at sun.security.ssl.SSLSocketImpl.readDataRecord(Unknown Source)
at sun.security.ssl.AppInputStream.read(Unknown Source)
at java.io.BufferedInputStream.fill(Unknown Source)
at java.io.BufferedInputStream.read1(Unknown Source)
at java.io.BufferedInputStream.read(Unknown Source)
at sun.net.www.MeteredStream.read(Unknown Source)
at java.io.FilterInputStream.read(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection$HttpInputStream.read(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection$HttpInputStream.read(Unknown Source)
at FileserviceTest.sendGET(FileserviceTest.java:58)
at FileserviceTest.main(FileserviceTest.java:18)

下面是示例 java 客户端代码。

    public static void sendGET() throws IOException {
    FileOutputStream fos = null;

    URL obj = new URL("https://crowdtest-fileservice.azure-mobile.net/api/files/");
    HttpURLConnection con = (HttpURLConnection) obj.openConnection();
    con.setRequestMethod("GET");
    con.setRequestProperty("sharename", "newamactashare");
    con.setRequestProperty("directorypath", "MaheshApp/TestLibrary/");
    con.setRequestProperty("filename", "Test.apk");

    int responseCode = con.getResponseCode();
    System.out.println("GET Response Code :: " + responseCode);
    if (responseCode == HttpURLConnection.HTTP_OK) { // success
        fos = new FileOutputStream("C:/Users/uma.maheshwaran/Desktop/Test.mt");
        InputStream iin = con.getInputStream();

        byte[] buffer = new byte[4096]; // declare 4KB buffer
        int len;

        // while we have availble data, continue downloading and storing to
        // local file
        while ((len = iin.read(buffer)) > 0) {
            fos.write(buffer, 0, len);
        }
        iin.close();
        fos.close();

        // print result
        System.out.println("Done");
    } else {
        BufferedReader br = new BufferedReader(new InputStreamReader(con.getErrorStream()));
        String line = "";
        while ((line = br.readLine()) != null) {
            System.out.println(line);
        }
        System.out.println("GET request not worked");
    }

}

我们可以将写入流转换为缓冲流吗?如果是这样,我们如何发送响应。或者有没有其他方法可以发送大量数据作为响应。请帮助我。我是 node.js 的新手。

4

1 回答 1

3

从 Azure 文件存储中获取大于 4MB 的文件,有一个请求头x-ms-range-get-content-md5会导致状态码400(Bad Request) 错误,请参考Get FileAzure 文件存储的 REST API 文档https://msdn.microsoft.com/ en-us/library/azure/dn194274.aspx,见下文:

在此处输入图像描述

因此,我查看了适用于 Node 的 Azure 文件存储 SDK 的来源(https://github.com/Azure/azure-storage-node/blob/master/lib/services/file/fileservice.js)。对于函数getFileToText、和getFileToLocalFile,您需要设置属性以避免错误,见下文。createReadStreamgetFileToStreamoptions.disableContentMD5Validation

  • @param {boolean} [options.disableContentMD5Validation] 设置为 true 时,下载文件时将禁用 MD5 验证。

并参考getFileToStream例如的来源:

在此处输入图像描述

在 NodeJS 代码中,需要response.disableContentMD5Validation = true;在调用函数的前面加上代码getFileToStream

更新代码

// this sentence must be removed in Azure Mobile Service, it cause the error.
// response.setHeader('Content-Type', 'application/json');
// add the argument {disableContentMD5Validation: true}
fileService.getFileToStream(shareName, dirPath, fileName, response, {disableContentMD5Validation: true}, function (error, result, response) {
    if(!error) {
        if(response.isSuccessful) {
           console.log("Success!");
        }
    }
});

2015-10-29 更新:对于 Java 代码:

Java 异常问题与移动服务代码无关。这是由于缺少X-ZUMO-APPLICATION如下所示的请求标头属性引起的。

con.addRequestProperty("X-ZUMO-APPLICATION", "<Manage Access Key>");

<Manage Access Key>您可以在 Azure Portal 的 Mobile Service Dashboard 底部找到密钥,如下图所示:

在此处输入图像描述

点击MANAGE KEYS按钮,可以看到如下两个键:

在此处输入图像描述

将任何一个添加到代码中,然后代码就可以正常工作。


Azure 移动服务的 NodeJS 中的服务器示例代码:</p>

exports.get = function(request, response) {
    var azure = require('azure-storage');
    var fileService = azure.createFileService('<storage_account_name>','<storage_access_key>');
    fileService.getFileToStream('taskshare', 'taskdirectory', 'taskfile', response,{disableContentMD5Validation:true}, function(error, result, res) {
                if(!error) {
                  console.log(result);
                  console.log(res);
                }
    });
};

Java中的客户端示例代码:

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;

import javax.net.ssl.HttpsURLConnection;

import org.apache.commons.io.IOUtils;

public class MobileSample {

    public static void main(String[] args) throws IOException {
        URL url = new URL("https://<mobile_service_name>.azure-mobile.net/api/<api_name: example 'filestorage'>");
        HttpURLConnection https = (HttpURLConnection) url.openConnection();
        https.addRequestProperty("X-ZUMO-APPLICATION", "<manage_access_key>");
        https.connect();
        int respCode = https.getResponseCode();
        System.out.println(respCode);
        InputStream is = https.getInputStream();
        IOUtils.copy(is, new FileOutputStream("<file_name>"));
        is.close();
    }
}

请在 Azure Portal 中查看 api 的权限,见下图:

在此处输入图像描述

此致。

于 2015-10-27T08:24:41.653 回答