@@ -167,24 +167,21 @@ static async Task ConvertFiles(string apiToken, string fromFormat, string toForm
167167
168168 var boundary = HeaderUtilities . RemoveQuotes ( response . Content . Headers . ContentType . Parameters . First ( p => p . Name == "boundary" ) . Value ) . Value ;
169169 var multipartReader = new MultipartReader ( boundary , await response . Content . ReadAsStreamAsync ( ) ) ;
170- MultipartSection section ;
171- int fileIndex = 1 ;
172170
173- while ( ( section = await multipartReader . ReadNextSectionAsync ( ) ) != null )
171+ while ( await multipartReader . ReadNextSectionAsync ( ) is { } section )
174172 {
175173 if ( Microsoft . Net . Http . Headers . ContentDispositionHeaderValue . TryParse ( section . ContentDisposition , out var contentDisposition ) &&
176174 ( contentDisposition . FileName != null || contentDisposition . FileNameStar . HasValue ) )
177175 {
178176 var fileName = contentDisposition . FileNameStar . HasValue ? contentDisposition . FileNameStar . Value : contentDisposition . FileName . Value . Trim ( '"' ) ;
179- var filePath = Directory . Exists ( outputPath ) ? Path . Combine ( outputPath , fileName ) : Path . Combine ( Path . GetDirectoryName ( outputPath ) , fileName ) ;
177+ var outputFilePath = GenerateOutputFilePath ( outputPath , fileName ) ;
180178
181- using ( var fileStream = new FileStream ( filePath , FileMode . Create , FileAccess . Write , FileShare . None ) )
179+ await using ( var fileStream = new FileStream ( outputFilePath , FileMode . Create , FileAccess . Write , FileShare . None ) )
182180 {
183181 await section . Body . CopyToAsync ( fileStream ) ;
184182 }
185183
186- Console . WriteLine ( $ "File saved: { filePath } ") ;
187- fileIndex ++ ;
184+ Console . WriteLine ( $ "File saved: { outputFilePath } ") ;
188185 }
189186 }
190187 }
@@ -197,6 +194,38 @@ static async Task ConvertFiles(string apiToken, string fromFormat, string toForm
197194 }
198195 }
199196
197+ private static string GenerateOutputFilePath ( string outputPath , string fileName )
198+ {
199+ // Determine if outputPath is a directory
200+ var isDir = outputPath . EndsWith ( Path . DirectorySeparatorChar ) ||
201+ outputPath . EndsWith ( Path . AltDirectorySeparatorChar ) ||
202+ Directory . Exists ( outputPath ) ||
203+ ! Path . HasExtension ( outputPath ) ;
204+
205+ var filePath = ! isDir ? outputPath : Path . Combine ( outputPath , fileName ) ;
206+ return GetAvailableFilePath ( filePath ) ;
207+ }
208+
209+ private static string GetAvailableFilePath ( string filePath )
210+ {
211+ if ( ! File . Exists ( filePath ) )
212+ return filePath ;
213+
214+ var directory = Path . GetDirectoryName ( filePath ) ;
215+ var fileNameWithoutExtension = Path . GetFileNameWithoutExtension ( filePath ) ;
216+ var extension = Path . GetExtension ( filePath ) ;
217+ var counter = 1 ;
218+
219+ string newFilePath ;
220+ do
221+ {
222+ newFilePath = Path . Combine ( directory , $ "{ fileNameWithoutExtension } ({ counter } ){ extension } ") ;
223+ counter ++ ;
224+ } while ( File . Exists ( newFilePath ) ) ;
225+
226+ return newFilePath ;
227+ }
228+
200229 private static void AddFilesToFormParameters ( MultipartFormDataContent form , string parameterName , string filePath )
201230 {
202231 form . Add ( new StreamContent ( File . OpenRead ( filePath ) )
0 commit comments