Allow multiple saves of an archive. New entry streams must be seekable and resetable.

This commit is contained in:
Adam Hathcock
2013-12-20 15:50:29 +00:00
parent c1562c5829
commit d46de85ca2
11 changed files with 78 additions and 21 deletions

View File

@@ -2,6 +2,7 @@
using System;
using System.IO;
using System.Linq;
using System.Text;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using SharpCompress.Archive;
using SharpCompress.Archive.Zip;
@@ -163,6 +164,25 @@ namespace SharpCompress.Test
CompareArchivesByPath(modified, scratchPath);
}
[TestMethod]
public void Zip_Save_Twice()
{
string scratchPath1 = Path.Combine(SCRATCH_FILES_PATH, "a.zip");
string scratchPath2 = Path.Combine(SCRATCH_FILES_PATH, "b.zip");
ResetScratch();
using (var arc = ZipArchive.Create())
{
string str = "test.txt";
var source = new MemoryStream(Encoding.UTF8.GetBytes(str));
arc.AddEntry("test.txt", source, true, source.Length);
arc.SaveTo(scratchPath1, CompressionType.Deflate);
arc.SaveTo(scratchPath2, CompressionType.Deflate);
}
Assert.AreEqual(new FileInfo(scratchPath1).Length, new FileInfo(scratchPath2).Length);
}
[TestMethod]
public void Zip_Create_New()
{

View File

@@ -94,6 +94,8 @@ namespace SharpCompress.Archive
public void SaveTo(Stream stream, CompressionInfo compressionType)
{
//reset streams of new entries
newEntries.Cast<IWritableArchiveEntry>().ForEach(x => x.Stream.Seek(0, SeekOrigin.Begin));
SaveTo(stream, compressionType, OldEntries, newEntries);
}
@@ -104,6 +106,8 @@ namespace SharpCompress.Archive
{
throw new ArgumentException("Streams must be readable and seekable to use the Writing Archive API");
}
//ensure new stream is at the start, this could be reset
source.Seek(0, SeekOrigin.Begin);
return CreateEntryInternal(filePath, source, size, modified, closeStream);
}

View File

@@ -6,18 +6,19 @@ using SharpCompress.IO;
namespace SharpCompress.Archive.GZip
{
internal class GZipWritableArchiveEntry : GZipArchiveEntry
internal class GZipWritableArchiveEntry : GZipArchiveEntry, IWritableArchiveEntry
{
private string path;
private long size;
private DateTime? lastModified;
private bool closeStream;
private readonly string path;
private readonly long size;
private readonly DateTime? lastModified;
private readonly bool closeStream;
private readonly Stream stream;
internal GZipWritableArchiveEntry(GZipArchive archive, Stream stream,
string path, long size, DateTime? lastModified, bool closeStream)
: base(archive, null)
{
this.Stream = stream;
this.stream = stream;
this.path = path;
this.size = size;
this.lastModified = lastModified;
@@ -84,18 +85,24 @@ namespace SharpCompress.Archive.GZip
get { throw new NotImplementedException(); }
}
internal Stream Stream { get; private set; }
Stream IWritableArchiveEntry.Stream
{
get
{
return stream;
}
}
public override Stream OpenEntryStream()
{
return new NonDisposingStream(Stream);
return new NonDisposingStream(stream);
}
internal override void Close()
{
if (closeStream)
{
Stream.Dispose();
stream.Dispose();
}
}
}

View File

@@ -0,0 +1,9 @@
using System.IO;
namespace SharpCompress.Archive
{
internal interface IWritableArchiveEntry
{
Stream Stream { get; }
}
}

View File

@@ -6,18 +6,19 @@ using SharpCompress.IO;
namespace SharpCompress.Archive.Tar
{
internal class TarWritableArchiveEntry : TarArchiveEntry
internal class TarWritableArchiveEntry : TarArchiveEntry, IWritableArchiveEntry
{
private readonly string path;
private readonly long size;
private readonly DateTime? lastModified;
private readonly bool closeStream;
private readonly Stream stream;
internal TarWritableArchiveEntry(TarArchive archive, Stream stream, CompressionType compressionType,
string path, long size, DateTime? lastModified, bool closeStream)
: base(archive, null, compressionType)
{
Stream = stream;
this.stream = stream;
this.path = path;
this.size = size;
this.lastModified = lastModified;
@@ -83,19 +84,24 @@ namespace SharpCompress.Archive.Tar
{
get { throw new NotImplementedException(); }
}
internal Stream Stream { get; private set; }
Stream IWritableArchiveEntry.Stream
{
get
{
return stream;
}
}
public override Stream OpenEntryStream()
{
return new NonDisposingStream(Stream);
return new NonDisposingStream(stream);
}
internal override void Close()
{
if (closeStream)
{
Stream.Dispose();
stream.Dispose();
}
}
}

View File

@@ -14,7 +14,7 @@ namespace SharpCompress.Archive.Zip
{
public class ZipArchive : AbstractWritableArchive<ZipArchiveEntry, ZipVolume>
{
private SeekableZipHeaderFactory headerFactory;
private readonly SeekableZipHeaderFactory headerFactory;
/// <summary>
/// Gets or sets the compression level applied to files added to the archive,

View File

@@ -6,19 +6,20 @@ using SharpCompress.IO;
namespace SharpCompress.Archive.Zip
{
internal class ZipWritableArchiveEntry : ZipArchiveEntry
internal class ZipWritableArchiveEntry : ZipArchiveEntry, IWritableArchiveEntry
{
private readonly string path;
private readonly long size;
private readonly DateTime? lastModified;
private readonly bool closeStream;
private readonly Stream stream;
private bool isDisposed;
internal ZipWritableArchiveEntry(ZipArchive archive, Stream stream, string path, long size,
DateTime? lastModified, bool closeStream)
: base(archive, null)
{
Stream = stream;
this.stream = stream;
this.path = path;
this.size = size;
this.lastModified = lastModified;
@@ -85,18 +86,24 @@ namespace SharpCompress.Archive.Zip
get { throw new NotImplementedException(); }
}
internal Stream Stream { get; private set; }
Stream IWritableArchiveEntry.Stream
{
get
{
return stream;
}
}
public override Stream OpenEntryStream()
{
return new NonDisposingStream(Stream);
return new NonDisposingStream(stream);
}
internal override void Close()
{
if (closeStream && !isDisposed)
{
Stream.Dispose();
stream.Dispose();
isDisposed = true;
}
}

View File

@@ -62,6 +62,7 @@
<Compile Include="Archive\IArchive.cs" />
<Compile Include="Archive\IArchiveEntry.cs" />
<Compile Include="Archive\IArchiveEntry.Extensions.cs" />
<Compile Include="Archive\IWritableArchiveEntry.cs" />
<Compile Include="Archive\Rar\RarArchive.cs" />
<Compile Include="Archive\Rar\RarArchive.Extensions.cs" />
<Compile Include="Archive\Rar\RarArchiveEntry.cs" />

View File

@@ -85,6 +85,7 @@
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="Archive\IWritableArchiveEntry.cs" />
<Compile Include="Common\ArchiveEncoding.cs" />
<Compile Include="Archive\AbstractWritableArchive.cs" />
<Compile Include="Archive\AbstractArchive.cs" />

View File

@@ -46,6 +46,7 @@
<Compile Include="Archive\IArchive.Extensions.cs" />
<Compile Include="Archive\IArchiveEntry.cs" />
<Compile Include="Archive\IArchiveEntry.Extensions.cs" />
<Compile Include="Archive\IWritableArchiveEntry.cs" />
<Compile Include="Archive\Rar\RarArchive.cs" />
<Compile Include="Archive\Rar\RarArchive.Extensions.cs" />
<Compile Include="Archive\Rar\RarArchiveEntry.cs" />

View File

@@ -88,6 +88,7 @@
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="Archive\IWritableArchiveEntry.cs" />
<Compile Include="Common\ArchiveEncoding.cs" />
<Compile Include="Archive\AbstractWritableArchive.cs" />
<Compile Include="Archive\AbstractArchive.cs" />