如何把多个文件写入到一个文件中去并能分解

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

 

那么最近作了一个简单的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:/" );

 

以上代码由于写得比较急,细节处理并不是很完善,因此使用的时候要加以细化,甚至可以在我的基础上进行扩充。

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
### 回答1: 可以通过以下代码实现: ```python import os # 获取所有txt文件的路径 txt_files = [f for f in os.listdir() if f.endswith('.txt')] # 合并并保存文件 with open('merged_files.txt', 'w') as merged_file: for file_path in txt_files: with open(file_path, 'r') as f: content = f.read() merged_file.write(f'---{file_path}---\n') merged_file.write(content) ``` 这段代码会将当前目录下所有以`.txt`结尾的文件合并,并在合并后的文件中添加每个文件文件名作为分隔符。最终合并后的文件名为`merged_files.txt`。 ### 回答2: 要合并多个txt文件并保存txt文件名称,我们可以使用Python的文件操作方法来实现。 首先,我们需要确定要合并的txt文件目录。假设这些文件都存储在同一文件夹下,并且我们将其命名为"txt_files"。 然后,我们可以使用os模块的listdir函数来获取该目录下所有的文件名。我们将这些文件名保存到一个列表中,以供后续使用。 接下来,我们可以使用Python的文件操作方法来逐个打开每个txt文件,并读取其中的内容。可以使用with关键字来确保文件的正确关闭。我们将每个文件的内容添加到一个字符串变量中,并在每个文件内容之间添加一个换行符。 最后,我们可以使用Python的文件操作方法来创建一个新的txt文件,并将合并后的内容写入文件中。为了保存每个原始txt文件的名称,我们可以在合并后的内容中添加一个标识符,用于指示每个文件的开始。 下面是具体的Python代码实现: ``` import os # 获取txt文件目录 folder_path = "txt_files" # 保存合并后的文件内容 merged_content = "" # 获取目录下所有txt文件文件file_names = os.listdir(folder_path) # 逐个打开txt文件并读取内容 for file_name in file_names: file_path = os.path.join(folder_path, file_name) with open(file_path, 'r') as file: txt_content = file.read() # 将每个文件的内容添加到merged_content变量中,并在每个文件内容之间添加换行符 merged_content += f"--- {file_name} ---\n{txt_content}\n\n" # 创建新的txt文件写入合并后的内容 merged_file_path = "merged_file.txt" with open(merged_file_path, 'w') as merged_file: merged_file.write(merged_content) print("合并完成!合并后的内容保存在merged_file.txt文件中。") ``` 此代码将在同级目录下创建一个名为"merged_file.txt"的新文件,其中包含了所有要合并的txt文件的内容,每个文件的开始都有一个标识符指示其名称。 ### 回答3: Python可以通过使用文件处理和字符串处理的功能来合并多个txt文件并保存txt文件名称。 首先,我们需要使用Python的文件处理功能来打开和读取每个txt文件。我们可以使用`open()`函数来打开每个文件,并使用`.read()`方法来读取文件内容。然后,我们可以使用字符串处理功能来将每个文件的内容保存到一个字符串变量中。 接下来,我们可以使用字符串处理的功能来保存每个txt文件的名称。我们可以使用`split()`函数将文件路径分解文件夹路径和文件名,然后使用`os.path.basename()`函数来获取文件名。我们可以将每个文件名保存到一个列表中。 最后,我们可以使用Python的文件处理功能来创建一个新的txt文件,并将我们所保存的所有文件内容全部写入到这个文件中。我们可以使用`open()`函数创建一个新的txt文件,并使用`.write()`方法将之前保存的合并内容写入文件中。同时,我们也可以使用之前保存的文件名列表来创建一个新的txt文件来保存每个txt文件的名称。 下面是一个示例的代码,展示了如何实现合并多个txt文件并保存txt文件名称。 ``` python import os # 合并多个txt文件 txt_files = ['file1.txt', 'file2.txt', 'file3.txt'] # txt文件列表 merged_content = '' # 保存合并后的内容 for file in txt_files: with open(file, 'r') as f: content = f.read() merged_content += content # 保存合并后的txt文件 merged_file = 'merged.txt' with open(merged_file, 'w') as f: f.write(merged_content) # 保存txt文件名称 file_names = [] for file in txt_files: file_name = os.path.basename(file) file_names.append(file_name) # 保存txt文件名称到新的txt文件 name_file = 'file_names.txt' with open(name_file, 'w') as f: for name in file_names: f.write(name + '\n') ``` 使用上述代码,我们将会合并`file1.txt`,`file2.txt`和`file3.txt`的内容,并将合并的内容保存到`merged.txt`文件中。同时,我们也将保存每个txt文件的名称到`file_names.txt`文件中。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值