mirror of
https://github.com/jellyfin/jellyfin.git
synced 2026-03-17 23:56:44 +00:00
Use async FileStreams where it makes sense
This commit is contained in:
@@ -815,7 +815,7 @@ namespace Emby.Server.Implementations.Channels
|
||||
{
|
||||
if (_fileSystem.GetLastWriteTimeUtc(cachePath).Add(cacheLength) > DateTime.UtcNow)
|
||||
{
|
||||
await using FileStream jsonStream = File.OpenRead(cachePath);
|
||||
await using FileStream jsonStream = AsyncFile.OpenRead(cachePath);
|
||||
var cachedResult = await JsonSerializer.DeserializeAsync<ChannelItemResult>(jsonStream, _jsonOptions, cancellationToken).ConfigureAwait(false);
|
||||
if (cachedResult != null)
|
||||
{
|
||||
@@ -838,7 +838,7 @@ namespace Emby.Server.Implementations.Channels
|
||||
{
|
||||
if (_fileSystem.GetLastWriteTimeUtc(cachePath).Add(cacheLength) > DateTime.UtcNow)
|
||||
{
|
||||
await using FileStream jsonStream = File.OpenRead(cachePath);
|
||||
await using FileStream jsonStream = AsyncFile.OpenRead(cachePath);
|
||||
var cachedResult = await JsonSerializer.DeserializeAsync<ChannelItemResult>(jsonStream, _jsonOptions, cancellationToken).ConfigureAwait(false);
|
||||
if (cachedResult != null)
|
||||
{
|
||||
|
||||
@@ -248,7 +248,7 @@ namespace Emby.Server.Implementations.IO
|
||||
{
|
||||
try
|
||||
{
|
||||
using (Stream thisFileStream = File.OpenRead(fileInfo.FullName))
|
||||
using (Stream thisFileStream = new FileStream(fileInfo.FullName, FileMode.Open, FileAccess.Read, FileShare.Read, 1))
|
||||
{
|
||||
result.Length = thisFileStream.Length;
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ using MediaBrowser.Controller.MediaEncoding;
|
||||
using MediaBrowser.Model.Dlna;
|
||||
using MediaBrowser.Model.Dto;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.IO;
|
||||
using MediaBrowser.Model.MediaInfo;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
@@ -49,7 +50,7 @@ namespace Emby.Server.Implementations.Library
|
||||
{
|
||||
try
|
||||
{
|
||||
await using FileStream jsonStream = File.OpenRead(cacheFilePath);
|
||||
await using FileStream jsonStream = AsyncFile.OpenRead(cacheFilePath);
|
||||
mediaInfo = await JsonSerializer.DeserializeAsync<MediaInfo>(jsonStream, _jsonOptions, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
// _logger.LogDebug("Found cached media info");
|
||||
@@ -86,7 +87,7 @@ namespace Emby.Server.Implementations.Library
|
||||
if (cacheFilePath != null)
|
||||
{
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(cacheFilePath));
|
||||
await using FileStream createStream = File.OpenWrite(cacheFilePath);
|
||||
await using FileStream createStream = AsyncFile.OpenWrite(cacheFilePath);
|
||||
await JsonSerializer.SerializeAsync(createStream, mediaInfo, _jsonOptions, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
// _logger.LogDebug("Saved media info to {0}", cacheFilePath);
|
||||
|
||||
@@ -638,7 +638,7 @@ namespace Emby.Server.Implementations.Library
|
||||
{
|
||||
try
|
||||
{
|
||||
await using FileStream jsonStream = File.OpenRead(cacheFilePath);
|
||||
await using FileStream jsonStream = AsyncFile.OpenRead(cacheFilePath);
|
||||
mediaInfo = await JsonSerializer.DeserializeAsync<MediaInfo>(jsonStream, _jsonOptions, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
// _logger.LogDebug("Found cached media info");
|
||||
|
||||
@@ -46,7 +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))
|
||||
using (var output = new FileStream(targetFile, FileMode.Create, FileAccess.Write, FileShare.None, IODefaults.FileStreamBufferSize, AsyncFile.UseAsyncIO))
|
||||
{
|
||||
onStarted();
|
||||
|
||||
@@ -72,7 +72,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);
|
||||
await using var output = new FileStream(targetFile, FileMode.Create, FileAccess.Write, FileShare.None, IODefaults.CopyToBufferSize, AsyncFile.UseAsyncIO);
|
||||
|
||||
onStarted();
|
||||
|
||||
|
||||
@@ -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, true);
|
||||
_logFileStream = new FileStream(logFilePath, FileMode.Create, FileAccess.Write, FileShare.Read, IODefaults.FileStreamBufferSize, AsyncFile.UseAsyncIO);
|
||||
|
||||
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);
|
||||
|
||||
@@ -81,7 +81,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings
|
||||
|
||||
using var response = await _httpClientFactory.CreateClient(NamedClient.Default).GetAsync(path, cancellationToken).ConfigureAwait(false);
|
||||
await using var stream = await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false);
|
||||
await using (var fileStream = new FileStream(cacheFile, FileMode.CreateNew))
|
||||
await using (var fileStream = new FileStream(cacheFile, FileMode.CreateNew, FileAccess.Write, FileShare.None, IODefaults.CopyToBufferSize, AsyncFile.UseAsyncIO))
|
||||
{
|
||||
await stream.CopyToAsync(fileStream, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
@@ -92,7 +92,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
|
||||
try
|
||||
{
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(channelCacheFile));
|
||||
await using var writeStream = File.OpenWrite(channelCacheFile);
|
||||
await using var writeStream = AsyncFile.OpenWrite(channelCacheFile);
|
||||
await JsonSerializer.SerializeAsync(writeStream, channels, cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
catch (IOException)
|
||||
@@ -108,7 +108,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
|
||||
{
|
||||
try
|
||||
{
|
||||
await using var readStream = File.OpenRead(channelCacheFile);
|
||||
await using var readStream = AsyncFile.OpenRead(channelCacheFile);
|
||||
var channels = await JsonSerializer.DeserializeAsync<List<ChannelInfo>>(readStream, cancellationToken: cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
list.AddRange(channels);
|
||||
|
||||
@@ -155,15 +155,13 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
|
||||
using var linkedCancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, LiveStreamCancellationTokenSource.Token);
|
||||
cancellationToken = linkedCancellationTokenSource.Token;
|
||||
|
||||
// use non-async filestream on windows along with read due to https://github.com/dotnet/corefx/issues/6039
|
||||
var allowAsync = Environment.OSVersion.Platform != PlatformID.Win32NT;
|
||||
|
||||
bool seekFile = (DateTime.UtcNow - DateOpened).TotalSeconds > 10;
|
||||
|
||||
var nextFileInfo = GetNextFile(null);
|
||||
var nextFile = nextFileInfo.file;
|
||||
var isLastFile = nextFileInfo.isLastFile;
|
||||
|
||||
var allowAsync = AsyncFile.UseAsyncIO;
|
||||
while (!string.IsNullOrEmpty(nextFile))
|
||||
{
|
||||
var emptyReadLimit = isLastFile ? EmptyReadLimit : 1;
|
||||
|
||||
@@ -14,6 +14,7 @@ using Jellyfin.Extensions;
|
||||
using MediaBrowser.Common.Extensions;
|
||||
using MediaBrowser.Common.Net;
|
||||
using MediaBrowser.Controller.LiveTv;
|
||||
using MediaBrowser.Model.IO;
|
||||
using MediaBrowser.Model.LiveTv;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
@@ -50,7 +51,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
|
||||
|
||||
if (!info.Url.StartsWith("http", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return File.OpenRead(info.Url);
|
||||
return AsyncFile.OpenRead(info.Url);
|
||||
}
|
||||
|
||||
using var requestMessage = new HttpRequestMessage(HttpMethod.Get, info.Url);
|
||||
|
||||
@@ -129,37 +129,39 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
|
||||
|
||||
private Task StartStreaming(HttpResponseMessage response, TaskCompletionSource<bool> openTaskCompletionSource, CancellationToken cancellationToken)
|
||||
{
|
||||
return Task.Run(async () =>
|
||||
{
|
||||
try
|
||||
return Task.Run(
|
||||
async () =>
|
||||
{
|
||||
Logger.LogInformation("Beginning {0} stream to {1}", GetType().Name, TempFilePath);
|
||||
using var message = response;
|
||||
await using var stream = await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false);
|
||||
await using var fileStream = new FileStream(TempFilePath, FileMode.Create, FileAccess.Write, FileShare.Read);
|
||||
await StreamHelper.CopyToAsync(
|
||||
stream,
|
||||
fileStream,
|
||||
IODefaults.CopyToBufferSize,
|
||||
() => Resolve(openTaskCompletionSource),
|
||||
cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
catch (OperationCanceledException ex)
|
||||
{
|
||||
Logger.LogInformation("Copying of {0} to {1} was canceled", GetType().Name, TempFilePath);
|
||||
openTaskCompletionSource.TrySetException(ex);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.LogError(ex, "Error copying live stream {0} to {1}.", GetType().Name, TempFilePath);
|
||||
openTaskCompletionSource.TrySetException(ex);
|
||||
}
|
||||
try
|
||||
{
|
||||
Logger.LogInformation("Beginning {0} stream to {1}", GetType().Name, TempFilePath);
|
||||
using var message = response;
|
||||
await using var stream = await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false);
|
||||
await using var fileStream = new FileStream(TempFilePath, FileMode.Create, FileAccess.Write, FileShare.Read, IODefaults.FileStreamBufferSize, AsyncFile.UseAsyncIO);
|
||||
await StreamHelper.CopyToAsync(
|
||||
stream,
|
||||
fileStream,
|
||||
IODefaults.CopyToBufferSize,
|
||||
() => Resolve(openTaskCompletionSource),
|
||||
cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
catch (OperationCanceledException ex)
|
||||
{
|
||||
Logger.LogInformation("Copying of {0} to {1} was canceled", GetType().Name, TempFilePath);
|
||||
openTaskCompletionSource.TrySetException(ex);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.LogError(ex, "Error copying live stream {0} to {1}.", GetType().Name, TempFilePath);
|
||||
openTaskCompletionSource.TrySetException(ex);
|
||||
}
|
||||
|
||||
openTaskCompletionSource.TrySetResult(false);
|
||||
openTaskCompletionSource.TrySetResult(false);
|
||||
|
||||
EnableStreamSharing = false;
|
||||
await DeleteTempFiles(new List<string> { TempFilePath }).ConfigureAwait(false);
|
||||
}, CancellationToken.None);
|
||||
EnableStreamSharing = false;
|
||||
await DeleteTempFiles(new List<string> { TempFilePath }).ConfigureAwait(false);
|
||||
},
|
||||
CancellationToken.None);
|
||||
}
|
||||
|
||||
private void Resolve(TaskCompletionSource<bool> openTaskCompletionSource)
|
||||
|
||||
@@ -15,6 +15,7 @@ using Jellyfin.Extensions.Json.Converters;
|
||||
using MediaBrowser.Common.Net;
|
||||
using MediaBrowser.Common.Plugins;
|
||||
using MediaBrowser.Model.Configuration;
|
||||
using MediaBrowser.Model.IO;
|
||||
using MediaBrowser.Model.Plugins;
|
||||
using MediaBrowser.Model.Updates;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
@@ -371,7 +372,7 @@ namespace Emby.Server.Implementations.Plugins
|
||||
var url = new Uri(packageInfo.ImageUrl);
|
||||
imagePath = Path.Join(path, url.Segments[^1]);
|
||||
|
||||
await using var fileStream = File.OpenWrite(imagePath);
|
||||
await using var fileStream = AsyncFile.OpenWrite(imagePath);
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
@@ -72,7 +72,7 @@ namespace Emby.Server.Implementations.Serialization
|
||||
/// <param name="file">The file.</param>
|
||||
public void SerializeToFile(object obj, string file)
|
||||
{
|
||||
using (var stream = new FileStream(file, FileMode.Create))
|
||||
using (var stream = new FileStream(file, FileMode.Create, FileAccess.Write))
|
||||
{
|
||||
SerializeToStream(obj, stream);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user