【发布时间】:2020-08-07 08:22:50
【问题描述】:
我们正在使用parquet.net 来编写 parquet 文件。我设置了一个包含 3 列和 2 行的简单模式:
// Set up the file structure
var UserKey = new Parquet.Data.DataColumn(
new DataField<Int32>("UserKey"),
new Int32[] { 1234, 12345}
);
var AADID = new Parquet.Data.DataColumn(
new DataField<string>("AADID"),
new string[] { Guid.NewGuid().ToString(), Guid.NewGuid().ToString() }
);
var UserLocale = new Parquet.Data.DataColumn(
new DataField<string>("UserLocale"),
new string[] { "en-US", "en-US" }
);
var schema = new Schema(UserKey.Field, AADID.Field, UserLocale.Field
);
使用 FileStream 写入本地文件时,会创建一个文件,代码完成后,我可以看到文件中有两行(之后为 1 kb):
using (Stream fileStream = System.IO.File.OpenWrite("C:\\Temp\\Users.parquet")) {
using (var parquetWriter = new ParquetWriter(schema, fileStream)) {
// Creare a new row group in the file
using (ParquetRowGroupWriter groupWriter = parquetWriter.CreateRowGroup()) {
groupWriter.WriteColumn(UserKey);
groupWriter.WriteColumn(AADID);
groupWriter.WriteColumn(UserLocale);
}
}
}
然而,当我尝试使用它来写入我们的 blob 存储时,只会生成一个空文件,并且数据丢失了:
// Open reference to Blob Container
CloudAppendBlob blob = OpenBlobFile(blobEndPoint, fileName);
using (MemoryStream stream = new MemoryStream()) {
blob.CreateOrReplaceAsync();
using (var parquetWriter = new ParquetWriter(schema, stream)) {
// Creare a new row group in the file
using (ParquetRowGroupWriter groupWriter = parquetWriter.CreateRowGroup()) {
groupWriter.WriteColumn(UserKey);
groupWriter.WriteColumn(AADID);
groupWriter.WriteColumn(UserLocale);
}
// Set stream position to 0
stream.Position = 0;
blob.AppendBlockAsync(stream);
return true;
}
...
public static CloudAppendBlob OpenBlobFile (string blobEndPoint, string fileName) {
CloudBlobContainer container = new CloudBlobContainer(new System.Uri(blobEndPoint));
CloudAppendBlob blob = container.GetAppendBlobReference(fileName);
return blob;
}
阅读文档,我认为我的 blob.AppendBlocAsync 实现应该可以解决问题,但我最终得到了一个空文件。有人会对这是为什么以及如何解决它有什么建议吗?
提前致谢。
【问题讨论】:
-
我可能只是不小心弄明白了。在调试时,我注意到我最终得到了一个文件,其中包含我的 blob 存储中的内容。因此,我的结论是代码确实有效,但不知何故肯定存在某种时间问题。我把包含上面代码的方法变成了Async方法,在这段代码前加了
await语句:blob.AppendBlockAsync(stream);,这样好像解决了空文件的问题。 -
在没有
await的情况下调用async方法会将控制权返回到下一行,而无需等待异步工作完成。由于您的下一行是“返回”,因此程序可能会尝试写入然后因为执行结束而被杀死(例如 http 请求,或者只是正常的 cli 退出) -
@zaitsman - 谢谢,这就是我的想法。直到我偏离了进程,才意识到这个过程实际上是在写入数据。它只是没有时间完成,所以看起来它真正做的唯一一件事就是创建文件,然后收工。
标签: c# azure-functions azure-blob-storage parquet parquet.net