mirror of
https://github.com/adamhathcock/sharpcompress.git
synced 2026-09-22 23:15:20 +00:00
Allow multiple saves of an archive. New entry streams must be seekable and resetable.
This commit is contained in:
@@ -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()
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
9
SharpCompress/Archive/IWritableArchiveEntry.cs
Normal file
9
SharpCompress/Archive/IWritableArchiveEntry.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
using System.IO;
|
||||
|
||||
namespace SharpCompress.Archive
|
||||
{
|
||||
internal interface IWritableArchiveEntry
|
||||
{
|
||||
Stream Stream { get; }
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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" />
|
||||
|
||||
@@ -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" />
|
||||
|
||||
@@ -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" />
|
||||
|
||||
@@ -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" />
|
||||
|
||||
Reference in New Issue
Block a user