URI formats are not supported

Mar 23, 2011 at 2:47 PM

Hi,

I am using DotNetZip library in sharepoint object model and i am passing the file name as "http://gdot-govm-spd24/info/tpd/Test/Data.txt" and trying to create this file as zip and it throwing me URI formats are not supported. When i use the same file which is on my local drive, it works perfectly. I am not sure what i am doing wrong here. Please help me.

This is the piece of code i am using here:

using (ZipFile zip = new ZipFile())          

{

                foreach (string filename in ItemsID)                

{                  

 ZipEntry e = zip.AddFile(filename);              

}  

zip.Save(@"C:\suri.zip");            

Thanks

KPd

Coordinator
Mar 25, 2011 at 12:33 PM

no, DotNetZip can read from filesystems.  It cannot read from http sources.  An easy way to do what you want is to send a GET request to the HTTP resource, and then pass the ResponseStream to the call to AddFile().

Oct 1, 2011 at 2:45 AM

I am trying to do the same thing but it says URI format not supported. Do you have any example, which can help me fix this issue?

Coordinator
Oct 2, 2011 at 11:03 PM

There are many variations.  One way to do it is to use WebClient to open a stream for the given URL, then call the ZipFile.AddEntry() method that accepts a stream.  Something like this would work:

string url = "http://example.org/fi/fie/fo/fum.txt";
using (var zip = new ZipFile())
{
  using (WebClient client = new WebClient())
  {
    using (var s = client.OpenRead(url))
    {
      // s is a readable System.IO.Stream
      zip.AddEntry("ThisEntry.txt", s);
      // must save the zip (and thereby read the stream) before disposing the stream or WebClient 
      zip.Save("MyArchive.zip");
    }
  }
}

If you have multiple URLs to pack into a single zip file, then you would need to keep all of those streams open at the same time.  The basic structure in the snippet above will work for a variable number of URLs, but you'd have to save the zip file for each additional URL added, which is very much non-optimal. 

What you'd like to do is open the stream only as necessary during the save operation. This is possible using the ZipFile.AddEntry() method that accepts an OpenDelegate and a CloseDelegate. In this approach, your code opens the stream within the context of the save operation.  It looks like this:

string[] urls = {
    "http://example.org/whatever.txt",
    "http://example.org/whatever2.txt",
    "http://example.org/whatever3.txt"
  }; 

var getOpener = new Ionic.Zip.OpenDelegate( name => {
   // GetUrlForEntryName is your custom function...
   var url = GetUrlForEntryName (name);
   WebClient c = new WebClient();
   return c.OpenRead(url);
});

var closer = new Ionic.Zip.CloseDelegate( (name, stream) => {
   stream.Dispose();
});

using(var zip = new Ionic.Zip.ZipFile())
{
    for(int i=0; i<urls.Length; i++) 
    {
        // GetEntryNameForUrl is your custom function...
        var entryName = GetEntryNameForUrl(urls[i]);
        zip.AddEntry(entryName, getOpener, closer);
    }
    zip.Save(zipFileName);
}

 

  

Nov 18, 2014 at 6:00 PM
Thanks Cheeso, here is a slightly simpler multi-file version in VB
Dim pdfs As New List(Of Tuple(Of String, String))
pdfs.Add(New Tuple(Of String, String)("MyFileNameInZip", "http://urlToFile.pdf"))
If pdfs.Count > 0 Then
    Dim getOpener = New Ionic.Zip.OpenDelegate(Function(name) New WebClient().OpenRead(pdfs.FirstOrDefault(Function(x) x.Item1 = name).Item2))
    Dim closer = New Ionic.Zip.CloseDelegate(Sub(name, stream) stream.Dispose())
    Using zip = New Ionic.Zip.ZipFile()
        For Each pdf In pdfs
            zip.AddEntry(pdf.Item1, getOpener, closer)
        Next
        Response.ContentType = "application/zip"
        Response.AddHeader("Content-Disposition", "filename=MyZipFile.zip")
        zip.Save(Response.OutputStream)
    End Using
End If
Mar 22 at 6:48 PM
Hi Cheeso,

I need to pack multiple uri's into a single Zip file, in which the above code is working fine when I tested using sample win forms application.

My requirement is how to use this to return a Zip file stream using web api when the user clicks on donwload ? we are using web api +angularJs.
Mar 22 at 6:49 PM
Hi Cheeso,

I need to pack multiple uri's into a single Zip file, in which the above code is working fine when I tested using sample win forms application.

My requirement is how to use this to return a Zip file stream using web api when the user clicks on donwload ? we are using web api +angularJs.
Mar 22 at 6:50 PM
I need to pack multiple uri's into a single Zip file, in which the above code is working fine when I tested using sample win forms application.

My requirement is how to use this to return a Zip file stream using web api when the user clicks on donwload ? we are using web api +angularJs.