在这篇文章中,我们将为您详细介绍同一映像的OracleBlob二进制文件不同的内容。此外,我们还会涉及一些关于ApacheBeam-在保持Blob分组的同时并行化GoogleCloudStorageB
在这篇文章中,我们将为您详细介绍同一映像的 Oracle Blob 二进制文件不同的内容。此外,我们还会涉及一些关于Apache Beam - 在保持 Blob 分组的同时并行化 Google Cloud Storage Blob 下载、Azure Blob Storage 基本用法 -- Azure Storage 之 Blob、Azure Blob 存储 - 如何在上传 Blob 后获取 Blob 存储 ID?、Azure Blob 存储中的文件 ID [AZURE-BLOB]的知识,以帮助您更全面地了解这个主题。
本文目录一览:- 同一映像的 Oracle Blob 二进制文件不同
- Apache Beam - 在保持 Blob 分组的同时并行化 Google Cloud Storage Blob 下载
- Azure Blob Storage 基本用法 -- Azure Storage 之 Blob
- Azure Blob 存储 - 如何在上传 Blob 后获取 Blob 存储 ID?
- Azure Blob 存储中的文件 ID [AZURE-BLOB]
同一映像的 Oracle Blob 二进制文件不同
如何解决同一映像的 Oracle Blob 二进制文件不同
当我尝试在 oracle 表上存储相同的图像时, 我注意到图像看起来相同但二进制 blob 文件不同。 所以我想知道这是什么原因。 是不是跟时间有关?
解决方法
可能有很多原因,包括(但不限于):
- 不同的文件格式(PNG、jpeg、BMP、TIFF、GIF 等)
- 不同的设置(高压缩与低压缩、Alpha 通道等)
- 其他元数据(时间、位置、评论、相机设置等)
Apache Beam - 在保持 Blob 分组的同时并行化 Google Cloud Storage Blob 下载
如何解决Apache Beam - 在保持 Blob 分组的同时并行化 Google Cloud Storage Blob 下载
我希望能够在单个 PCollection
元素中维护一组实体,但同时从 Google Cloud Storage (GCS) 中提取这些实体。即PCollection<Iterable<String>>
--> PCollection<Iterable<String>>
其中起始 PCollection
是文件路径的可迭代对象,结果 PCollection
是文件内容的可迭代对象。或者,PCollection<String> --> PCollection<Iterable<String>>
也可以工作,甚至可能更可取,其中起始 PCollection
是一个 glob 模式,结果 PCollection
是与 glob 匹配的文件内容的可迭代对象。>
我的用例是,在我的管道中,我将输入 PCollection<String>
作为输入。 PCollection
的每个元素都是一个 GCS glob 模式。将与 glob 匹配的文件分组在一起很重要,因为文件的内容——一旦读取了组中的所有文件——需要在管道的下游分组。我最初尝试使用 FileIO.matchAll
和随后的 GroupByKey
。但是,matchAll、window 和 GroupByKey
组合无法保证在执行 GroupByKey 转换之前将读取与 glob 匹配的所有文件并在同一窗口中(尽管我可能误解了 Windowing)。如果应用大的时间跨度 WindowFn
有可能达到预期的结果,但它仍然是概率性的,而不是保证在分组之前将读取所有文件。保持尽可能低的延迟也是我的管道的主要目标。
因此,我的下一个当前可操作的计划是使用 AsyncHttpClient
来扇出通过 GCS HTTP API 获取文件内容。我觉得这与 Beam 中的纹理背道而驰,并且在并行化方面可能不是最佳的。
所以我开始研究 SplittableDoFn 。我目前的计划是允许拆分,以便可以单独处理输入 Iterable 中的每个实体(即来自 glob 模式的每个匹配文件)。我已经能够修改 FileIO#MatchFn
(defined here in the Java SDK) 以提供 PCollection<String> -> PCollection<Iterable<String>>
在 GCS glob 模式输入和 glob 匹配的 Iterable 输出之间转换的机制。
我遇到的挑战是:如何将拆分的调用分组/收集回 DoFn
中的单个输出值?我曾尝试使用有状态处理并使用 BagState
沿途收集文件内容,但我在某种程度上意识到可拆分的 ProcessElement
方法 DoFn
可能只接受 {{ 1}} 和 ProcessContext
元组,并且没有其他参数,因此没有 Restriction
参数引用 StateId
(在运行时抛出无效参数错误)。
我注意到在官方 SDF proposal doc 的 StateSpec
示例中创建了一个自定义跟踪器,其中 FilePatternWatcher
对象保存在一个集合中,并且可能通过 FilePath
添加到集合中.这似乎适用于我的用例,但我不明白/不明白如何使用自定义 tryClaim
实现 @SplitRestriction
方法。
如果有人能够提供建议,我将不胜感激。我不喜欢任何特定的解决方案,只是希望能够在单个 RestrictionTracker
元素中维护一组实体,但并行化从 Google Cloud Storage (GCS) 获取这些实体的能力。>
解决方法
加入输出 PCollections 对您有帮助吗?
PCollectionList
.of(collectionOne)
.and(collectionTwo)
.and(collectionThree)
...
.apply(Flatten.pCollections())
Azure Blob Storage 基本用法 -- Azure Storage 之 Blob
Azure Storage 是微软 Azure 云提供的云端存储解决方案,当前支持的存储类型有 Blob、Queue、File 和 Table。
笔者在《Azure Table storage 基本用法》一文中,介绍了 Table Storage 的基本用法,本文将通过 C# 代码介绍 Blob Storage 的主要使用方法。
Blob Storage 是什么?
Azure Blob Storage 是用来存放大量的像文本、图片、视频等非结构化数据的存储服务。我们可以在任何地方通过互联网协议 http 或者 https 访问 Blob Storage。简单说,就是把文件放在云上,给它一个 URL,通过这个 URL 来访问文件。这就涉及到一个问题:如何控制访问权限?答案是我们可以根据自己的需要,设置 Blob 对象是只能被自己访问,还是可以被所有人访问。
下面是 Blog Storage 典型的应用场景:
- 存储图片和文档,这些文件可以直接通过浏览器访问。
- 支持分布式访问,主要用于 cdn。
- 提供视频、音频流。
- 存储基本的文件备份和归档文件。
Azure Blob Storage 的结构
下图描述了 Blob Storage 的基本组织结构:
- Azure Storage Account:
Storage Account 是用来管理 Azure Storage 的一个命名空间,主要用来控制存储数据的访问权限和计费。对于 Blob、Queue、File 和 Table 这些 Azure 提供的存储服务的访问控制,都是通过 Storage Account 来进行的,所以要想使用 Blob Storage,首先需要创建你的 Storage Account。
- Container:
Container 中包含一组资源,所有的 Blob 都必须存在于 Container 中。一个 Storage Account 中可以包含无限个 Container,每个 Container 中也可以包含无限个 Blob。需要注意的是 Container 的名字必须全部小写。
- Blob:
一个 Blob 就代表一个文件。为了区分应用的场景及提升不同应用场景下存储的性能,又为 Blob 划分了不同的类型:block blobs, page blobs,append blobs。
- Block blobs 主要用来存储静态的文件,比如图片、电影和文档。
- Append blobs 与 block blobs 类似,但优化了 append 操作,主要的应用场景是存储日志文件。
- Page blobs 针对频繁的读写操作做了优化,如 Azure 上虚拟机的磁盘,就是使用的 page blobs。
如果你还不熟悉 Azure Storage Account 的使用,以及如何通过 WindowsAzure.Storage 库访问 Azure Storage,请参考前文《Azure Table storage 基本用法》中的介绍。
为了方便查看 C# 代码执行的结果,本文使用了 MS 发布的一个 Azure Storage 客户端工具:Microsoft Azure Storage Explorer,文中简称为 Storage Explorer。
接下来我们直接通过 C# 代码来介绍如何操作 Blob Storage。
创建 Blob Container
由于任何一个 Blob 都必须包含在一个 Blob Container 中,所以我们第一步先创建一个名为 “picturecontainer” 的 Blob Container:
//CloudStorageAccount 类表示一个 Azure Storage Account,我们需要先创建它的实例,才能访问属于它的资源。 //注意连接字符串中的xxx和yyy,分别对应Access keys中的Storage account name 和 key。 CloudStorageAccount storageAccount = CloudStorageAccount.Parse("DefaultEndpointsProtocol=https;AccountName=xxx;AccountKey=yyy"); //CloudBlobClient 类是 Windows Azure Blob Service 客户端的逻辑表示,我们需要使用它来配置和执行对 Blob Storage 的操作。 CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient(); //CloudBlobContainer 表示一个 Blob Container 对象。 CloudBlobContainer container = blobClient.GetContainerReference("picturecontainer"); //如果不存在就创建名为 picturecontainer 的 Blob Container。 container.CreateIfNotExists();
执行上面的代码,然后打开 Storage Explorer,刷新一下,看到名为 “picturecontainer” 的 Blob Container 已经创建:
Container 名称规则
MSDN 上不厌其烦的描述 Blob Container 的名称规则,足以说明其重要性,本文试图以简要的文字进行描述:
- 以小写字母或数字开头,只能包含字母、数字和 dash (-)。
- 不能有连续的 dash (-),dash (-) 不能是第一个字符,也不能是最后一个字符。
- 所有字符小写,总长度为 3-63 字符。
违反任何一个规则,在创建 Blob Container 时都会受到 (400) Bad Request 错误。
上传 Blob 文件
我们上传一个文件到刚才创建的 Container 中:
//mypicture.png 为放在 container 中的 Blob 的名称。 //GetBlockBlobReference 方法获得一个 Block 类型的 Blob 对象的引用。 //您可以根据应用的需要,分别调用 GetBlobReference,GetAppendBlobReference 或 GetPageBlobReference 来创建不同类型的 Blob 对象。 CloudBlockBlob blockBlob = container.GetBlockBlobReference("mypicture.png"); using (var fileStream = System.IO.File.OpenRead(file)) { // 这是一个同步执行的方法 blockBlob.UploadFromStream(fileStream); }
在代码中我们通过调用刚才创建的 Container 对象 container 的 GetBlockBlobReference 方法,获得了一个 CloudBlockBlob 类型的对象。然后通过它的 UploadFromStream 方法把一个本地的文件上传到了云端。
刷新 Storage Explorer 看看上传的结果:
图片中显示文件已经上传成功!
遍历 Container 中的内容
如果我们想要罗列出一个 Container 中的所有 Blob 对象,就需要对整个 Container 进行遍历操作:
foreach (IListBlobItem item in container.ListBlobs(null, false)) { if (item.GetType() == typeof(CloudBlockBlob)) { CloudBlockBlob blob = (CloudBlockBlob)item; // todo something } else if (item.GetType() == typeof(CloudAppendBlob)) { CloudAppendBlob appendBlob = (CloudAppendBlob)item; // todo something } else if (item.GetType() == typeof(CloudPageBlob)) { CloudPageBlob pageBlob = (CloudPageBlob)item; // todo something } else if (item.GetType() == typeof(CloudBlobDirectory)) { CloudBlobDirectory directory = (CloudBlobDirectory)item; // todo something } }
这段代码中有两处需要注意的地方:
- 获得的 Blob 对象是有类型的。
- 可以获得一个虚拟的目录信息,其实是对文件名称的解析。比如一个 Blob 的名称为 abc/flower.jpg,此时就能获得一个名叫 abc 的虚拟目录信息。
下载 Blob 文件
有上传自然要有下载,看看下载一个 Blob 对象的代码:
// 创建名称为 mypicture.png 的 Blob 对象的引用。 CloudBlockBlob blockBlob = container.GetBlockBlobReference("mypicture.png"); // 把文件保存到本地。 using (var fileStream = System.IO.File.OpenWrite(fileName)) { blockBlob.DownloadToStream(fileStream); }
Mypicture.png 被下载到本地指定的文件中。
设置 Blob 的访问权限
我们在本文开始的地方就强调可以通过 http 或 https 协议访问 Blob Storage 文件,现在我们就尝试一下。
在 Storage Explorer 中选择 mypicture.png,右键,选择 “Copy URL to Clipboard”。把 URL 粘贴到浏览器的地址栏中。
怎么回事?文件不存在吗?不是的,默认情况下,你的文件是被保护的,只有通过你的 Storage Account 验证后才能访问。如果想要把它设置为任何人都能访问,需要通过设置 Container 的权限来实现。
private static void SetPublicContainerPermissions(CloudBlobContainer container) { BlobContainerPermissions permissions = container.GetPermissions(); // Container 中的所有 Blob 都能被访问 permissions.PublicAccess = BlobContainerPublicAccessType.Container; container.SetPermissions(permissions); }
重新在浏览器中访问一次试试:
注意,针对上传文件的权限需要谨慎处理,个人文件不建议设置为任何人都能访问。
删除 Blob 文件
mypicture.png 已经完成了演示的使命,通过以下命令就可以删除它了:
CloudBlockBlob blockBlob = container.GetBlockBlobReference("mypicture.png"); blockBlob.Delete();
总结
Blob Storage 以其丰富的类型(block,append,page)为各类应用场景提供了最优的选择。本文仅仅是入门的介绍,更多的场景如用 Blob 存储设置 cdn ,如何对数据进行加密存储等内容都没有涉及。希望对刚接触 Azure 的朋友有所帮助。
Azure Blob 存储 - 如何在上传 Blob 后获取 Blob 存储 ID?
如何解决Azure Blob 存储 - 如何在上传 Blob 后获取 Blob 存储 ID?
我正在使用 C# 控制台应用程序 (.NET Core 3.1) 从 Azure Blob 存储读取大量图像文件并生成这些图像的缩略图。新图像将保存回 Azure,并将 Blob ID 存储在我们的数据库中。如何找到保存的项目的 ID。这是命令:
Azure.Response<BlobContentInfo> blobs = containerClient.UploadBlob(fileName,outStream);
我似乎在返回的对象中找不到它
https://docs.microsoft.com/en-us/dotnet/api/azure.storage.blobs.models.blobcontentinfo?view=azure-dotnet
我的原始图片是使用 PowerApps 创建和保存的,其中控件确实返回 Blob ID - 见下文:
Set(
gblSentBlob,AzureBlobStorage.CreateFile(
Text(gblAzureFileContainer),GUID() & ".jpg",camControl.Photo
)
);
If(
!IsEmpty(gblSentBlob),Notify("Picture saved to Azure storage:" & gblSentBlob.displayName);
UpdateContext({locFileName: gblSentBlob.displayName});
UpdateContext({locAzureStorageID: Text(gblSentBlob.Id)}); // <- *** this is the Blob ID ***
UpdateContext({locSavedToAzure: true});
这里,AzureBlobStorage.CreateFile 函数返回一个包含我要查找的 ID 的对象。
如何在我的控制台应用程序中获取此 ID。
典型的 Blob ID 如下所示:
JTJmc2hpcmVibG9iY29udGFpbmVyJTJmNTk3MzQ4NGYtNGVhNy00NzJkLTkyMzQtYWIwNzM5NWNlOGRiLmpwZw==
然后我可以使用以下(在 PowerApps 中)检索要显示的图像
AzureBlobStorage.GetFileContent(ThisItem.BlobStorageID)
我的完整代码:
var blobClient = containerClient.GetBlobClient(blobName);
using Stream stream = await blobClient.OpenReadAsync();
Image myImage = Image.FromStream(stream);
Image myThumbnail = PictureProcessor.returnThumbnail(myImage);
// Now save this image
string guid = Guid.NewGuid().ToString();
string fileName = guid + ".jpg";
//create a memory stream ready for the rescaled image
Stream outStream = new MemoryStream();
myThumbnail.Save(outStream,System.Drawing.Imaging.ImageFormat.Jpeg);
Console.WriteLine(
"Length = {0},Position = {1}\\n",outStream.Length.ToString(),outStream.Position.ToString());
outStream.Position = 0;
Azure.Response<BlobContentInfo> blobs = containerClient.UploadBlob(fileName,outStream);
Console.WriteLine("blobs RETURN OBJECT: " + blobs.ToString());
Console.WriteLine("blobs GetRawResponse: " + blobs.GetRawResponse());
Console.ReadKey();
解决方法
当我将其从 Base64 解码然后解码为 UTF-8 时:
JTJmc2hpcmVibG9iY29udGFpbmVyJTJmNTk3MzQ4NGYtNGVhNy00NzJkLTkyMzQtYWIwNzM5NWNlOGRiLmpwZw==
我明白了:
%2fshireblobcontainer%2f5973484f-4ea7-472d-9234-ab07395ce8db.jpg
因此,您的“Blob ID”似乎是您传入 AzureBlobStorage.CreateFile
的 URL 编码字符串值的 UTF-8(或 7 位 ASCII?)表示的 Base64 编码表示第二个参数。
这样做:
String powerAppsBlobId = @"JTJmc2hpcmVibG9iY29udGFpbmVyJTJmNTk3MzQ4NGYtNGVhNy00NzJkLTkyMzQtYWIwNzM5NWNlOGRiLmpwZw==";
Byte[] blobIdBytes = Convert.FromBase64String( powerAppsBlobId );
String urlEncodedBlobName = Encoding.UTF8.GetString( bytes );
String actualBlobName = Uri.UnescapeDataString( urlEncodedBlobName );
Console.WriteLine( actualBlobName )
这个程序会打印:
/shireblobcontainer/5973484f-4ea7-472d-9234-ab07395ce8db.jpg
,
在发布我的第一个答案(使用 Base64
解码)I took a look at the documentation for the Azure Blob connector for PowerApps 后,我发现 BlobMetadata.Name
和/或 BlobMetadata.Path
值也应该包含完整的 blob 名称.
我不知道你为什么指出 Azure.Storage.Blobs.Models
的文档,因为它不是供 PowerApps 使用的。
因此,更好的主意是在您从 PowerApps 中上传 blob 时存储 Blob.MetadataPath
值,以便您的控制台应用程序可以访问它 - 这是以防 PowerApps 更改其生成这些 Base64 的“算法” BlobId(例如,它们可以包含 Blob 版本日期+时间或共享访问签名)。
把你的代码改成这样:
Set(
gblSentBlob,AzureBlobStorage.CreateFile(
Text(gblAzureFileContainer),GUID() & ".jpg",camControl.Photo
)
);
If(
!IsEmpty(gblSentBlob),Notify("Picture saved to Azure storage:" & gblSentBlob.DisplayName);
UpdateContext({locFileName: gblSentBlob.DisplayName});
UpdateContext({locAzureStorageID: Text(gblSentBlob.Id)});
UpdateContext({locAzureStoragePath: Text(gblSentBlob.Path)}); // <--- Add this here
UpdateContext({locSavedToAzure: true});
Azure Blob 存储中的文件 ID [AZURE-BLOB]
如何解决Azure Blob 存储中的文件 ID [AZURE-BLOB]
Azure Blob 存储中是否有诸如修改时间、创建时间之类的文件 ID 之类的字段?它可用于唯一标识除名称之外的文件。 链接 here 中没有提到这样的事情。
解决方法
没有。您可以使用 blob 的 URL 作为唯一标识符。
,是的,你可以通过这个rest API得到modified_time
creation_time
:get blob property在响应头中的key:Last-Modified
和x-ms-creation-time
:
Azure 存储 blob 没有 FileID 作为标识符,正如@GauravMantri 提到的,Azure 使用 blob 的 URL 作为它的唯一标识符。
但如果您需要一个文件 ID,您可以通过 metadata 将其设置为 this API,并根据您设置的元数据过滤 blob。
关于同一映像的 Oracle Blob 二进制文件不同的介绍已经告一段落,感谢您的耐心阅读,如果想了解更多关于Apache Beam - 在保持 Blob 分组的同时并行化 Google Cloud Storage Blob 下载、Azure Blob Storage 基本用法 -- Azure Storage 之 Blob、Azure Blob 存储 - 如何在上传 Blob 后获取 Blob 存储 ID?、Azure Blob 存储中的文件 ID [AZURE-BLOB]的相关信息,请在本站寻找。
本文标签: