protected override async Task <FileMetadata> GetFileMetadataImplAsync(string path, FileMetadataGetFlags flags = FileMetadataGetFlags.DefaultAll, CancellationToken cancel = default) { FileMetadata physicalMetadata = await UnderlayFileSystem.GetFileMetadataAsync(path, flags, cancel); try { long headerOffset = 0; long physicalSize = physicalMetadata.Size; using (FileObject physicalFile = await UnderlayFileSystem.OpenAsync(path)) { byte[] bomRead = new byte[3]; Memory <byte> tmp = new byte[3]; if (await physicalFile.ReadRandomAsync(0, tmp, cancel) == tmp.Length) { if (tmp.Span.SequenceEqual(Str.BOM_UTF_8.Span)) { headerOffset = 3; } } physicalSize = await physicalFile.GetFileSizeAsync(true, cancel) - headerOffset; if (physicalSize >= 0) { physicalMetadata.Size = physicalSize; } } } catch { } return(physicalMetadata); }
protected override async Task <FileMetadata> GetFileMetadataImplAsync(string path, FileMetadataGetFlags flags = FileMetadataGetFlags.DefaultAll, CancellationToken cancel = default) { // Try physical file first try { return(await UnderlayFileSystem.GetFileMetadataAsync(path, flags, cancel)); } catch { } LargeFileSystem.ParsedPath[] physicalFiles = await GetPhysicalFileStateInternal(path, cancel); var lastFileParsed = physicalFiles.OrderBy(x => x.FileNumber).LastOrDefault(); if (lastFileParsed == null) { // File not found throw new IOException($"The file '{path}' not found."); } else { // Large file exists checked { FileMetadata ret = await UnderlayFileSystem.GetFileMetadataAsync(lastFileParsed.PhysicalFilePath, flags | FileMetadataGetFlags.NoSecurity | FileMetadataGetFlags.NoAlternateStream, cancel); long sizeOfLastFile = ret.Size; sizeOfLastFile = Math.Min(sizeOfLastFile, Params.MaxSinglePhysicalFileSize); long currentFileSize = lastFileParsed.FileNumber * Params.MaxSinglePhysicalFileSize + sizeOfLastFile; ret.Size = currentFileSize; ret.PhysicalSize = physicalFiles.Sum(x => x.PhysicalEntity !.PhysicalSize); ret.CreationTime = physicalFiles.Min(x => x.PhysicalEntity !.CreationTime); ret.LastWriteTime = physicalFiles.Max(x => x.PhysicalEntity !.LastWriteTime); ret.LastAccessTime = physicalFiles.Max(x => x.PhysicalEntity !.LastAccessTime); return(ret); } } }