Skip to content

Commit

Permalink
Optimized file streams for read-only file systems
Browse files Browse the repository at this point in the history
  • Loading branch information
LTRData committed Dec 12, 2023
1 parent b088ce9 commit e2841b3
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 8 deletions.
2 changes: 1 addition & 1 deletion Library/DiscUtils.Ntfs/Internals/MasterFileTableEntry.cs
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ public SparseStream Open(IAttributeLocator attr, FileAccess access)
return null;
}

return new NtfsFileStream(File, directoryEntry.Value, attr.AttributeType, attr.Identifier, access);
return NtfsFileStream.Open(File, directoryEntry.Value, attr.AttributeType, attr.Identifier, access);
}

public IEnumerable<Range<long, long>> GetClusters(IAttributeLocator attr) =>
Expand Down
46 changes: 40 additions & 6 deletions Library/DiscUtils.Ntfs/NtfsFileStream.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,26 +32,60 @@ namespace DiscUtils.Ntfs;
internal sealed class NtfsFileStream : SparseStream
{
private SparseStream _baseStream;

public SparseStream BaseStream => _baseStream;

private readonly DirectoryEntry _entry;

private readonly File _file;

private bool _isDirty;

public NtfsFileStream(File file, DirectoryEntry entry, AttributeType attrType, string attrName,
public static SparseStream Open(File file, DirectoryEntry entry, AttributeType attrType, string attrName,
FileAccess access)
{
var baseStream = file.OpenStream(attrType, attrName, access);

if (baseStream is null)
{
return null;
}

if (file.Context.ReadOnly)
{
return baseStream;
}
else
{
return new NtfsFileStream(entry, file, baseStream);
}
}

private NtfsFileStream(DirectoryEntry entry, File file, SparseStream baseStream)
{
_entry = entry;
_file = file;
_baseStream = _file.OpenStream(attrType, attrName, access);
_baseStream = baseStream;
}

public NtfsFileStream(File file, DirectoryEntry entry, AttributeType attrType, ushort attrId,
public static SparseStream Open(File file, DirectoryEntry entry, AttributeType attrType, ushort attrId,
FileAccess access)
{
_entry = entry;
_file = file;
_baseStream = _file.OpenStream(attrId, attrType, access);
var baseStream = file.OpenStream(attrId, attrType, access);

if (baseStream is null)
{
return null;
}

if (file.Context.ReadOnly)
{
return baseStream;
}
else
{
return new NtfsFileStream(entry, file, baseStream);
}
}

public override bool CanRead
Expand Down
7 changes: 6 additions & 1 deletion Library/DiscUtils.Ntfs/NtfsFileSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2055,7 +2055,12 @@ public SparseStream OpenFile(string path, FileMode mode, FileAccess access, NewF
}
}

var stream = new NtfsFileStream(file, entry.Value, attributeType, attributeName, access);
var stream = NtfsFileStream.Open(file, entry.Value, attributeType, attributeName, access);

if (stream is null)
{
throw new InvalidFileSystemException("File system corrupt");
}

if (mode is FileMode.Create or FileMode.Truncate)
{
Expand Down

0 comments on commit e2841b3

Please sign in to comment.