Exemplo n.º 1
0
// Removes specified files from zip
void ZipFile::Remove(String* FileSpec, Boolean RecurseSubdirectories)
{
	ZipFile* tempZipFile;
	OpenFileForUnzip();

	// Just wrapping in a try/catch/finally to make sure temp zip file gets removed
	try
	{
		Regex* filePattern = GetFilePatternRegularExpression(FileSpec, caseSensitive);
		IEnumerator* filesEnum = files->GetEnumerator();
		CompressedFile* file;

		// Create temporary zip file to hold remove results
		tempZipFile = CreateTempZipFile();

		// Loop through compressed file collection
		while (filesEnum->MoveNext())
		{
			file = static_cast<CompressedFile*>(filesEnum->Current);

			// We copy all files into destination zip file except those user requested to be removed...
			if (!filePattern->IsMatch(GetSearchFileName(FileSpec, file->get_FileName(), RecurseSubdirectories)))
				CopyFileInZip(file, this, tempZipFile, S"Remove Zip File");
		}

		// Now make the temp file the new zip file
		Close();
		tempZipFile->Close();
		File::Delete(fileName);
		File::Move(tempZipFile->fileName, fileName);
	}
	catch (CompressionException* ex)		
	{
		// We just rethrow any errors back to user
		throw ex;
	}
	catch (Exception* ex)
	{
		throw ex;
	}
	__finally
	{
		// If everything went well, temp zip will no longer exist, but just in case we tidy up and delete the temp file...
		DeleteTempZipFile(tempZipFile);
	}

	// We'll reload the file list after remove if requested...
	if (autoRefresh) Refresh();
}
Exemplo n.º 2
0
// Extracts specified files from zip
void ZipFile::Extract(String* FileSpec, String* DestPath, UpdateOption OverwriteWhen, Boolean RecurseSubdirectories, PathInclusion CreatePathMethod)
{
	// Any file spec in destination path will be ignored
	DestPath = JustPath(DestPath);

	char* pszPassword = NULL;
	char* pszFileName = NULL;
	OpenFileForUnzip();

	// Just wrapping in a try/catch/finally to make sure unmanaged code allocations always get released
	try
	{
		Regex* filePattern = GetFilePatternRegularExpression(FileSpec, caseSensitive);
		IEnumerator* filesEnum = files->GetEnumerator();
		CompressedFile* file;
		String* sourceFileName;
		String* destFileName;
		bool writeFile;
 		int err;

		// Get ANSI password, if one was provided
		if (password)
			if (password->get_Length())
				pszPassword = StringToCharBuffer(password);

		// Loop through compressed file collection
		while (filesEnum->MoveNext())
		{
			file = static_cast<CompressedFile*>(filesEnum->Current);
			sourceFileName = file->get_FileName();

			if (filePattern->IsMatch(GetSearchFileName(FileSpec, sourceFileName, RecurseSubdirectories)))
			{
				pszFileName = StringToCharBuffer(sourceFileName);
				err = unzLocateFile(hUnzipFile, pszFileName, (caseSensitive ? 1 : 2));
				free(pszFileName);
				pszFileName = NULL;

				// We should find file in zip file if it was in our compressed file collection
				if (err != Z_OK) throw new CompressionException(String::Concat(S"Extract Zip File Error: Compressed file \"", sourceFileName, "\" cannot be found in zip file!"));

				// Open compressed file for unzipping
				if (pszPassword)
					err = unzOpenCurrentFilePassword(hUnzipFile, pszPassword);
				else
					err = unzOpenCurrentFile(hUnzipFile);

				if (err != Z_OK) throw new CompressionException(S"Extract Zip File", err);

				// Get full destination file name
				switch (CreatePathMethod)
				{
					case PathInclusion::FullPath:
						destFileName = sourceFileName;
						break;
					case PathInclusion::NoPath:
						destFileName = String::Concat(DestPath, Path::GetFileName(sourceFileName));
						break;
					case PathInclusion::RelativePath:
						destFileName = String::Concat(DestPath, sourceFileName);
						break;
				}

				// Make sure destination directory exists
				Directory::CreateDirectory(JustPath(destFileName));

				// See if destination file already exists
				if (File::Exists(destFileName))
				{
					DateTime lastUpdate = File::GetLastWriteTime(destFileName);

					switch (OverwriteWhen)
					{
						case UpdateOption::Never:
							writeFile = false;
							break;
						case UpdateOption::Always:
							writeFile = true;
							break;
						case UpdateOption::ZipFileIsNewer:
							writeFile = (DateTime::Compare(file->get_FileDateTime(), lastUpdate) > 0);
							break;
						case UpdateOption::DiskFileIsNewer:
							writeFile = (DateTime::Compare(file->get_FileDateTime(), lastUpdate) < 0);
							break;
						default:
							writeFile = false;
							break;
					}
				}
				else
					writeFile = true;

				if (writeFile)
				{
					System::Byte buffer[] = new System::Byte[BufferSize];
					System::Byte __pin * destBuff = &buffer[0];	// pin buffer so it can be safely passed into unmanaged code...
					FileStream* fileStream = File::Create(destFileName);
					int read;
					__int64 total = 0, len = -1;

					// Send initial progress event
					len = file->get_UncompressedSize();
					CurrentFile(destFileName, sourceFileName);
					FileProgress(0, len);					

					// Read initial buffer
					read = unzReadCurrentFile(hUnzipFile, destBuff, buffer->get_Length());
					if (read < 0) throw new CompressionException(S"Extract Zip File", read);

					while (read)
					{
						// Write data to file stream,
						fileStream->Write(buffer, 0, read);

						// Raise progress event
						total += read;
						FileProgress(total, len);

						// Read next buffer from source file stream
						read = unzReadCurrentFile(hUnzipFile, destBuff, buffer->get_Length());
						if (read < 0) throw new CompressionException(S"Extract Zip File", read);
					}

					fileStream->Close();
				}

				// Close compressed file
				unzCloseCurrentFile(hUnzipFile);
			}
		}
	}
	catch (CompressionException* ex)		
	{
		// We just rethrow any errors back to user
		throw ex;
	}
	catch (Exception* ex)
	{
		throw ex;
	}
	__finally
	{
		if (pszPassword)
			free(pszPassword);

		if (pszFileName)
			free(pszFileName);
	}
}