Cannot use Document stream
Hi,
Consider the following method:
public void CreateZip()
using (ZipFile zip = new ZipFile()) // ZipFile = Ionic.Zip.ZipFile
foreach (var doc in this.documents) // documents is a List of Telerik.Sitefinity.Libraries.Model.Document objects
var stream = LibrariesManager.GetManager().Download(doc);
zip.AddEntry(doc.Title + doc.Extension, stream);
zip.Save(@"C:\test.zip");
var stream = new System.IO.FileStream(@"C:\test.txt", System.IO.FileMode.Open);
Hello Thomas,
Thank you for the detailed description of the issue.
Actually I am wondering whether I miss something in reproducing the issue as I tested your code and I successfully saved a .zip file on my local drive. Also to check whether the stream is OK I tried to save it by using a FileStream:
public
void
CreateZip()
LibrariesManager manager = LibrariesManager.GetManager();
using
(ZipFile zip =
new
ZipFile())
// ZipFile = Ionic.Zip.ZipFile
IQueryable<Document> docList = manager.GetDocuments().Where(d => d.Status == Telerik.Sitefinity.GenericContent.Model.ContentLifecycleStatus.Live);
foreach
(var doc
in
docList)
// documents is a List of Telerik.Sitefinity.Libraries.Model.Document objects
var stream = manager.Download(doc);
FileStream fileStream =
new
FileStream(@
"C:/MyFiles"
, FileMode.Create);
using
(fileStream)
// Fill the bytes[] array with the stream data
byte
[] bytesInStream =
new
byte
[stream.Length];
stream.Read(bytesInStream, 0, bytesInStream.Length);
// Use FileStream object to write to the specified file
fileStream.Write(bytesInStream, 0, bytesInStream.Length);
//zip.AddFileStream(doc.Title + doc.Extension, "", stream);
//zip.Save(@"C:\test.zip");
Thank you for being the most amazing .NET community! Your unfailing support is what helps us charge forward! We'd appreciate your vote for Telerik in this year's DevProConnections Awards. We are competing in mind-blowing 20 categories and every vote counts! VOTE for Telerik NOW >>
Hi Veronica,
I made a mistake: I should have used stream.Read rather than stream.Write to create the byte array.
With the byte array, I got it to work.
So this didn't work (not sure why):
var stream = LibrariesManager.GetManager().Download(doc);
zip.AddEntry(doc.Title + doc.Extension, stream);
byte
[] bytes =
this
.GetBytes(doc);
zip.AddEntry(doc.Title + doc.Extension, bytes);
(...)
private
byte
[] GetBytes(Document document)
var manager = LibrariesManager.GetManager();
using
(var stream = manager.Download(document))
byte
[] bytes =
new
byte
[stream.Length];
stream.Read(bytes, 0, bytes.Length);
return
bytes;
Hello Thomas,
Please accept my apologies for the late reply.
I am glad that you found a workaround of the issue. However I wonder why the first one is not working on your side. If the workaround satisfies your requirement I'll close the thread, otherwise I'll continue researching the issue although both scenarios work on my side.
Regards,
Veronica Milcheva
the Telerik team
Hi Veronica,
I'm thinking you may not have been able to reproduce my problem because you used a Telerik.Sitefinity.Utilities.Zip.ZipFile rather than Ionic.Zip.ZipFile. It may be interesting to see what makes this fail with Ionic.Zip, as it's possible there is something wrong with the stream that may only cause a failure in certain circumstances (ie: it could also happen in other cases, not just with Ionic.Zip).
So as far as I'm concerned, I've worked around this issue and can now move on to other things, so this doesn't block me anymore. But for the future of Sitefinity, you might want to investigate this some more to fix potential issues. Of course, it's also possible that it's Ionic.Zip that does something wrong (I've never had any problems with this library, though).
Hi Thomas,
I've tested with Ionic library and I can confirm that the following code works:
public
void
CreateZip()
LibrariesManager manager = LibrariesManager.GetManager();
using
(ZipFile zip =
new
ZipFile())
// ZipFile = Ionic.Zip.ZipFile
IQueryable<Document> docList = manager.GetDocuments().Where(d => d.Status == Telerik.Sitefinity.GenericContent.Model.ContentLifecycleStatus.Live);
foreach
(var doc
in
docList)
// documents is a List of Telerik.Sitefinity.Libraries.Model.Document objects
var stream = LibrariesManager.GetManager().Download(doc);
zip.AddEntry(doc.Title + doc.Extension, stream);
zip.Save(@
"C:\test.zip"
);
IQueryable<Document> docList = manager.GetDocuments().Where(d => d.Status == Telerik.Sitefinity.GenericContent.Model.ContentLifecycleStatus.Live);
Hi Veronica,
This how I retrieve the documents:
private
void
LoadDocuments()
this
.docIds =
this
.GetDocumentIds();
// docIds is of type IEnumerable<Guid>
this
.documents =
new
List<Document>();
foreach
(Guid id
in
this
.docIds)
var doc = App.WorkWith().Documents().Publihed().FirstThat(d => d.Id == id).Get();
this
.documents.Add(doc);
Hello Thomas,
In this case could you provide us with the source of this function:
this.GetDocumentIds()
Since an Id may be an Id for a draft, live or temp version of a Document, so it is important what Ids do you actually retrieve with this function.
Hi Lubomir,
The GetDocumentIds method loads ids from session, so I'll just skip to the relevant part (ie: how documents are loaded in the first place):
private
IEnumerable<Document> GetAllLibraryDocuments()
var docs =
new
List<Document>();
var allDocs = App.WorkWith().Documents().Publihed().Get();
foreach
(var doc
in
allDocs)
if
(doc.Library.UrlName ==
this
.LibraryUrlName)
docs.Add(doc);
return
docs;
Hello Thomas,
Ok so using your code to retrieve the documents you can't get the ZipFile to actually create a Zip file from them?
Regards,I managed to do it by converting the streams to byte arrays, but I couldn't do it directly from the streams, no.
Hi Thomas,
Ok, so is the workaround with converting the Stream to byte array working for you or do you need any additional help for this issue?
Regards,Hi Lubomir,
The workaround works, so I'm fine. Thank you.