diff --git a/OpenRA.Game/FileSystem/MixFile.cs b/OpenRA.Game/FileSystem/MixFile.cs index 7a36fb7e15..8a8f7b0d6e 100644 --- a/OpenRA.Game/FileSystem/MixFile.cs +++ b/OpenRA.Game/FileSystem/MixFile.cs @@ -191,9 +191,22 @@ namespace OpenRA.FileSystem public Stream GetContent(PackageEntry entry) { Stream parentStream; - var offset = dataStart + entry.Offset + SegmentStream.GetOverallNestedOffset(s, out parentStream); - var path = ((FileStream)parentStream).Name; - return new SegmentStream(File.OpenRead(path), offset, entry.Length); + var baseOffset = dataStart + entry.Offset; + var nestedOffset = baseOffset + SegmentStream.GetOverallNestedOffset(s, out parentStream); + + // Special case FileStream - instead of creating an in-memory copy, + // just reference the portion of the on-disk file that we need to save memory. + // We use GetType instead of 'is' here since we can't handle any derived classes of FileStream. + if (parentStream.GetType() == typeof(FileStream)) + { + var path = ((FileStream)parentStream).Name; + return new SegmentStream(File.OpenRead(path), nestedOffset, entry.Length); + } + + // For all other streams, create a copy in memory. + // This uses more memory but is the only way in general to ensure the returned streams won't clash. + s.Seek(baseOffset, SeekOrigin.Begin); + return new MemoryStream(s.ReadBytes((int)entry.Length)); } public Stream GetStream(string filename)