How do I zip files in Xamarin for Android?

I have a function that creates a zip file, a string array of uploaded files. The function does create a zip file and zip recording files inside it, but those zip recording files are empty. I've tried several different methods - the function code below is closest to something working:

    public static bool ZipFile(string[] arrFiles, string sZipToDirectory, string sZipFileName)
    {
        if (Directory.Exists(sZipToDirectory))
        {
            FileStream fNewZipFileStream;
            ZipOutputStream zos;

            try {
                fNewZipFileStream = File.Create(sZipToDirectory + sZipFileName);
                zos = new ZipOutputStream(fNewZipFileStream);

                for (int i = 0; i < arrFiles.Length; i++) {
                    ZipEntry entry = new ZipEntry(arrFiles[i].Substring(arrFiles[i].LastIndexOf("/") + 1));
                    zos.PutNextEntry(entry);

                    FileStream fStream = File.OpenRead(arrFiles[i]);
                    BufferedStream bfStrm = new BufferedStream(fStream);

                    byte[] buffer = new byte[bfStrm.Length];
                    int count;
                    while ((count = bfStrm.Read(buffer, 0, 1024)) != -1) {
                        zos.Write(buffer);
                    }

                    bfStrm.Close();
                    fStream.Close();
                    zos.CloseEntry();
                }
                zos.Close();
                fNewZipFileStream.Close();
                return true;
            }
            catch (Exception ex)
            {
                string sErr = ex.Message;
                return false;
            }
            finally
            {
                fNewZipFileStream = null;
                zos = null;
            }
        }
        else
        {
            return false;
        }
    }

      

I think it has to do with handling the byte stream. I've tried this bit of code that processes the stream, but it goes into an infinite loop:

while ((count = fStream.Read(buffer, 0, 1024)) != -1) {
        zos.Write(buffer, 0, count);
}
fStream.Close();

      

+3


source to share


3 answers


I found a solution that is quite simple - I used the ReadAllBytes method for the static File class.



ZipEntry entry = new ZipEntry(arrFiles[i].Substring(arrFiles[i].LastIndexOf("/") + 1));
zos.PutNextEntry(entry);

byte[] fileContents = File.ReadAllBytes(arrFiles[i]);
zos.Write(fileContents);
zos.CloseEntry();

      

+2


source


Using Read()

c FileStream

returns the number of bytes read in the stream, or 0 if the end of the stream has been reached. It will never return -1. In the meantime, there is no need to worry about it. ”

From MSDN :

The total number of bytes read into the buffer. This might be less than the number of bytes requested if that number of bytes are not currently available, or

zero if the end of the stream is reached

...



I would change your code to the following:

System.IO.FileStream fos = new System.IO.FileStream(sZipToDirectory + sZipFileName, FileMode.Create);
Java.Util.Zip.ZipOutputStream zos = new Java.Util.Zip.ZipOutputStream(fos);

byte[] buffer = new byte[1024];
for (int i = 0; i < arrFiles.Length; i++) {

    FileInfo fi = new FileInfo (arrFiles[i]);
    Java.IO.FileInputStream fis = new Java.IO.FileInputStream(fi.FullName);

    ZipEntry entry = new ZipEntry(arrFiles[i].Substring(arrFiles[i].LastIndexOf("/") + 1));
    zos.PutNextEntry(entry);

    int count = 0;
    while ((count = fis.Read(buffer)) > 0) {
        zos.Write(buffer, 0, count);
    }

    fis.Close();
    zos.CloseEntry();
}

      

This is almost identical to the code I've used to create zip archives on Android in the past.

+2


source


Can SharpZip be used ? It's really easy to use.

Here is the blog post I wrote to extract zip files

    private static void upzip(string url)
    {
        WebClient wc = new WebClient();
        wc.DownloadFile(url, "temp.zip");  
        //unzip
        ZipFile zf = null;
        try
        {
            zf = new ZipFile(File.OpenRead("temp.zip"));
            foreach (ZipEntry zipEntry in zf)
            {
                string fileName = zipEntry.Name;
                byte[] buffer = new byte[4096];
                Stream zipStream = zf.GetInputStream(zipEntry);
                using (FileStream streamWriter = File.Create( fileName))
                {
                    StreamUtils.Copy(zipStream, streamWriter, buffer);
                }
            }

        }
        finally
        {
            if (zf != null)
            {
                zf.IsStreamOwner = true;
                zf.Close();
            }
        }

    }

      

0


source







All Articles