多个文件写入到一个文件里

来源:互联网 发布:sql数据库安全防护 编辑:程序博客网 时间:2024/05/01 14:20

/*
 * 其中类的操作参看clsComposeFiles这个类,而文件索引结构参看FileIndex这个Structure。
 *
 *
*/
namespace ComposeFiles
{

    using System;

    using System.IO;

    using System.Collections;

    using System.Text;

 

    /// <summary>

    /// Summary description for clsComposeFiles.

    /// </summary>

    public class clsComposeFiles
    {

        private ArrayList arrFiles = new ArrayList();

 

        public clsComposeFiles()
        {

            //

            // TODO: Add constructor logic here

            //

        }

 

        /// <summary>

        /// Add a file to be composed

        /// </summary>

        /// <param name="sFileName"></param>

        public void AddFile(string sFileName)
        {

            arrFiles.Add(sFileName);

        }

 

        /// <summary>

        /// Compose files to the specific file

        /// </summary>

        /// <param name="sFileName"></param>

        /// <returns></returns>

        public bool ComposeFiles(string sFileName)
        {

            if (arrFiles.Count == 0) return false;

 

            FileInfo fi = new FileInfo(sFileName);

            // Open file to write

            FileStream fsWriter = null;

            try
            {

                if (!fi.Exists)
                {

                    fsWriter = new FileStream(

                        sFileName,

                        FileMode.CreateNew,

                        FileAccess.ReadWrite,

                        FileShare.None);

                }

                else

                    fsWriter = new FileStream(

                        sFileName,

                        FileMode.Truncate,

                        FileAccess.ReadWrite,

                        FileShare.None);

            }

            catch (Exception err)
            {

                System.Diagnostics.Debug.WriteLine(err.Message);

                return false;

            }

 

            byte[] bBuffer = null;

            // Write files count

            bBuffer = FileIndex.LongToBytes(arrFiles.Count);

            fsWriter.Write(bBuffer, 0, 8);

 

            const long INDEX_START_POS = 8L;

            // Init files index

            FileIndex FI = new FileIndex();

            for (int i = 0; i < arrFiles.Count; i++)

                fsWriter.Write(FileIndex.ConvertToBytes(ref FI), 0, 32);

 

            long FILE_START_POS = INDEX_START_POS + 32 * arrFiles.Count;

            long lCurFileStartPos = FILE_START_POS;

 

            // Write every file

            for (int i = 0; i < arrFiles.Count; i++)
            {

                WriteFile(arrFiles[i].ToString(),

                    ref lCurFileStartPos,

                    INDEX_START_POS,

                    fsWriter,

                    i);

            }

 

            // Close stream

            fsWriter.Close();

            return true;

        }

 

        /// <summary>

        /// Write file name and data into composed file

        /// </summary>

        /// <param name="sFileName"></param>

        /// <param name="FileStartPos"></param>

        /// <param name="IndexStartPos"></param>

        /// <param name="fsWriter"></param>

        /// <param name="Index"></param>

        private void WriteFile(

            string sFileName,

            ref long FileStartPos,

            long IndexStartPos,

            FileStream fsWriter,

            int Index)
        {

            FileInfo fi = new FileInfo(sFileName);

            if (!fi.Exists) return;

 

            FileStream fsReader = null;

            try
            {

                fsReader = new FileStream(

                    sFileName, FileMode.Open,

                    FileAccess.Read);

            }

            catch { return; }

 

            // Get file name

            byte[] bFileName = Encoding.Unicode.GetBytes(fi.Name);

            // Write file name

            fsWriter.Write(bFileName, 0, bFileName.Length);

 

            const int BUFFER_LENGTH = 1024;

            byte[] bBuffer = new byte[BUFFER_LENGTH];

            int nRealRead = 0;

            // Write data using

            do
            {

                // Read data from file

                nRealRead = fsReader.Read(bBuffer, 0,

                    BUFFER_LENGTH);

                // Write data

                fsWriter.Write(bBuffer, 0, nRealRead);

            } while (nRealRead > 0);

            // Close file reader

            fsReader.Close();

 

            FileIndex FINew = new FileIndex();

            FINew.NameStartPos = FileStartPos;

            FINew.NameLength = bFileName.Length;

            FINew.FileStartPos = FileStartPos + bFileName.Length;

            FINew.FileLength = fi.Length;

 

            // Go back to file index position

            fsWriter.Seek(IndexStartPos + Index * 32, SeekOrigin.Begin);

 

            // Write file index info

            fsWriter.Write(FileIndex.ConvertToBytes(ref FINew), 0, 32);

 

            // Go back to file end

            fsWriter.Seek(0, SeekOrigin.End);

 

            // Set file current position

            FileStartPos += bFileName.Length + fi.Length;

        }

 

        /// <summary>

        /// Decompose file to multi files into specific directory

        /// </summary>

        /// <param name="sFileName"></param>

        /// <param name="sDestDir"></param>

        /// <returns></returns>

        public bool DecomposeFile(string sFileName, string sDestDir)
        {

            FileInfo fi = new FileInfo(sFileName);

            if (!fi.Exists) return false;

 

            FileStream fsReader = null;

            try
            {

                fsReader = new FileStream(

                    sFileName, FileMode.Open,

                    FileAccess.Read);

            }

            catch { return false; }

 

            // Read file count

            byte[] bFileCount = new byte[8];

            int nRealRead = 0;

            nRealRead = fsReader.Read(bFileCount, 0, 8);

            if (nRealRead != 8)
            {

                fsReader.Close();

                return false;

            }

 

            long lFileCount = FileIndex.BytesToLong(bFileCount);

            if (lFileCount > 0)
            {

                //Init file index array

                FileIndex[] fiArray = new FileIndex[lFileCount];

                byte[] bFileIndex = new byte[32];

                for (int i = 0; i < lFileCount; i++)
                {

                    fsReader.Read(bFileIndex, 0, 32);

                    fiArray[i] = FileIndex.ConvertToFileIndex(bFileIndex);

                }

 

                if (sDestDir[sDestDir.Length - 1] != '//')

                    sDestDir += "//";

                // Save every file into current directory

                for (int i = 0; i < fiArray.Length; i++)
                {

                    SaveFile(fsReader,

                        ref fiArray[i],

                        sDestDir);

                }

            }

 

            // Close file reader

            fsReader.Close();

            return true;

        }

 

        /// <summary>

        /// Save every file into directory

        /// </summary>

        /// <param name="fsReader"></param>

        /// <param name="FI"></param>

        /// <param name="sDestDir"></param>

        private void SaveFile(

            FileStream fsReader,

            ref FileIndex FI,

            string sDestDir)
        {

            // Read file name

            byte[] bFileName = new byte[FI.NameLength];

            int nRealRead = fsReader.Read(bFileName, 0, bFileName.Length);

            if (nRealRead != bFileName.Length) return;

            string sFileName = Encoding.Unicode.GetString(bFileName);

            sFileName = sDestDir + sFileName;

            FileInfo fi = new FileInfo(sFileName);

            // Open file to write

            FileStream fsWriter = null;

            try
            {

                if (!fi.Exists)
                {

                    fsWriter = new FileStream(

                        sFileName,

                        FileMode.CreateNew,

                        FileAccess.ReadWrite,

                        FileShare.None);

                }

                else

                    fsWriter = new FileStream(

                        sFileName,

                        FileMode.Truncate,

                        FileAccess.ReadWrite,

                        FileShare.None);

            }

            catch (Exception err)
            {

                System.Diagnostics.Debug.WriteLine(err.Message);

                return;

            }

 

            // Init buffer 

            const int BUFFER_LENGTH = 1024;

            byte[] bBuffer = new byte[BUFFER_LENGTH];

            long lLeft = FI.FileLength;

 

            // Copy file

            do
            {

                if (lLeft > BUFFER_LENGTH)
                {

                    fsReader.Read(bBuffer, 0, BUFFER_LENGTH);

                    fsWriter.Write(bBuffer, 0, BUFFER_LENGTH);

 

                    lLeft -= BUFFER_LENGTH;

                }

                else
                {

                    nRealRead = fsReader.Read(bBuffer, 0, (int)lLeft);

                    fsWriter.Write(bBuffer, 0, nRealRead);

 

                    lLeft -= nRealRead;

                }

            }

            while (lLeft > 0);

 

            // close file writer

            fsWriter.Close();

        }

    }

 

    /// <summary>

    /// File index data structure

    /// </summary>

    public struct FileIndex
    {

        public long NameStartPos;

        public long NameLength;

        public long FileStartPos;

        public long FileLength;

 

        public static byte[] ConvertToBytes(ref FileIndex FI)
        {

            byte[] bData = new byte[32];

 

            Array.Copy(LongToBytes(FI.NameStartPos), 0, bData, 0, 8);

            Array.Copy(LongToBytes(FI.NameLength), 0, bData, 8, 8);

            Array.Copy(LongToBytes(FI.FileStartPos), 0, bData, 16, 8);

            Array.Copy(LongToBytes(FI.FileLength), 0, bData, 24, 8);

 

            return bData;

        }

 

        public static byte[] LongToBytes(long lValue)
        {

            byte[] bData = new byte[8];

 

            bData[0] = (byte)((lValue >> 56) & 0xFF);

            bData[1] = (byte)((lValue >> 48) & 0xFF);

            bData[2] = (byte)((lValue >> 40) & 0xFF);

            bData[3] = (byte)((lValue >> 32) & 0xFF);

            bData[4] = (byte)((lValue >> 24) & 0xFF);

            bData[5] = (byte)((lValue >> 16) & 0xFF);

            bData[6] = (byte)((lValue >> 8) & 0xFF);

            bData[7] = (byte)(lValue & 0xFF);

            return bData;

        }

 

        public static FileIndex ConvertToFileIndex(byte[] bData)
        {

            if (bData == null || bData.Length != 32)

                throw new Exception("Invalid parameters!");

 

            FileIndex FI = new FileIndex();

            byte[] bBuffer = new byte[8];

            Array.Copy(bData, 0, bBuffer, 0, 8);

            FI.NameStartPos = BytesToLong(bBuffer);

            Array.Copy(bData, 8, bBuffer, 0, 8);

            FI.NameLength = BytesToLong(bBuffer);

            Array.Copy(bData, 16, bBuffer, 0, 8);

            FI.FileStartPos = BytesToLong(bBuffer);

            Array.Copy(bData, 24, bBuffer, 0, 8);

            FI.FileLength = BytesToLong(bBuffer);

            return FI;

        }

 

        public static long BytesToLong(byte[] bData)
        {

            if (bData == null || bData.Length != 8)

                throw new Exception("Invalid parameters!");

 

            long lngValue = 0;

            lngValue += bData[0];

            lngValue = (lngValue << 8);

            lngValue += bData[1];

            lngValue = (lngValue << 8);

            lngValue += bData[2];

            lngValue = (lngValue << 8);

            lngValue += bData[3];

            lngValue = (lngValue << 8);

            lngValue += bData[4];

            lngValue = (lngValue << 8);

            lngValue += bData[5];

            lngValue = (lngValue << 8);

            lngValue += bData[6];

            lngValue = (lngValue << 8);

            lngValue += bData[7];

            return lngValue;

        }

    }

}

 

 

 

 

    protected void Button1_Click(object sender, EventArgs e)
    {
        clsComposeFiles myComposeFiles = new clsComposeFiles();

        myComposeFiles.AddFile(@"E:/ffff/product2.csv");

        myComposeFiles.AddFile(@"E:/ffff/150no.JPG");
        //将product2.csv文件和150no.JPG合并生成admin2_css.css文件
        myComposeFiles.ComposeFiles(@"E:/ffff/admin2_css.css");

    }
    protected void Button2_Click(object sender, EventArgs e)
    {
        clsComposeFiles myComposeFiles = new clsComposeFiles();
        //将admin2_css.css文件分解保存到,E:/ffff/ddd/目录下
        myComposeFiles.DecomposeFile(@"E:/ffff/admin_css.css", @"E:/ffff/ddd/");

    }