zoukankan      html  css  js  c++  java
  • c# 将多个文件保存为一个文件并将文件拆分开来

    本文介绍的是用C#实现把多个文件写入到一个文件中去并且能分解,对于一个文件的读写,其实很简单,就是用FileStream进行Read或者Write就行了。但是如何把多个文件写入到同一个文件,之后要能把这个文件进行还原成多个文件。那么光靠FileStream的Read和Write方法是不够的,首先你需要自行建立文件索引,来标明每个文件在当前文件的位置。

    那么最近作了一个简单的DEMO,其中类的部分代码如下:

    //------------------------------- Compose Files ------------
    //-------------------------------------------------------
    //---File:clsComposeFiles.cs
    //---Description:This file is to show how-to compose multi-files into one file
    //               and decompose one file to multi-files.
    //---Author:Knight
    //---Date:May.16, 2006
    //---------------------------------------------------
    //------------------------------{ Compose Files }-------

    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;

            }

        }

    }

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

    之后的调用就很简单,例如:

    合成文件:

        clsComposeFiles myComposeFiles = new clsComposeFiles();

        myComposeFiles.AddFile( @"D:\Ship.exe" );

        myComposeFiles.AddFile( @"D:\LoginPage.JPG" );

      myComposeFiles.ComposeFiles( @"D:\Ship.dat" );

    分解文件:

        clsComposeFiles myComposeFiles = new clsComposeFiles();

        myComposeFiles.DecomposeFile( @"D:\Ship.dat", @"E:\" );

    以上代码由于写得比较急,细节处理并不是很完善,因此在使用的时候要加以细化了。

     

    本文来自: IT知道网(http://www.itwis.com) 详细出处参考:http://www.itwis.com/html/net/c/20081205/3050.html

  • 相关阅读:
    hdu 3415 Max Sum of MaxKsubsequence
    poj 2243 Knight Moves
    【LCD手册】飞凌3.5/4.3/5.6/7/8 寸LCD手册大全下载
    【转载zq2002好文章】Windows CE 休眠唤醒全面解析(基于2440平台)(1)(2)(3)
    【转载】如果做到窗口自动适应不同尺寸屏幕的尺寸?
    【转载】wince6.0+s3c6410摄像头驱动修改
    推荐一个比较活跃的ARM/WinCE/LinuxQQ群
    【转载】微软的USB摄像头驱动,
    【收集】ARM+WinCE QQ 群
    【转载】S3C6410移植日记系列
  • 原文地址:https://www.cnblogs.com/butterfly/p/1373047.html
Copyright © 2011-2022 走看看