don't overwrite existing files when converting images/audio.

This commit is contained in:
morkt 2015-08-03 22:33:00 +04:00
parent 54d8d1cd86
commit 3a293baeea
2 changed files with 44 additions and 6 deletions

View File

@ -173,7 +173,7 @@ namespace GARbro.GUI
if (source_ext == source_format) if (source_ext == source_format)
return; return;
string output_name = Path.ChangeExtension (filename, source_format); 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.Position = 0;
input.Source.CopyTo (output); input.Source.CopyTo (output);
@ -184,7 +184,7 @@ namespace GARbro.GUI
if (source_ext == "wav") if (source_ext == "wav")
return; return;
string output_name = Path.ChangeExtension (filename, "wav"); string output_name = Path.ChangeExtension (filename, "wav");
using (var output = File.Create (output_name)) using (var output = CreateNewFile (output_name))
WavFormat.Write (input, output); WavFormat.Write (input, output);
} }
} }
@ -204,7 +204,7 @@ namespace GARbro.GUI
return; return;
try try
{ {
using (var output = File.Create (target_name)) using (var output = CreateNewFile (target_name))
m_image_format.Write (output, image); m_image_format.Write (output, image);
} }
catch // delete destination file on conversion failure catch // delete destination file on conversion failure
@ -215,6 +215,31 @@ namespace GARbro.GUI
} }
} }
/// <summary>
/// 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.
/// <exception cref="System.IOException">Throws exception after 100th failed attempt.</exception>
/// </summary>
public static Stream CreateNewFile (string filename)
{
string name = filename;
var ext = new Lazy<string> (() => 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) void OnConvertComplete (object sender, RunWorkerCompletedEventArgs e)
{ {
m_main.ResumeWatchDirectoryChanges(); m_main.ResumeWatchDirectoryChanges();

View File

@ -305,7 +305,7 @@ namespace GARbro.GUI
throw new InvalidFormatException (string.Format ("{1}: {0}", guiStrings.MsgUnableInterpretImage, entry.Name)); throw new InvalidFormatException (string.Format ("{1}: {0}", guiStrings.MsgUnableInterpretImage, entry.Name));
file.Position = 0; file.Position = 0;
string target_ext = target_format.Extensions.First(); 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) if (src_format.Item1 == target_format)
{ {
// source format is the same as a target, copy file as is // source format is the same as a target, copy file as is
@ -371,7 +371,7 @@ namespace GARbro.GUI
string source_format = input.SourceFormat; string source_format = input.SourceFormat;
if (GarConvertMedia.CommonAudioFormats.Contains (source_format)) 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)) using (var output = ArchiveFormat.CreateFile (output_name))
{ {
input.Source.Position = 0; input.Source.Position = 0;
@ -380,12 +380,25 @@ namespace GARbro.GUI
} }
else else
{ {
string output_name = Path.ChangeExtension (entry_name, "wav"); string output_name = FindUniqueFileName (entry_name, "wav");
using (var output = ArchiveFormat.CreateFile (output_name)) using (var output = ArchiveFormat.CreateFile (output_name))
GarConvertMedia.WavFormat.Write (input, output); 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) void OnExtractComplete (object sender, RunWorkerCompletedEventArgs e)
{ {
m_extract_in_progress = false; m_extract_in_progress = false;