Use the zip class in the J # class library to compress files and data through C #.

Source: Internet
Author: User
Tags create zip decompress zip deflater visual studio 2002 zip folder
Released on: 12/13/2004 | updated on: 12/13/2004

Ianier Munoz

This document assumes that you are familiar with C # And Windows Forms.

Download the code in this article:Zipcompression.exe(150kb)

Summary

When you store files or send files over the network, using zip compression can save space and network bandwidth. In addition, the directory structure of the ZIP folder will not be lost, which makes it a very useful compression solution. C # language does not have any class that allows you to manipulate ZIP files. the net language can share class implementations, and J # exposes classes in the java.util.zip namespace. Therefore, you can use these classes in C # code. This article explains how to use the Microsoft J # class library to create a C # application that can compress and decompress ZIP files. It also introduces some other unique parts of the J # Runtime Library that can be used in any. Net compatible language to save some coding work.

Content on this page
ZIP file and C #
Solution
Sharpzip
Enumerative zip entries
Decompress the ZIP file
Create and modify ZIP files
Low-level zip Compression
Other attractive functions of J #
Application Deployment
Summary

Zip is a popular data transmission and storage standard because it can save disk space and network bandwidth. Typical Text and database files can be compressed to 10% of their original size. Even if the binary file cannot be compressed, the compression ratio is usually 50%.

An additional advantage of a zip file is that a single file can contain multiple files, while retaining the directory structure. This allows you to send the complete directory tree attached to the email message and restore the recipient's original file structure.

The zip data format is open and does not involve patent rights or other legal issues. Developers can freely create apps that manipulate ZIP files, and use low-level zip compression algorithms to temporarily reduce the size of their own custom data. The author of the zip data specification provides developers with compression and decompression algorithms in the library named zlib (http://www.gzip.org/zlib. The Java platform uses this library in Java Development Kit (JDK) Version 1.1 to form the basis of the Java archive (jar) file format. Therefore, starting with JDK 1.1, the standard Java API contains the classes required to manipulate ZIP files. You can find these classes in the java.util.zip namespace.


ZIP file and C #

I want to use zip compression in applications written in C. Unfortunately, Microsoft. NET Framework does not currently contain any classes used to manipulate ZIP files. However, I did find several products related to zip compression. For example, # ziplib (formerly known as nziplib, http://www.icsharpcode.net/OpenSource/SharpZipLib/default.asp) is a porting product from zlib library to C. Its license allows developers to include the library in commercial applications with closed source code. HoweverMsdn magazineAt the time of printing, # ziplib is in the prerelease status (version 0.31 ).

Another solution is to use unmanaged zlib as a Windows DLL and write necessary InterOP packages for it. However, since compression involves transferring a large amount of data during each function call, therefore, writing InterOP packages to achieve optimal performance is a difficult process. Although other libraries are available, they are not free.

Back to Top


Solution

The. NET Framework Design considers language interoperability. All managed components that follow certain rules can be correctly used from any. Net-compatible programming language that implements the necessary functions. The rules and language feature set required for interoperability are referred to as the public language specification (CLS ).

All. net Language compilers comply with CLs, including Microsoft Visual J #. net-one type for Microsoft.. NET Framework. (Visual J #. NET is developed independently by Microsoft. It is not approved by Sun Microsystems, Inc.) That is why the. NET Framework class can be used in Windows Forms and ASP. NET applications written in J.

As you will see later in this article, some classes exposed by the J # Runtime Library do not actually conform to CLs, but you can still access most J # classes in other languages for ease of use.. NET Framework. Because J # implements JDK version 1.1.4, it is not surprising that developers can access the java.util.zip namespace through the J # Runtime Library. In the next section of this article, I will introduce an application written in C #, which uses the java.util.zip class to compress and decompress the ZIP file, to save space locally and bandwidth in the network.

All the sample code in this article is developed using Microsoft Visual Studio 2002 and J # Runtime Library version 1.0 (see the link at the top of this Article.

Back to Top


Sharpzip

I used C # To compile sharpzip, one of the sample applications included in this article. It is a simplified utility used to process ZIP files. It can be used to create ZIP files or open existing ZIP files to decompress, attach, and delete files (seeFigure 1).

Figure 1Sharpzip Application

Before viewing the code, make sure that the J # Runtime Library is correctly installed in the system. You do not need to install the complete Visual J #. net product. You can just download and install J #1.0 redistributable package, which is available from the http://msdn.microsoft.com/vjsharp/downloads/howtoget.asp.

The java.util.zip namespace is implemented in the vjslib. dll program. This Assembly is located in the C: \ winnt \ Microsoft Visual jsharp. Net \ framework \ v1.0.4205 \ directory (replace winnt with the actual windows directory ).

When a project contains a reference to vjslib. dll, you can start to use the J # namespace in the Code and use the Object Browser to browse the JDK namespace (seeFigure 2). Important classes include java.util.zip.zipfile?java.util.zip. zipentry and java.util.zip. zipoutputstream. These classes are displayed inFigure 3You can use them to manipulate ZIP files at the file level.

Figure 2Namespace in Object Browser

When using the methods described in this article, the method name may seem unfamiliar to you, Because Java is used for Identifiers (except classes and interfaces) the naming conventions are different from those used in C. In Java, the namespace and method names are written in a mix of lower-case and lower-case cases. The first letter is in lower case, and the other words are in upper case, as shown in nextelement. However, I am sure you will understand this method.

Back to Top


Enumerative zip entries

The entries method of the java.util.zip. zipfile class returns an object that implements the java. util. Enumeration interface. Then, the application traverses the enumeration to retrieve the zipentry instances of each entry in the ZIP file. The zipentry class exposes all required information, such as the file name, compression method, timestamp, original size, and compression size (seeFigure 4).

Note that although Java. util. the enumeration interface is similar to system. collections. ienumerator interface, but the Java enumerator advances to the next element when you call nextelement to retrieve the current object. the net enumerator advances when you check the availability of more elements in the movenext call. Another important difference is that the enumeration interface does not provide a method for restarting traversal.

One advantage of the. Net enumerator is that you can access the current element multiple times. On the other hand, the Java enumerator allows you to check the completion status multiple times, but this is not very useful in most cases. Both Java and. Net enumerators have been well designed to prevent you from forgetting to move to the next element in the enumeration loop.

I decided to write a class to wrap the Java enumerator so that I could use C # foreach statements with them. I name this class enumerationadapter. I simulate the reset method by calling the method that can return the Java enumerator again. Therefore, the constructor of the packaging class uses the delegate of the Java. util. Enumeration interface as the parameter, rather than the java. util. Enumeration interface itself as the parameter.

Back to Top


Decompress the ZIP file

The first thing the sharpzip application does when extracting files is to prompt the user to specify the directory in which the files should be created. You may have noticed that the application displays the "browse for folder" dialog box. I prefer to use system. windows. forms. design. foldernameeditor. folderbrowser class, but the document claims that this type is supported. net Framework infrastructure, and is not suitable for direct use, so I use the shell32 object by importing the Microsoft shell controls and automation Type Library and using COM InterOP.

It is very easy to extract (decompress) the original file from a zip file: you only need to call the getinputstream on the zipfile object and pass the entries for the compressed file. The getinputstream method generates an inputstream from which you can read the content of an archive entry.

The extractzipfile helper function does this for you. A separate entry is used to store the directory in the ZIP file, but the file name in each entry also contains the directory information. Therefore, extractzipfile ignores the directory entries and extracts the necessary path information from the file name.

To save a single file to a disk, you only need to write the inputstream content corresponding to the entry you are interested in into the file. This time, I decided not to wrap the custom system. Io. Stream class into a Java stream, because the java. Io namespace has excellent support for the stream. Specifically, java. Io. fileoutputstream allows you to create files to copy the required entries to them.

Figure 5The copystream helper function in copies the content of the Java. Io. inputstream object to the java. Io. outputstream object. This helper function is also used by other parts of the sharpzip application. However, you should note that this example does not check whether the output files already exist before rewriting. You may want to prompt the user by asking whether the file should be rewritten.

Note that password-protected files are not supported. You can use the class in the system. Security. cryptography namespace to create your own encryption mechanism. If you do this, note that the generated files are not compatible with standard ZIP utilities (such as WinZip.

Back to Top


Create and modify ZIP files

The java.util.zip. zipoutputstream class allows you to compress data and write the results to the basic java. Io. outputstream object. The sharpzip application is suitable for processing files, so it writes compressed data to a new Java. io. fileoutputstream object, but you can easily. io. outputstream derives its own class, or uses one of the standard classes to directly write compressed data to the network or other storage media.

The createemptyzipfile helper function creates a zip file and closes it immediately. The result shows an empty ZIP file that does not contain any entries. Append or delete items is not that easy, because the java.util.zip package does not provide random access to the ZIP file. To delete a file, copy the entries to be retained to the new zip file. To add a file, copy all entries to the new zip file and append the new entry. Copying an entry involves extracting the entry from the source file as described, and then compressing it to the target file.

Create a new zipentry instance for each file to be added, and call setmethod for the entry to set the compression method to be used. Supported methods are zipentry. deflated (which uses a compression algorithm to compress data) and zipentry. stored (which stores data but does not apply any compression ). Call zipoutputstream. putnextentry, and input a new entry. Then, call the write method on the zipoutputstream object to write data to it. When processing the current entry, call zipoutputstream. closeentry to continue processing the next entry.

Figure 5The updatezipfile function in implements update and deletion by calling the delegate for each entry, so that you can select which entries should be copied to the temporary file. Finally, the new entry is added to the ZIP file.

Back to Top


Low-level zip Compression

By using the java.util.zip class, you can not only compress files, but also compress application data. To illustrate this, I have created a pair of functions to use the java.util.zip. Deflater and java.util.zip. Inflater classes to compress and decompress strings.

The compression function creates an instance of the java.util.zip. Deflater class. A parameter in the constructor defines the compression level required. Next, I will call the Deflater. setinput class, transfer the data to be compressed as a signed byte (sbyte) array, and then call Deflater. Finish.

Note that, in contrast to C #, the byte data type in Java is signed-Java does not have the unsigned byte data type. This is why the sbyte array is used as the parameter for all the buffer Processing Methods of the J # runtime database.

Fortunately, the com. Ms. vjsharp. struct namespace contains the javastructexternalhelper class, which not only provides other functions, but also helps you perform array conversion. The compressstring function calls the converttobytearray method to convert a string to a signed byte array. To get the actual compression bit, I just keep calling Deflater. Deflate until Deflater. Finished returns true to indicate that all input data has been consumed. I use the java. Io. bytearrayoutputstream instance to collect the data in the compression loop. As a general rule, JDK classes are recommended when processing Java types in C. It is the best way to avoid repeated array conversion between sbyte and byte.

The code used to extract strings looks very similar to the code used for compression. This time, an instance of the java.util.zip. Inflater class is created, the setinput method is called, and the compressed data is imported. The extract loop continuously calls Inflater. Inflate until inflate. Finished becomes true, indicating that all input data has been decompressed. Finally, call javastructmarshalhelper. converttostring to convert the unsigned byte array to a string to be returned by the function.

The cszipll sample application (LL stands for low level) creates a long string and compresses it to about half the size. You can use these functions to do some work, such as writing soap extensions to reduce the network bandwidth required by Web Services.

Back to Top


Other attractive functions of J #

Although this article focuses on how to process ZIP files, this principle can also be applied to other fields where the J # Runtime Library provides functionality that cannot be obtained from the. NET Framework standard program set.

Because J # provides developers with the ability to migrate their visual J ++ project.. NET Framework, so J # also implements many functions specific to Visual J ++, such as J/Direct ?. J/direct technology allows Java programs to call local Windows code. Like in Visual J ++, the com. Ms. Win32 namespace in J # provides access to most Windows API functions, data types, and constants.

USER32, Kernel32, and GDI32 classes contain Win32? The core of API functions. These constants are named in winx (where,XIs the initial character of a constant. For example, the sw_show flag of the showwindow API can be found in the com. Ms. win32.wins interface.

To make the interface conform to CLs, it cannot contain fields, and the com. Ms. win32.winx interface cannot pass this test. Because C # does not allow fields to be used in the interface, neither the intelliisense nor C # compiler can see these constants, but you can still access these fields using reflection, as shown below:

private int GetWin32IntConstant(string name){    System.Reflection.Assembly asm =     System.Reflection.Assembly.GetAssembly(typeof(com.ms.win32.wina));    Type t = asm.GetType("com.ms.win32.win" + char.ToLower(name[0]),                          true);    System.Reflection.FieldInfo info = t.GetField(name);    return int.Parse(info.GetValue(null).ToString());}

Using this technology to retrieve Windows API constants is slow, so you should be careful when using this method. Another problem is that constants cannot be parsed during compilation, so every time you spell them wrong, you will get a runtime error. In any case, declaring the majority of Windows APIs in the. NET program can save a lot of work. For example, the sharpzip sample program displays the system icons associated with the extension names of each file. Therefore, the Code calls the shgetfileinfo API defined in the com. Ms. win32.shell32 interface to obtain the icon handle (seeFigure 6).

Note that when you create a system. Drawing. Icon object from the handle, the new icon does not have this handle. This means that you must call the destroyicon API to release the associated resources. Because I do not want to store the icon handle for the entire lifetime of the icon object, I choose to create a copy of the object. Icon by using the copy constructor on the handle.

Although the namespace of COM. Ms. Win32 is huge, you should know that it does not contain every Windows API function and data structure. For example, the shbrowseforfolder API is a notable oversight of the COM. Ms. win32.shell32 interface. It allows us to display the "browse for folder" dialog box without using the Microsoft shell controls and automation com library.

Note that the processing callback is a bit complicated because the Java language does not support delegation. For each callback type, an abstract class that defines the function prototype is provided. You must derive code from this class to implement callback processing, and then pass an instance of this class to the API call (seeFigure 7). Another small difficulty related to the Java language is that parameters passed by reference are declared as arrays, but this only affects the code that calls these functions, without affecting basic functions.

Finally, some API calls are poorly converted. An example is waveoutopen (defined in the winmm class ). The dwcallback parameter is used in C ++ to pass the event handle, window handle, thread ID, or callback function, depending on the value of the fdwopen parameter. Since the J/direct packaging declares the dwcallback parameter as int32, and does not delegate the callback (delegate) to the typecast to int32, other notification mechanisms must be used, for example, event handle, window handle, or thread ID.

There are other interesting things in the core J # package. For example, Java. math. bigdecimal and Java. math. bigintegers allows you to manipulate any large number, which may be useful when you write an application to process encryption algorithms or scientific computing.

The csmath sample project shows how to use Java. Math. bigdecimal to calculate pi with any number after the decimal point using the Machin formula. To make the code easier to read, I wrapped java. Math. bigdecimal in my bigdecimal class and defined the most common operators.

Back to Top


Application Deployment

Applications using this technology require that J # Runtime Library and. NET Framework be installed on the target computer. Like. NET Framework, Microsoft provides a redistributable package that can be deployed with the application installer.

Microsoft already indicates that it will continue to support J # For the desktop operating system #. However, currently J # does not support. NET Compact framework. Therefore, you cannot apply the technology described in this article to smart device-oriented applications. Copying an assembly to the local project directory does not take effect because the J # Runtime Library depends heavily on local calls. However, you can make full use of the J # Runtime Library for Web applications that use mobile Web controls.

Back to Top


Summary

J # The Runtime Library contains many useful classes that can be used from other languages in. NET Framework. Some of these classes allow you to process ZIP files, perform high-precision mathematical calculations, or call windows APIs. Although most of this feature can be obtained by using a third-party library, the J # Runtime Library is fully supported by Microsoft and is free of charge!

For more information, see:

Java 911: parlez-vous J/direct?

For background information, see:

Http://msdn.microsoft.com/vjsharp/

What is the common language specification?

Ianier MunozIt is a software architect and analyst at dokumenta, a Luxembourg-based consulting company. He also created chronotron and other popular software. You can contact him via http://www.chronotron.com.

Go to the original English page

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.