. NET implementation of merging files-practical tips

Source: Internet
Author: User

The files in the list above are not from all JPG files in a folder, but from

This file.
Merging multiple files into one file is useful in many areas of application. Implementing such a program in person is not only enjoyable, but it can help us build more efficient programs in many cases. Here I made a program to share with you.
Since the merged file is like a package, this file is referred to as the "package file"
Main idea:
To combine multiple files into a single package file, you can also distinguish one of the files and extract them. We need to know the name of the file and the location and length of the file in the package file, which is called the address offset.
Because the package file is often larger, it should not be allowed to reside in memory, and should be extracted from the package file only when it needs a certain part.
That's what I did:

A manager class that provides some peripheral methods
_pathlist is used to store the path to the file to be added to the package file by calling the Addsourcefile () method to add
_PF is a specific package file that generates an instance via Loadpackfile () and returns through the Currentpackfile property
Build method is used to generate package files

The Packfile class acts as a nested class of Packfilemanager, which provides properties and construction details for the package file.
Well, let's take a look at the Packfilemanager.build () method.

Copy Code code as follows:

public void Build (string path)
{
using (FileStream fs = new FileStream (path, FileMode.Create, FileAccess.Write))
{
BinaryWriter bw = new BinaryWriter (FS);
Bw. Write ("Packfile");
Bw. Write (This._pathlist.count);
foreach (string f in this._pathlist)
{
FileInfo fi = new FileInfo (f);
Bw. Write (FI. Length);
fi = null;
}
foreach (string f in this._pathlist)
{
Bw. Write (Path.getfilename (f));
}
foreach (string f in this._pathlist)
{
Bw. Write (File.readallbytes (f));
Bw. Flush ();
}
}
}

1. First write a "Packfile" string to the file header
2. The number of files to be output to the package file is written to the Int32 type.
3. The length of each file to be output to the package file is written as a long type.
4. and write each file name
5. Finally, the entity content for each file is written.
Due to frequent switching between the Write method and the different versions of the Readxxx method when writing or reading, I think it is more efficient to organize the file structure.

The question came. When we write the filename, we use BW. Write (Path.getfilename (f));
BinaryWriter.Write (string value) is invoked, and the string is passed in, then binaryreader.readstring () is invoked at the time of reading. This is how it distinguishes two string boundaries. Fortunately, the Write method first writes the length of the string as a four-byte unsigned integer, and it reads the value of a specific length based on that value when using binaryreader.readstring (), and is interpreted as a string.
Here are a few important ways to do this:

Copy Code code as follows:

The Loadpackfile method of Packfilemanager
public void Loadpackfile (string path)
{
if (! File.exists (PATH))
{
throw new FileNotFoundException (path);
}
if (_PF!= null)
{
_PF. Close ();
_PF = null;
}
FileStream fs = new FileStream (path, FileMode.Open, FileAccess.Read);
BinaryReader br = new BinaryReader (FS);
if (Br. ReadString ()!= "Packfile")
{
throw new Invalidcoalescentfileexception ("This file is not a valid package file");
}
THIS._PF = new Packfile (FS,BR);
}

At this point, the string "Packfile" We write at build has a clear function
Constructor for Packfile
Copy Code code as follows:

Internal Packfile (FileStream srcfile,binaryreader BR)
{
This._sourcefile = Srcfile;
_BR = BR;
This._filecount = _br. ReadInt32 ()//number of files taken
for (int i = 1; I <= _filecount; i++)
{
This._filelengthlist.add (_BR. ReadInt64 ());
}
for (int i = 1; I <= _filecount; i++)
{
This._shortnamelist.add (_BR. ReadString ());
}
This._contentstartpos = _sourcefile.position;//Set the total starting position of the entity file
}

Packfile.getbytes ()
Copy Code code as follows:

Public byte[] GetBytes (int index)
{
Long startpos = This._contentstartpos;
for (int i = 0; i < index; i++)
{
Startpos + = This._filelengthlist[i];
}
_sourcefile.position = startpos; Set the starting position of a file's contents
Return _BR. Readbytes ((int) _filelengthlist[index]);
}

This is just a draft, we can also add compression, or like a zip file, such as nested folder features, improved code do not forget to share with me oh.

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.