11// Licensed to the .NET Foundation under one or more agreements.
22// The .NET Foundation licenses this file to you under the MIT license.
33
4- using System . Security . Cryptography ;
4+ using System . IO . Hashing ;
5+ using Aspire . Hosting . Utils ;
56
67namespace Aspire . Hosting . ApplicationModel ;
78
89internal sealed class AspireStore : IAspireStore
910{
11+ internal const string AspireStorePathKeyName = "Aspire:Store:Path" ;
12+
1013 private readonly string _basePath ;
1114
1215 /// <summary>
@@ -29,56 +32,38 @@ public AspireStore(string basePath)
2932
3033 public string BasePath => _basePath ;
3134
32- public string GetFileNameWithContent ( string filenameTemplate , string sourceFilename )
35+ public string GetFileNameWithContent ( string filenameTemplate , Stream contentStream )
3336 {
3437 ArgumentException . ThrowIfNullOrWhiteSpace ( filenameTemplate ) ;
35- ArgumentException . ThrowIfNullOrWhiteSpace ( sourceFilename ) ;
36-
37- if ( ! File . Exists ( sourceFilename ) )
38- {
39- throw new FileNotFoundException ( "The source file does not exist." , sourceFilename ) ;
40- }
38+ ArgumentNullException . ThrowIfNull ( contentStream ) ;
4139
4240 EnsureDirectory ( ) ;
4341
4442 // Strip any folder information from the filename.
4543 filenameTemplate = Path . GetFileName ( filenameTemplate ) ;
4644
47- var hashStream = File . OpenRead ( sourceFilename ) ;
45+ // Create a temporary file to write the content to.
46+ var tempFileName = Path . GetTempFileName ( ) ;
4847
49- // Compute the hash of the content .
50- var hash = SHA256 . HashData ( hashStream ) ;
48+ // Fast, non-cryptographic hash.
49+ var hash = new XxHash3 ( ) ;
5150
52- hashStream . Dispose ( ) ;
51+ // Write the content to the temporary file while also building a hash.
52+ using ( var fileStream = File . OpenWrite ( tempFileName ) )
53+ {
54+ using var digestStream = new HashDigestStream ( fileStream , hash ) ;
55+ contentStream . CopyTo ( digestStream ) ;
56+ }
5357
5458 var name = Path . GetFileNameWithoutExtension ( filenameTemplate ) ;
5559 var ext = Path . GetExtension ( filenameTemplate ) ;
56- var finalFilePath = Path . Combine ( _basePath , $ "{ name } .{ Convert . ToHexString ( hash ) [ ..12 ] . ToLowerInvariant ( ) } { ext } ") ;
60+ var finalFilePath = Path . Combine ( _basePath , $ "{ name } .{ Convert . ToHexString ( hash . GetCurrentHash ( ) ) [ ..12 ] . ToLowerInvariant ( ) } { ext } ") ;
5761
5862 if ( ! File . Exists ( finalFilePath ) )
5963 {
60- File . Copy ( sourceFilename , finalFilePath , overwrite : true ) ;
64+ File . Copy ( tempFileName , finalFilePath , overwrite : true ) ;
6165 }
6266
63- return finalFilePath ;
64- }
65-
66- public string GetFileNameWithContent ( string filenameTemplate , Stream contentStream )
67- {
68- ArgumentException . ThrowIfNullOrWhiteSpace ( filenameTemplate ) ;
69- ArgumentNullException . ThrowIfNull ( contentStream ) ;
70-
71- // Create a temporary file to write the content to.
72- var tempFileName = Path . GetTempFileName ( ) ;
73-
74- // Write the content to the temporary file.
75- using ( var fileStream = File . OpenWrite ( tempFileName ) )
76- {
77- contentStream . CopyTo ( fileStream ) ;
78- }
79-
80- var finalFilePath = GetFileNameWithContent ( filenameTemplate , tempFileName ) ;
81-
8267 try
8368 {
8469 File . Delete ( tempFileName ) ;
0 commit comments