diff --git a/Source/Core/Data/PK3Reader.cs b/Source/Core/Data/PK3Reader.cs index 329ea67..18db05f 100644 --- a/Source/Core/Data/PK3Reader.cs +++ b/Source/Core/Data/PK3Reader.cs @@ -37,6 +37,7 @@ namespace CodeImp.DoomBuilder.Data private readonly ArchiveType archivetype; //mxd private readonly Dictionary sevenzipentries; //mxd private bool bathmode = true; //mxd + private FileStream filestream; #endregion @@ -51,6 +52,9 @@ namespace CodeImp.DoomBuilder.Data // Constructor public PK3Reader(DataLocation dl) : base(dl) { + FileAccess access = FileAccess.Read; + FileShare share = FileShare.ReadWrite; + General.WriteLogLine("Opening " + Path.GetExtension(location.location).ToUpper().Replace(".", "") + " resource '" + location.location + "'"); if(!File.Exists(location.location)) @@ -59,8 +63,11 @@ namespace CodeImp.DoomBuilder.Data // Make list of all files List fileentries = new List(); + // Take the detour with a FileStream because SharpCompress doesn't directly support opening files as read-only + filestream = File.Open(location.location, FileMode.OpenOrCreate, access, share); + // Create archive - archive = ArchiveFactory.Open(location.location, Options.KeepStreamsOpen); + archive = ArchiveFactory.Open(filestream); archivetype = archive.Type; // Random access of 7z archives works TERRIBLY slow in SharpCompress @@ -92,6 +99,9 @@ namespace CodeImp.DoomBuilder.Data archive.Dispose(); archive = null; + filestream.Dispose(); + filestream = null; + // Make files list files = new DirectoryFilesList(fileentries); @@ -117,6 +127,12 @@ namespace CodeImp.DoomBuilder.Data archive = null; } + if (filestream != null) + { + filestream.Dispose(); + filestream = null; + } + // Done base.Dispose(); } @@ -129,12 +145,25 @@ namespace CodeImp.DoomBuilder.Data if(enable && archive == null) { - archive = ArchiveFactory.Open(location.location); + FileAccess access = FileAccess.Read; + FileShare share = FileShare.ReadWrite; + + // The file might have vanished in the meantime + if (!File.Exists(location.location)) + throw new FileNotFoundException("Could not find the file \"" + location.location + "\"", location.location); + + // Take the detour with a FileStream because SharpCompress doesn't directly support opening files as read-only + filestream = File.Open(location.location, FileMode.OpenOrCreate, access, share); + + archive = ArchiveFactory.Open(filestream); } else if(!enable && !bathmode && archive != null) { archive.Dispose(); archive = null; + + filestream.Dispose(); + filestream = null; } }