浏览代码

Remove workaround for dotnet/runtime#42790

Bond_009 3 年之前
父节点
当前提交
9af16fcb6c

+ 6 - 3
Emby.Dlna/DlnaManager.cs

@@ -359,14 +359,17 @@ namespace Emby.Dlna
                 // The stream should exist as we just got its name from GetManifestResourceNames
                 using (var stream = _assembly.GetManifestResourceStream(name)!)
                 {
+                    var length = stream.Length;
                     var fileInfo = _fileSystem.GetFileInfo(path);
 
-                    if (!fileInfo.Exists || fileInfo.Length != stream.Length)
+                    if (!fileInfo.Exists || fileInfo.Length != length)
                     {
                         Directory.CreateDirectory(systemProfilesPath);
 
-                        // use FileShare.None as this bypasses dotnet bug dotnet/runtime#42790 .
-                        using (var fileStream = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.None, IODefaults.FileStreamBufferSize, FileOptions.Asynchronous))
+                        var fileOptions = AsyncFile.WriteOptions;
+                        fileOptions.Mode = FileMode.CreateNew;
+                        fileOptions.PreallocationSize = length;
+                        using (var fileStream = new FileStream(path, fileOptions))
                         {
                             await stream.CopyToAsync(fileStream).ConfigureAwait(false);
                         }

+ 1 - 1
Emby.Drawing/ImageProcessor.cs

@@ -102,7 +102,7 @@ namespace Emby.Drawing
         {
             var file = await ProcessImage(options).ConfigureAwait(false);
 
-            using (var fileStream = new FileStream(file.Item1, FileMode.Open, FileAccess.Read, FileShare.Read, IODefaults.FileStreamBufferSize, FileOptions.Asynchronous))
+            using (var fileStream = AsyncFile.OpenRead(file.Item1))
             {
                 await fileStream.CopyToAsync(toStream).ConfigureAwait(false);
             }

+ 4 - 5
Emby.Server.Implementations/AppBase/ConfigurationHelper.cs

@@ -41,20 +41,19 @@ namespace Emby.Server.Implementations.AppBase
             xmlSerializer.SerializeToStream(configuration, stream);
 
             // Take the object we just got and serialize it back to bytes
-            byte[] newBytes = stream.GetBuffer();
-            int newBytesLen = (int)stream.Length;
+            Span<byte> newBytes = stream.GetBuffer().AsSpan(0, (int)stream.Length);
 
             // If the file didn't exist before, or if something has changed, re-save
-            if (buffer == null || !newBytes.AsSpan(0, newBytesLen).SequenceEqual(buffer))
+            if (buffer == null || !newBytes.SequenceEqual(buffer))
             {
                 var directory = Path.GetDirectoryName(path) ?? throw new ArgumentException($"Provided path ({path}) is not valid.", nameof(path));
 
                 Directory.CreateDirectory(directory);
+
                 // Save it after load in case we got new items
-                // use FileShare.None as this bypasses dotnet bug dotnet/runtime#42790 .
                 using (var fs = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.None))
                 {
-                    fs.Write(newBytes, 0, newBytesLen);
+                    fs.Write(newBytes);
                 }
             }
 

+ 2 - 4
Emby.Server.Implementations/LiveTv/EmbyTV/DirectRecorder.cs

@@ -46,8 +46,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
         {
             Directory.CreateDirectory(Path.GetDirectoryName(targetFile) ?? throw new ArgumentException("Path can't be a root directory.", nameof(targetFile)));
 
-            // use FileShare.None as this bypasses dotnet bug dotnet/runtime#42790 .
-            using (var output = new FileStream(targetFile, FileMode.Create, FileAccess.Write, FileShare.None, IODefaults.FileStreamBufferSize, FileOptions.Asynchronous))
+            using (var output = new FileStream(targetFile, FileMode.CreateNew, FileAccess.Write, FileShare.Read, IODefaults.FileStreamBufferSize, FileOptions.Asynchronous))
             {
                 onStarted();
 
@@ -79,8 +78,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
 
             Directory.CreateDirectory(Path.GetDirectoryName(targetFile) ?? throw new ArgumentException("Path can't be a root directory.", nameof(targetFile)));
 
-            // use FileShare.None as this bypasses dotnet bug dotnet/runtime#42790 .
-            await using var output = new FileStream(targetFile, FileMode.Create, FileAccess.Write, FileShare.None, IODefaults.CopyToBufferSize, FileOptions.Asynchronous);
+            await using var output = new FileStream(targetFile, FileMode.CreateNew, FileAccess.Write, FileShare.Read, IODefaults.CopyToBufferSize, FileOptions.Asynchronous);
 
             onStarted();
 

+ 4 - 8
Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs

@@ -1848,14 +1848,12 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
                 return;
             }
 
-            // use FileShare.None as this bypasses dotnet bug dotnet/runtime#42790 .
-            using (var stream = new FileStream(nfoPath, FileMode.Create, FileAccess.Write, FileShare.None))
+            using (var stream = new FileStream(nfoPath, FileMode.CreateNew, FileAccess.Write, FileShare.None))
             {
                 var settings = new XmlWriterSettings
                 {
                     Indent = true,
-                    Encoding = Encoding.UTF8,
-                    CloseOutput = false
+                    Encoding = Encoding.UTF8
                 };
 
                 using (var writer = XmlWriter.Create(stream, settings))
@@ -1913,14 +1911,12 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
                 return;
             }
 
-            // use FileShare.None as this bypasses dotnet bug dotnet/runtime#42790 .
-            using (var stream = new FileStream(nfoPath, FileMode.Create, FileAccess.Write, FileShare.None))
+            using (var stream = new FileStream(nfoPath, FileMode.CreateNew, FileAccess.Write, FileShare.None))
             {
                 var settings = new XmlWriterSettings
                 {
                     Indent = true,
-                    Encoding = Encoding.UTF8,
-                    CloseOutput = false
+                    Encoding = Encoding.UTF8
                 };
 
                 var options = _config.GetNfoConfiguration();

+ 1 - 1
Emby.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs

@@ -94,7 +94,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
             Directory.CreateDirectory(Path.GetDirectoryName(logFilePath));
 
             // FFMpeg writes debug/error info to stderr. This is useful when debugging so let's put it in the log directory.
-            _logFileStream = new FileStream(logFilePath, FileMode.Create, FileAccess.Write, FileShare.Read, IODefaults.FileStreamBufferSize, FileOptions.Asynchronous);
+            _logFileStream = new FileStream(logFilePath, FileMode.CreateNew, FileAccess.Write, FileShare.Read, IODefaults.FileStreamBufferSize, FileOptions.Asynchronous);
 
             await JsonSerializer.SerializeAsync(_logFileStream, mediaSource, _jsonOptions, cancellationToken).ConfigureAwait(false);
             await _logFileStream.WriteAsync(Encoding.UTF8.GetBytes(Environment.NewLine + Environment.NewLine + commandLineLogMessage + Environment.NewLine + Environment.NewLine), cancellationToken).ConfigureAwait(false);

+ 0 - 31
Jellyfin.Api/Controllers/RemoteImageController.cs

@@ -183,36 +183,5 @@ namespace Jellyfin.Api.Controllers
         {
             return Path.Combine(_applicationPaths.CachePath, "remote-images", filename.Substring(0, 1), filename);
         }
-
-        /// <summary>
-        /// Downloads the image.
-        /// </summary>
-        /// <param name="url">The URL.</param>
-        /// <param name="urlHash">The URL hash.</param>
-        /// <param name="pointerCachePath">The pointer cache path.</param>
-        /// <returns>Task.</returns>
-        private async Task DownloadImage(Uri url, Guid urlHash, string pointerCachePath)
-        {
-            var httpClient = _httpClientFactory.CreateClient(NamedClient.Default);
-            using var response = await httpClient.GetAsync(url).ConfigureAwait(false);
-            if (response.Content.Headers.ContentType?.MediaType == null)
-            {
-                throw new ResourceNotFoundException(nameof(response.Content.Headers.ContentType));
-            }
-
-            var ext = response.Content.Headers.ContentType.MediaType.AsSpan().RightPart('/').ToString();
-            var fullCachePath = GetFullCachePath(urlHash + "." + ext);
-
-            var fullCacheDirectory = Path.GetDirectoryName(fullCachePath) ?? throw new ResourceNotFoundException($"Provided path ({fullCachePath}) is not valid.");
-            Directory.CreateDirectory(fullCacheDirectory);
-            // use FileShare.None as this bypasses dotnet bug dotnet/runtime#42790 .
-            await using var fileStream = new FileStream(fullCachePath, FileMode.Create, FileAccess.Write, FileShare.None, IODefaults.FileStreamBufferSize, FileOptions.Asynchronous);
-            await response.Content.CopyToAsync(fileStream).ConfigureAwait(false);
-
-            var pointerCacheDirectory = Path.GetDirectoryName(pointerCachePath) ?? throw new ArgumentException($"Provided path ({pointerCachePath}) is not valid.", nameof(pointerCachePath));
-            Directory.CreateDirectory(pointerCacheDirectory);
-            await System.IO.File.WriteAllTextAsync(pointerCachePath, fullCachePath, CancellationToken.None)
-                .ConfigureAwait(false);
-        }
     }
 }

+ 10 - 2
MediaBrowser.LocalMetadata/Savers/BaseXmlSaver.cs

@@ -113,11 +113,19 @@ namespace MediaBrowser.LocalMetadata.Savers
         {
             var directory = Path.GetDirectoryName(path) ?? throw new ArgumentException($"Provided path ({path}) is not valid.", nameof(path));
             Directory.CreateDirectory(directory);
+
             // On Windows, savint the file will fail if the file is hidden or readonly
             FileSystem.SetAttributes(path, false, false);
 
-            // use FileShare.None as this bypasses dotnet bug dotnet/runtime#42790 .
-            using (var filestream = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.None))
+            var fileStreamOptions = new FileStreamOptions()
+            {
+                Mode = FileMode.Create,
+                Access = FileAccess.Write,
+                Share = FileShare.None,
+                PreallocationSize = stream.Length
+            };
+
+            using (var filestream = new FileStream(path, fileStreamOptions))
             {
                 stream.CopyTo(filestream);
             }

+ 0 - 1
MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs

@@ -679,7 +679,6 @@ namespace MediaBrowser.MediaEncoding.Subtitles
 
             if (!string.Equals(text, newText, StringComparison.Ordinal))
             {
-                // use FileShare.None as this bypasses dotnet bug dotnet/runtime#42790 .
                 using (var fileStream = new FileStream(file, FileMode.Create, FileAccess.Write, FileShare.None, IODefaults.FileStreamBufferSize, FileOptions.Asynchronous))
                 using (var writer = new StreamWriter(fileStream, encoding))
                 {

+ 19 - 0
MediaBrowser.Model/IO/AsyncFile.cs

@@ -7,6 +7,25 @@ namespace MediaBrowser.Model.IO
     /// </summary>
     public static class AsyncFile
     {
+        /// <summary>
+        /// Gets the default <see cref="FileStreamOptions"/> for reading files async.
+        /// </summary>
+        public static FileStreamOptions ReadOptions => new FileStreamOptions()
+        {
+            Options = FileOptions.Asynchronous
+        };
+
+        /// <summary>
+        /// Gets the default <see cref="FileStreamOptions"/> for writing files async.
+        /// </summary>
+        public static FileStreamOptions WriteOptions => new FileStreamOptions()
+        {
+            Mode = FileMode.OpenOrCreate,
+            Access = FileAccess.Write,
+            Share = FileShare.None,
+            Options = FileOptions.Asynchronous
+        };
+
         /// <summary>
         /// Opens an existing file for reading.
         /// </summary>

+ 4 - 2
MediaBrowser.Providers/Manager/ImageSaver.cs

@@ -261,8 +261,10 @@ namespace MediaBrowser.Providers.Manager
 
                 _fileSystem.SetAttributes(path, false, false);
 
-                // use FileShare.None as this bypasses dotnet bug dotnet/runtime#42790 .
-                await using (var fs = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.None, IODefaults.FileStreamBufferSize, FileOptions.Asynchronous))
+                var fileStreamOptions = AsyncFile.WriteOptions;
+                fileStreamOptions.Mode = FileMode.Create;
+                fileStreamOptions.PreallocationSize = source.Length;
+                await using (var fs = new FileStream(path, fileStreamOptions))
                 {
                     await source.CopyToAsync(fs, cancellationToken).ConfigureAwait(false);
                 }

+ 1 - 1
MediaBrowser.Providers/Manager/ItemImageProvider.cs

@@ -163,7 +163,7 @@ namespace MediaBrowser.Providers.Manager
                                 {
                                     var mimeType = MimeTypes.GetMimeType(response.Path);
 
-                                    var stream = new FileStream(response.Path, FileMode.Open, FileAccess.Read, FileShare.Read, IODefaults.FileStreamBufferSize, FileOptions.Asynchronous);
+                                    var stream = AsyncFile.OpenRead(response.Path);
 
                                     await _providerManager.SaveImage(item, stream, mimeType, imageType, null, cancellationToken).ConfigureAwait(false);
                                 }

+ 1 - 2
MediaBrowser.Providers/Manager/ProviderManager.cs

@@ -210,8 +210,7 @@ namespace MediaBrowser.Providers.Manager
                 throw new ArgumentNullException(nameof(source));
             }
 
-            var fileStream = new FileStream(source, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
-
+            var fileStream = AsyncFile.OpenRead(source);
             return new ImageSaver(_configurationManager, _libraryMonitor, _fileSystem, _logger).SaveImage(item, fileStream, mimeType, type, imageIndex, saveLocallyWithMedia, cancellationToken);
         }
 

+ 5 - 2
MediaBrowser.Providers/Plugins/AudioDb/AudioDbAlbumProvider.cs

@@ -172,8 +172,11 @@ namespace MediaBrowser.Providers.Plugins.AudioDb
 
             using var response = await _httpClientFactory.CreateClient(NamedClient.Default).GetAsync(url, cancellationToken).ConfigureAwait(false);
             await using var stream = await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false);
-            // use FileShare.None as this bypasses dotnet bug dotnet/runtime#42790 .
-            await using var xmlFileStream = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.None, IODefaults.FileStreamBufferSize, FileOptions.Asynchronous);
+
+            var fileStreamOptions = AsyncFile.WriteOptions;
+            fileStreamOptions.Mode = FileMode.Create;
+            fileStreamOptions.PreallocationSize = stream.Length;
+            await using var xmlFileStream = new FileStream(path, fileStreamOptions);
             await stream.CopyToAsync(xmlFileStream, cancellationToken).ConfigureAwait(false);
         }
 

+ 4 - 2
MediaBrowser.Providers/Plugins/AudioDb/AudioDbArtistProvider.cs

@@ -154,8 +154,10 @@ namespace MediaBrowser.Providers.Plugins.AudioDb
 
             Directory.CreateDirectory(Path.GetDirectoryName(path));
 
-            // use FileShare.None as this bypasses dotnet bug dotnet/runtime#42790 .
-            await using var xmlFileStream = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.None, IODefaults.FileStreamBufferSize, FileOptions.Asynchronous);
+            var fileStreamOptions = AsyncFile.WriteOptions;
+            fileStreamOptions.Mode = FileMode.Create;
+            fileStreamOptions.PreallocationSize = stream.Length;
+            await using var xmlFileStream = new FileStream(path, fileStreamOptions);
             await stream.CopyToAsync(xmlFileStream, cancellationToken).ConfigureAwait(false);
         }
 

+ 2 - 5
MediaBrowser.Providers/Studios/StudiosImageProvider.cs

@@ -172,19 +172,16 @@ namespace MediaBrowser.Providers.Studios
 
         public IEnumerable<string> GetAvailableImages(string file)
         {
-            using var fileStream = new FileStream(file, FileMode.Open, FileAccess.Read, FileShare.Read);
+            using var fileStream = File.OpenRead(file);
             using var reader = new StreamReader(fileStream);
-            var lines = new List<string>();
 
             foreach (var line in reader.ReadAllLines())
             {
                 if (!string.IsNullOrWhiteSpace(line))
                 {
-                    lines.Add(line);
+                    yield return line;
                 }
             }
-
-            return lines;
         }
     }
 }

+ 4 - 2
MediaBrowser.Providers/Subtitles/SubtitleManager.cs

@@ -244,8 +244,10 @@ namespace MediaBrowser.Providers.Subtitles
                 {
                     Directory.CreateDirectory(Path.GetDirectoryName(savePath));
 
-                    // use FileShare.None as this bypasses dotnet bug dotnet/runtime#42790 .
-                    using var fs = new FileStream(savePath, FileMode.Create, FileAccess.Write, FileShare.None, FileStreamBufferSize, FileOptions.Asynchronous);
+                    var fileOptions = AsyncFile.WriteOptions;
+                    fileOptions.Mode = FileMode.CreateNew;
+                    fileOptions.PreallocationSize = stream.Length;
+                    using var fs = new FileStream(savePath, fileOptions);
                     await stream.CopyToAsync(fs).ConfigureAwait(false);
 
                     return;

+ 9 - 2
MediaBrowser.XbmcMetadata/Savers/BaseNfoSaver.cs

@@ -203,8 +203,15 @@ namespace MediaBrowser.XbmcMetadata.Savers
             // On Windows, saving the file will fail if the file is hidden or readonly
             FileSystem.SetAttributes(path, false, false);
 
-            // use FileShare.None as this bypasses dotnet bug dotnet/runtime#42790 .
-            using (var filestream = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.None))
+            var fileStreamOptions = new FileStreamOptions()
+            {
+                Mode = FileMode.Create,
+                Access = FileAccess.Write,
+                Share = FileShare.None,
+                PreallocationSize = stream.Length
+            };
+
+            using (var filestream = new FileStream(path, fileStreamOptions))
             {
                 stream.CopyTo(filestream);
             }