我们尝试在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 新手。
最佳答案
要从 Azure 文件存储获取大于 4MB 的文件,有一个请求 header x-ms-range-get-content-md5
这会导致状态码 400
(Bad Request)错误,请引用Get File
Azure 文件存储的 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
, createReadStream
和getFileToStream
,您需要设置options.disableContentMD5Validation
属性以避免错误,请参见下文。
- @param {boolean} [options.disableContentMD5Validation] When set to true, MD5 validation will be disabled when downloading files.
并引用getFileToStream
的来源例如:
在NodeJS代码中,需要添加代码response.disableContentMD5Validation = true;
在调用函数getFileToStream
的前面.
Updated Code
// 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!");
}
}
});
<小时/>
Updated 2015-10-29: For Java Code:
Java异常问题与移动服务代码无关。这是由于缺少名为 X-ZUMO-APPLICATION
的请求 header 属性引起的。如下。
con.addRequestProperty("X-ZUMO-APPLICATION", "<Manage Access Key>");
您可以找到 key <Manage Access Key>
在Azure门户的移动服务仪表板底部,如下快照:
点击MANAGE KEYS
按钮,您可以看到两个按键,如下所示:
将任意一个添加到代码中,代码就可以正常工作了。
<小时/>Azure移动服务的NodeJS服务器示例代码:
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的权限,如下图:
最诚挚的问候。
关于node.js - java.net.SocketInputStream.read(来源未知)处的连接重置 - Node.js - Azure 文件服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33361826/