不支持给定路径的格式,NotSupportedException

本文探讨了在生成文本文件时遇到的问题,特别是文件名中包含特殊符号导致的问题。文章指出,诸如“:/”等特殊符号不应出现在文件名中。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

生成文本文件时会遇到这样的问题,这样的问题主要在于文件路径后面跟着的文件名有关系,文件名的命名问题:文件名中不能出现特殊符号,例如:“: / \”等等这样的特殊符号;

转载于:https://www.cnblogs.com/lizhao/archive/2012/06/14/2549636.html

using CommunityToolkit.Maui.Core.Primitives; using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Net.Http.Headers; using System.Security.Cryptography; using System.Text; using System.Text.Json; using System.Threading; using System.Threading.Tasks; using static AIToy.Services.VideoService; namespace AIToy.Services { public interface IVideoService { Task DownloadVideoAsync(string url, string localPath, IProgress<double> progress, CancellationToken cancellationToken); Task PauseDownloadAsync(); Task ResumeDownloadAsync(); // 添加事件 event EventHandler<DownloadStateChangedEventArgs> StateChanged; event EventHandler<double> ProgressChanged; // 新增下载完成事件 public event EventHandler<string> DownloadCompleted; DownloadState CurrentState { get; } } // 定义下载状态枚举 public enum DownloadState { Idle, Downloading, Paused, Completed, Error, WaitingForRetry, WaitingForNetwork } // 断点续传元数据类 public class DownloadMetadata { public string Url { get; set; } public string TempFilePath { get; set; } public long RemoteSize { get; set; } public long DownloadedSize { get; set; } public string DestinationPath { get; set; } // 新增 } public class VideoService : IVideoService { private HttpClient _httpClient; private CancellationTokenSource _pauseTokenSource; // 公开可绑定的下载状态属性 public DownloadState _currentState = DownloadState.Idle; public DownloadState CurrentState { get => _currentState; private set { if (_currentState != value) { _currentState = value; StateChanged?.Invoke(this, new DownloadStateChangedEventArgs(_currentState)); } } } // 下载进度属性(0.0 - 1.0) private double _downloadProgress; public double DownloadProgress { get => _downloadProgress; private set { if (Math.Abs(_downloadProgress - value) > 0.01) { _downloadProgress = value; ProgressChanged?.Invoke(this, value); } } } public class DownloadStateChangedEventArgs : EventArgs { public DownloadState State { get; } public DownloadStateChangedEventArgs(DownloadState state) { State = state; } } // 状态变更事件(供前端订阅) public event EventHandler<DownloadStateChangedEventArgs> StateChanged; public event EventHandler<double> ProgressChanged; // 新增下载完成事件 public event EventHandler<string> DownloadCompleted; // 当前下载的元数据(用于续传) private DownloadMetadata _currentMetadata; public async Task DownloadVideoAsync(string url, string localPath, IProgress<double> progress, CancellationToken cancellationToken) { try { // 1. 初始化元数据(保留原有续传功能) _currentMetadata = new DownloadMetadata { Url = url, TempFilePath = Path.Combine(FileSystem.CacheDirectory, $"video_{ComputeUrlHash(url)}.tmp"), DestinationPath = localPath // 新增目标路径记录 }; // 2. 获取远程文件大小 _currentMetadata.RemoteSize = await GetRemoteFileSize(url); // 3. 检查本地临时文件(续传逻辑) if (File.Exists(_currentMetadata.TempFilePath)) { var fileInfo = new FileInfo(_currentMetadata.TempFilePath); _currentMetadata.DownloadedSize = fileInfo.Length; if (_currentMetadata.DownloadedSize == _currentMetadata.RemoteSize) { CompleteDownload(localPath); return; } } // 4. 开始断网续传下载 CurrentState = DownloadState.Downloading; await DownloadWithNetworkResilience(progress, cancellationToken); } catch (OperationCanceledException) { CurrentState = DownloadState.Paused; SaveMetadata(_currentMetadata); } catch (Exception ex) { CurrentState = DownloadState.Error; // 错误处理... } } private async Task DownloadWithResumeSupport(string url, string localPath, IProgress<double> progress, CancellationToken cancellationToken) { using var client = new HttpClient(); // 设置续传范围 if (_currentMetadata.DownloadedSize > 0) { client.DefaultRequestHeaders.Range = new RangeHeaderValue(_currentMetadata.DownloadedSize, null); } // 下载逻辑(与原始方法类似,但增加状态更新) using var response = await client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead, cancellationToken); response.EnsureSuccessStatusCode(); using var remoteStream = await response.Content.ReadAsStreamAsync(); using var localStream = new FileStream(_currentMetadata.TempFilePath, _currentMetadata.DownloadedSize > 0 ? FileMode.Append : FileMode.Create, FileAccess.Write); var buffer = new byte[8192]; int bytesRead; while ((bytesRead = await remoteStream.ReadAsync(buffer, 0, buffer.Length, cancellationToken)) > 0) { await localStream.WriteAsync(buffer, 0, bytesRead, cancellationToken); _currentMetadata.DownloadedSize += bytesRead; // 更新进度 double currentProgress = (double)_currentMetadata.DownloadedSize / _currentMetadata.RemoteSize; DownloadProgress = currentProgress; progress?.Report(currentProgress); } } // 断网续传核心方法 private async Task DownloadWithNetworkResilience( IProgress<double> progress, CancellationToken cancellationToken) { const int MAX_RETRIES = 5; int retryCount = 0; TimeSpan retryDelay = TimeSpan.FromSeconds(3); while (retryCount < MAX_RETRIES && !cancellationToken.IsCancellationRequested) { try { // 网络可用性检测[^1] if (!NetworkUtils.IsNetworkAvailable()) { CurrentState = DownloadState.WaitingForNetwork; await WaitForNetworkAsync(cancellationToken); } // 执行带续传功能的下载 await DownloadWithResumeSupport( _currentMetadata.Url, _currentMetadata.DestinationPath, progress, cancellationToken); // 下载完成后处理 CompleteDownload(_currentMetadata.DestinationPath); return; } catch (WebException ex) when (NetworkUtils.IsNetworkError(ex)) { retryCount++; CurrentState = DownloadState.WaitingForRetry; await Task.Delay(retryDelay, cancellationToken); retryDelay *= 2; // 指数退避策略 SaveMetadata(_currentMetadata); } } } private bool IsNetworkError(Exception ex) { return ex is HttpRequestException || ex is WebException || ex is TaskCanceledException; } private void MoveTempFileToDestination(string tempFilePath, string destPath) { // 确保目标目录存在 var destDir = Path.GetDirectoryName(destPath); if (!string.IsNullOrEmpty(destDir) && !Directory.Exists(destDir)) Directory.CreateDirectory(destDir); // 如果目标文件已存在,先删除(或者覆盖移动) if (File.Exists(destPath)) File.Delete(destPath); File.Move(tempFilePath, destPath); } public async Task PauseDownloadAsync() { _pauseTokenSource?.Cancel(); } public async Task ResumeDownloadAsync() { // 恢复逻辑需结合具体上下文实现 } // 获取服务器文件大小 private async Task<long> GetRemoteFileSize(string url) { using (var client = new HttpClient()) using (var response = await client.SendAsync( new HttpRequestMessage(HttpMethod.Head, url))) { response.EnsureSuccessStatusCode(); return response.Content.Headers.ContentLength ?? 0; } } // 生成URL的哈希值作为文件名 private string ComputeUrlHash(string url) { using var sha256 = SHA256.Create(); byte[] hashBytes = sha256.ComputeHash(Encoding.UTF8.GetBytes(url)); return BitConverter.ToString(hashBytes).Replace("-", "").Substring(0, 16); } // 网络工具类 public static class NetworkUtils { public static bool IsNetworkAvailable() { try { // 检测网络连接状态 return Connectivity.NetworkAccess == NetworkAccess.Internet; } catch { return false; } } public static bool IsNetworkError(WebException ex) { // 检查是否为网络相关错误 return ex.Status == WebExceptionStatus.ConnectFailure || ex.Status == WebExceptionStatus.ConnectionClosed || ex.Status == WebExceptionStatus.Timeout; } } // 保存元数据方法 private void SaveMetadata(DownloadMetadata metadata) { string metaPath = Path.Combine(FileSystem.CacheDirectory, "download_meta.json"); File.WriteAllText(metaPath, JsonSerializer.Serialize(metadata)); } // 下载完成处理(新增自动播放触发) private void CompleteDownload(string localPath) { // 移动临时文件到最终位置 MoveTempFileToDestination(_currentMetadata.TempFilePath, localPath); // 清理元数据 //ClearMetadata(); // 触发下载完成事件 DownloadCompleted?.Invoke(this, localPath); CurrentState = DownloadState.Completed; } // 新增:网络等待方法 private async Task WaitForNetworkAsync(CancellationToken cancellationToken) { var tcs = new TaskCompletionSource<bool>(); // 订阅网络状态变化 void OnConnectivityChanged(object sender, ConnectivityChangedEventArgs e) { if (e.NetworkAccess == NetworkAccess.Internet) { tcs.TrySetResult(true); } } Connectivity.ConnectivityChanged += OnConnectivityChanged; try { // 设置超时避免永久等待 using var timeoutCts = new CancellationTokenSource(TimeSpan.FromMinutes(5)); using var linkedCts = CancellationTokenSource.CreateLinkedTokenSource( cancellationToken, timeoutCts.Token); await tcs.Task.WaitAsync(linkedCts.Token); } finally { Connectivity.ConnectivityChanged -= OnConnectivityChanged; } } } } 结合上下文,帮我把以下恢复下载的代码补充完整public async Task ResumeDownloadAsync() { // 恢复逻辑需结合具体上下文实现 }
最新发布
08-06
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值