@@ -386,7 +386,11 @@ public async Task<List<BsonFileManagerModel>> ShareFile(string dbName, string bs
386386 await _db . subBytesToFolder ( dbName , entry . ParentId , entry . Size ) ;
387387 }
388388
389- await _db . checkAndSetDirectoryHasChild ( dbName , args . Files . FirstOrDefault ( ) . ParentId ) ;
389+ var firstFile = args . Files . FirstOrDefault ( ) ;
390+ if ( firstFile != null )
391+ {
392+ await _db . checkAndSetDirectoryHasChild ( dbName , firstFile . ParentId ) ;
393+ }
390394 return await GetFilesPath ( dbName , args . Path ) ;
391395 }
392396
@@ -1903,11 +1907,25 @@ private async Task<List<ExpandoObject>> AddChildRecords(string id, string parent
19031907 if ( path == "/" )
19041908 {
19051909 List < BsonFileManagerModel > Data = collectionName == null ? await _db . getAllFiles ( dbName ) : await _db . getAllFiles ( dbName , collectionName ) ;
1906- string ParentId = Data
1907- . Where ( x => string . IsNullOrEmpty ( x . ParentId ) )
1908- . Select ( x => x . Id ) . First ( ) ;
1909- response . CWD = Data
1910- . Where ( x => string . IsNullOrEmpty ( x . ParentId ) ) . First ( ) . toFileManagerContent ( ) ;
1910+
1911+ // Find root element (element with no ParentId)
1912+ var rootElement = Data . FirstOrDefault ( x => string . IsNullOrEmpty ( x . ParentId ) ) ;
1913+
1914+ if ( rootElement == null )
1915+ {
1916+ // No root element found, return empty response
1917+ response . CWD = new Syncfusion . Blazor . FileManager . FileManagerDirectoryContent
1918+ {
1919+ Name = "Root" ,
1920+ FilterPath = "/" ,
1921+ IsFile = false
1922+ } ;
1923+ response . Files = new List < Syncfusion . Blazor . FileManager . FileManagerDirectoryContent > ( ) ;
1924+ return response ;
1925+ }
1926+
1927+ string ParentId = rootElement . Id ;
1928+ response . CWD = rootElement . toFileManagerContent ( ) ;
19111929 response . Files = Data
19121930 . Where ( x => x . ParentId == ParentId ) . Select ( x => x . toFileManagerContent ( ) ) . ToList ( ) ;
19131931 }
@@ -2038,11 +2056,22 @@ private async Task SaveToFile(IBrowserFile file, string path)
20382056
20392057 private async Task < List < string > > splitFileStreamAsync ( string path , string name , int splitSize )
20402058 {
2059+ var originalFileInfo = new System . IO . FileInfo ( System . IO . Path . Combine ( path , name ) ) ;
2060+ long originalFileSize = originalFileInfo . Length ;
2061+
20412062 _logger . LogInformation ( "Starting file split - FileName: {FileName}, SizeMB: {SizeMB:F2}, SplitSizeMB: {SplitSizeMB}" ,
2042- name , new System . IO . FileInfo ( System . IO . Path . Combine ( path , name ) ) . Length / ( 1024.0 * 1024.0 ) , splitSize / ( 1024 * 1024 ) ) ;
2063+ name , originalFileSize / ( 1024.0 * 1024.0 ) , splitSize / ( 1024 * 1024 ) ) ;
2064+
20432065 int _gb = TelegramService . splitSizeGB ;
2066+ long partSize = ( long ) splitSize * _gb ; // Size of each part in bytes
2067+ int expectedParts = ( int ) Math . Ceiling ( ( double ) originalFileSize / partSize ) ;
2068+
2069+ // Check for existing split parts from a previous failed run
2070+ var existingParts = CheckExistingSplitParts ( path , name , originalFileSize , partSize , expectedParts ) ;
2071+
20442072 List < string > listPath = new List < string > ( ) ;
20452073 byte [ ] buffer = new byte [ splitSize ] ;
2074+
20462075 using ( FileStream fs = new FileStream ( System . IO . Path . Combine ( path , name ) , FileMode . Open , FileAccess . Read , FileShare . Read ) )
20472076 {
20482077 SplitModel sm = new SplitModel ( ) ;
@@ -2051,13 +2080,33 @@ private async Task<List<string>> splitFileStreamAsync(string path, string name,
20512080 sm . _transmitted = 0 ;
20522081 _tis . addToUploadList ( sm ) ;
20532082 int index = 1 ;
2083+
20542084 while ( fs . Position < fs . Length )
20552085 {
20562086 string partPath = System . IO . Path . Combine ( path , $ "({ index } )" + name ) ;
2087+
2088+ // Check if this part already exists and is valid
2089+ if ( existingParts . TryGetValue ( index , out var existingPartInfo ) && existingPartInfo . isValid )
2090+ {
2091+ _logger . LogInformation ( "Reusing existing split part {PartNumber}/{TotalParts} - Size: {SizeMB:F2} MB" ,
2092+ index , expectedParts , existingPartInfo . size / ( 1024.0 * 1024.0 ) ) ;
2093+
2094+ // Skip this part in the source file
2095+ fs . Position += existingPartInfo . size ;
2096+ listPath . Add ( partPath ) ;
2097+ sm . ProgressCallback ( fs . Position , fs . Length ) ;
2098+ index ++ ;
2099+ continue ;
2100+ }
2101+
2102+ // Delete existing invalid part if exists
20572103 if ( File . Exists ( partPath ) )
20582104 {
2105+ _logger . LogDebug ( "Deleting invalid existing part: {PartPath}" , partPath ) ;
20592106 File . Delete ( partPath ) ;
20602107 }
2108+
2109+ // Create new part
20612110 int gb = _gb ;
20622111 while ( fs . Position < fs . Length && gb > 0 )
20632112 {
@@ -2070,16 +2119,72 @@ private async Task<List<string>> splitFileStreamAsync(string path, string name,
20702119 sm . ProgressCallback ( fs . Position , fs . Length ) ;
20712120 }
20722121
2073-
2074- // await fs.CopyToAsync(fsPart, Convert.ToInt32(Math.Min(splitSize, fs.Length - fs.Position)));
20752122 listPath . Add ( partPath ) ;
20762123 index ++ ;
20772124 }
20782125 }
2079- _logger . LogInformation ( "File split completed - FileName: {FileName}, Parts: {PartsCount}" , name , listPath . Count ) ;
2126+
2127+ int reusedParts = existingParts . Count ( p => p . Value . isValid ) ;
2128+ _logger . LogInformation ( "File split completed - FileName: {FileName}, Parts: {PartsCount}, ReusedParts: {ReusedParts}" ,
2129+ name , listPath . Count , reusedParts ) ;
20802130 return listPath ;
20812131 }
20822132
2133+ /// <summary>
2134+ /// Checks for existing split parts from a previous failed run and validates their sizes
2135+ /// </summary>
2136+ private Dictionary < int , ( long size , bool isValid ) > CheckExistingSplitParts ( string path , string name , long originalFileSize , long partSize , int expectedParts )
2137+ {
2138+ var existingParts = new Dictionary < int , ( long size , bool isValid ) > ( ) ;
2139+
2140+ for ( int i = 1 ; i <= expectedParts ; i ++ )
2141+ {
2142+ string partPath = System . IO . Path . Combine ( path , $ "({ i } )" + name ) ;
2143+ if ( File . Exists ( partPath ) )
2144+ {
2145+ var partInfo = new System . IO . FileInfo ( partPath ) ;
2146+ long actualSize = partInfo . Length ;
2147+
2148+ // Calculate expected size for this part
2149+ long expectedSize ;
2150+ if ( i < expectedParts )
2151+ {
2152+ // Not the last part - should be full partSize
2153+ expectedSize = partSize ;
2154+ }
2155+ else
2156+ {
2157+ // Last part - calculate remaining size
2158+ expectedSize = originalFileSize - ( partSize * ( expectedParts - 1 ) ) ;
2159+ }
2160+
2161+ bool isValid = actualSize == expectedSize ;
2162+
2163+ existingParts [ i ] = ( actualSize , isValid ) ;
2164+
2165+ if ( isValid )
2166+ {
2167+ _logger . LogDebug ( "Found valid existing part {PartNumber}/{TotalParts} - Size: {SizeMB:F2} MB" ,
2168+ i , expectedParts , actualSize / ( 1024.0 * 1024.0 ) ) ;
2169+ }
2170+ else
2171+ {
2172+ _logger . LogWarning ( "Found invalid existing part {PartNumber}/{TotalParts} - Expected: {ExpectedMB:F2} MB, Actual: {ActualMB:F2} MB" ,
2173+ i , expectedParts , expectedSize / ( 1024.0 * 1024.0 ) , actualSize / ( 1024.0 * 1024.0 ) ) ;
2174+ }
2175+ }
2176+ }
2177+
2178+ if ( existingParts . Any ( ) )
2179+ {
2180+ int validCount = existingParts . Count ( p => p . Value . isValid ) ;
2181+ _logger . LogInformation ( "Found {TotalExisting} existing split parts, {ValidCount} are valid and will be reused" ,
2182+ existingParts . Count , validCount ) ;
2183+ }
2184+
2185+ return existingParts ;
2186+ }
2187+
20832188 private async Task mergeFileStreamAsync ( List < string > pathList , string destName )
20842189 {
20852190 _logger . LogInformation ( "Starting file merge - DestName: {DestName}, PartsCount: {PartsCount}" , destName , pathList . Count ) ;
0 commit comments