我目前使用的是 Azure Function Apps v2。我已将环境设置为 64 位并编译为 .Net Standard 2.0。主机 Json 指定版本 2。
我正在读取 .csv,它对于较小的文件效果很好。但是,当我将 180MB 的 .csv 读入 string[] 列表时,读取时它会膨胀到超过 GB,当我尝试解析它时,它会超过 2 GB,但随后会抛出“内存不足”异常。即使运行超过 3.5 GB 的应用服务计划也无法解决问题。
编辑: 我正在使用这个:
Uri blobUri = AppendSasOnUri(blobName); _webClient = new WebClient();
Stream sourceStream = _webClient.OpenRead(blobUri);
_reader = new StreamReader(sourceStream);
但是,由于它是 csv,因此我将拆分整列数据。很难摆脱这个:
internal async Task<List<string[]>> ReadCsvAsync() {
while (!_reader.EndOfStream) {
string[] currentCsvRow = await ReadCsvRowAsync();
_fullBlobCsv.Add(currentCsvRow);
}
return _fullBlobCsv; }
目标是在一切完成后将 json 存储到 blob 中。
最佳答案
尝试使用流 (StreamReader
) 读取输入 .csv 文件并一次处理一行。
我能够使用流解析消费计划中的 300mb 文件。我的用例可能不相同但相似。解析一个大型串联 pdf 文件,并将其分成 5000 多个较小的文件,并将分离的文件存储到 blob 容器中。下面是我的代码供引用。
对于您的用例,如果您要将所有解析的数据推送到单个 blob 中,您可能需要使用 CloudAppendBlob
而不是 CloudBlockBlob
。
public async static void ExtractSmallerFiles(CloudBlockBlob myBlob, string fileDate, ILogger log)
{
using (var reader = new StreamReader(await myBlob.OpenReadAsync()))
{
CloudBlockBlob blockBlob = null;
var fileContents = new StringBuilder(string.Empty);
while (!reader.EndOfStream)
{
var line = reader.ReadLine();
if (line.StartsWith("%%MS_SKEY_0000_000_PDF:"))
{
var matches = Regex.Match(line, @"%%MS_SKEY_0000_000_PDF: A(\d+)_SMFL_B1234_D(\d{8})_A\d+_M(\d{15}) _N\d+");
var smallFileDate = matches.Groups[2];
var accountNumber = matches.Groups[3];
var fileName = $"SmallerFiles/{smallFileDate}/{accountNumber}.pdf";
blockBlob = myBlob.Container.GetBlockBlobReference(fileName);
}
fileContents.AppendLine(line);
if (line.Equals("%%EOF"))
{
log.LogInformation($"Uploading {fileContents.Length} bytes to {blockBlob.Name}");
await blockBlob.UploadTextAsync(fileContents.ToString());
fileContents = new StringBuilder(string.Empty);
}
}
await myBlob.DeleteAsync();
log.LogInformation("Extracted Smaller files");
}
}
关于azure - Azure Function App V2 是否可以使用超过 1.5 Gb 的内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52826203/