diff --git a/GarConvert.cs b/GarConvert.cs index b0f57ef6..2c076c8a 100644 --- a/GarConvert.cs +++ b/GarConvert.cs @@ -173,7 +173,7 @@ namespace GARbro.GUI if (source_ext == source_format) return; string output_name = Path.ChangeExtension (filename, source_format); - using (var output = File.Create (output_name)) + using (var output = CreateNewFile (output_name)) { input.Source.Position = 0; input.Source.CopyTo (output); @@ -184,7 +184,7 @@ namespace GARbro.GUI if (source_ext == "wav") return; string output_name = Path.ChangeExtension (filename, "wav"); - using (var output = File.Create (output_name)) + using (var output = CreateNewFile (output_name)) WavFormat.Write (input, output); } } @@ -204,7 +204,7 @@ namespace GARbro.GUI return; try { - using (var output = File.Create (target_name)) + using (var output = CreateNewFile (target_name)) m_image_format.Write (output, image); } catch // delete destination file on conversion failure @@ -215,6 +215,31 @@ namespace GARbro.GUI } } + /// + /// Creates new file with specified filename, or, if it's already exists, tries to open + /// files named "FILENAME.1.EXT", "FILENAME.2.EXT" and so on. + /// Throws exception after 100th failed attempt. + /// + + public static Stream CreateNewFile (string filename) + { + string name = filename; + var ext = new Lazy (() => Path.GetExtension (filename)); + for (int attempt = 1; ; ++attempt) + { + try + { + return File.Open (name, FileMode.CreateNew); + } + catch (IOException) // file already exists + { + if (100 == attempt) // limit number of attempts + throw; + } + name = Path.ChangeExtension (filename, attempt.ToString()+ext.Value); + } + } + void OnConvertComplete (object sender, RunWorkerCompletedEventArgs e) { m_main.ResumeWatchDirectoryChanges(); diff --git a/GarExtract.cs b/GarExtract.cs index a2a44436..5365d085 100644 --- a/GarExtract.cs +++ b/GarExtract.cs @@ -305,7 +305,7 @@ namespace GARbro.GUI throw new InvalidFormatException (string.Format ("{1}: {0}", guiStrings.MsgUnableInterpretImage, entry.Name)); file.Position = 0; string target_ext = target_format.Extensions.First(); - string outname = Path.ChangeExtension (entry.Name, target_ext); + string outname = FindUniqueFileName (entry.Name, target_ext); if (src_format.Item1 == target_format) { // source format is the same as a target, copy file as is @@ -371,7 +371,7 @@ namespace GARbro.GUI string source_format = input.SourceFormat; if (GarConvertMedia.CommonAudioFormats.Contains (source_format)) { - string output_name = Path.ChangeExtension (entry_name, source_format); + string output_name = FindUniqueFileName (entry_name, source_format); using (var output = ArchiveFormat.CreateFile (output_name)) { input.Source.Position = 0; @@ -380,12 +380,25 @@ namespace GARbro.GUI } else { - string output_name = Path.ChangeExtension (entry_name, "wav"); + string output_name = FindUniqueFileName (entry_name, "wav"); using (var output = ArchiveFormat.CreateFile (output_name)) GarConvertMedia.WavFormat.Write (input, output); } } + public static string FindUniqueFileName (string source_filename, string target_ext) + { + string ext = target_ext; + for (int attempt = 1; attempt < 100; ++attempt) + { + string filename = Path.ChangeExtension (source_filename, ext); + if (!File.Exists (filename)) + return filename; + ext = string.Format ("{0}.{1}", attempt, target_ext); + } + throw new IOException ("File aready exists"); + } + void OnExtractComplete (object sender, RunWorkerCompletedEventArgs e) { m_extract_in_progress = false;