/// <summary> /// </summary> /// <returns>Docking station event</returns> public DockingStationEvent Execute() { UploadDatabaseEvent uploadEvent = new UploadDatabaseEvent(this); CompressDatabase(uploadEvent); #if DEBUG // UncompressDatabase( uploadEvent ); // unit test. Temporarily uncomment it to run it. #endif return(uploadEvent); }
/// <summary> /// /// </summary> /// <remarks> /// System.IO.Packaging.ZipPackage can handle .zip files, but it is not supported in Compact Framework. /// We therefore use the freeware SharpZipLib to do our uncompression. /// </remarks> /// <param name="uploadEvent"></param> private void CompressDatabase(UploadDatabaseEvent uploadEvent) { string dbFilePath = Controller.FLASHCARD_PATH + Controller.INET_DB_NAME; FileInfo finfo = new FileInfo(dbFilePath); long totalLength = finfo.Length; using (FileStream dbFileStream = new FileStream(dbFilePath, FileMode.Open)) { MemoryStream outputMemStream = new MemoryStream(); ZipOutputStream zipStream = new ZipOutputStream(outputMemStream); // We just use default compression leve, which I think is actually 6. zipStream.SetLevel(Deflater.DEFAULT_COMPRESSION); // 0-9, 9 being the highest compression, 0 being no compression ZipEntry newEntry = new ZipEntry(Controller.INET_DB_NAME); newEntry.DateTime = DateTime.UtcNow; zipStream.PutNextEntry(newEntry); // Assign the entry's size to what the file size is expected to be when // uncompressed. This is necessary to get Window's built-in extractor to work, // according to SharpZipLib sample code. newEntry.Size = finfo.Length; DateTime startTime = DateTime.UtcNow; // Copy the file into the zip stream. The ZipStream // compresses the data as it's fed into it. const int bufferSize = 8196; long logThreshold = bufferSize * 50; byte[] buffer = new byte[bufferSize]; int bytesRead; long totalBytesRead = 0; while ((bytesRead = dbFileStream.Read(buffer, 0, bufferSize)) > 0) { zipStream.Write(buffer, 0, bytesRead); totalBytesRead += bytesRead; if ((totalBytesRead % logThreshold) == 0) { LogCompression(totalBytesRead, totalLength, outputMemStream.Length); } } zipStream.CloseEntry(); zipStream.IsStreamOwner = false; // False stops the Close also Closing the underlying stream. zipStream.Close(); // Must finish the ZipOutputStream before using outputMemStream. outputMemStream.Position = 0; DateTime endTime = DateTime.UtcNow; TimeSpan elapsed = endTime - startTime; LogCompression(totalBytesRead, totalLength, outputMemStream.Length); Log.Debug(string.Format("Compression finished. Elapsed time: {0} seconds.", (int)elapsed.TotalSeconds)); // ToArray is the cleaner and easiest to use correctly with the penalty of duplicating allocated memory. uploadEvent.File = outputMemStream.ToArray(); // Alternative: GetBuffer returns a raw buffer raw and so you need to account for the true length yourself. //byte[] byteArrayOut = outputMemStream.GetBuffer(); //long len = outputMemStream.Length; uploadEvent.FileName = newEntry.Name + ".zip"; } }