none
How to copy the content of a CFile to CMemFile? RRS feed

Answers

  • Hello,

    I'd say, about this way:

    CFile f;
    bool b = f.Open( L"C:\\test.txt",  CFile::modeReadWrite);
    int Length = f.GetLength();
    BYTE* buffer = new BYTE[Length];
    f.Read((void*)buffer,Length);
    f.Close();
    CMemFile memFile;
    memFile.Attach(buffer, Length);

    Regards, Guido


    Monday, April 15, 2019 7:27 AM
  • Hello,

    I'd say, about this way:

    CFile f;
    bool b = f.Open( L"C:\\test.txt",  CFile::modeReadWrite);
    int Length = f.GetLength();
    BYTE* buffer = new BYTE[Length];
    f.Read((void*)buffer,Length);
    f.Close();
    CMemFile memFile;
    memFile.Attach(buffer, Length);

    Regards, Guido


    thank you for the reply.

    I tried to append data to memfile using below code.

    CFile f;
    bool b1 = f.Open( L"C:\\test.txt",  CFile::modeReadWrite);
    int Length = f.GetLength();
    unsigned char* buffer = new unsigned char[Length];
    f.Read(buffer, Length);
    CMemFile memFile;
    memFile.Attach(buffer, Length, 0);
    f.Close();
    memFile.Seek(0,CFile::end);
    memFile.Write("Hai",3);
    	

    But memFile.Write crashes with ASSERT(m_nGrowBytes != 0);

    void CMemFile::GrowFile(SIZE_T dwNewLen)
    {
    	ASSERT_VALID(this);
    
    	if (dwNewLen > m_nBufferSize)
    	{
    		// grow the buffer
    		SIZE_T dwNewBufferSize = m_nBufferSize;
    
    		// watch out for buffers which cannot be grown!
    		ASSERT(m_nGrowBytes != 0);
    If I set some values for nGrowBytes in memFile.Attach function, the function memFile.Seek(0,CFile::end); is not seeting the position at the end.

    The original question was about how to copy a CFile buffer to a CMemFile. So, this question is answerd.

    Now you want to expand your question and add data to the memfile buffer. Then you must set nGrowBytes. Just read the documentation of CMemFile. For nGrowBytes:

    "If nGrowBytes is 0, CMemFile will set the file length to nBufferSize. This means that the data in the memory block before it was attached to CMemFile will be used as the file. Memory files created in this manner cannot be grown.

    Since the file cannot be grown, be careful not to cause CMemFile to attempt to grow the file. For example, don't call the CMemFile overrides of CFile:Write to write past the end or don't call CFile:SetLength with a length longer than nBufferSize.

    If nGrowBytes is greater than 0, CMemFile will ignore the contents of the memory block you've attached. You'll have to write the contents of the memory file from scratch using the CMemFile override of CFile::Write. If you attempt to write past the end of the file or grow the file by calling the CMemFile override of CFile::SetLength, CMemFile will grow the memory allocation in increments of nGrowBytes. Growing the memory allocation will fail if the memory block you pass to Attach wasn't allocated with a method compatible with Alloc. To be compatible with the default implementation of Alloc, you must allocate the memory with the run-time library function malloc or calloc."

    Regards, Guido


    Monday, April 15, 2019 8:02 AM

All replies

  • Hello,

    a CMemFile is a CFile:

    class CMemFile : public CFile

    https://docs.microsoft.com/en-us/cpp/mfc/reference/cmemfile-class?view=vs-2019

    So it is the same when you load the whole contents to a CFile or a CMemFile.

    Use CFile::Read: https://docs.microsoft.com/en-us/cpp/mfc/reference/cfile-class?view=vs-2019#read

    Regards, Guido


    Monday, April 15, 2019 6:30 AM
  • Hello,

    a CMemFile is a CFile:

    class CMemFile : public CFile

    https://docs.microsoft.com/en-us/cpp/mfc/reference/cmemfile-class?view=vs-2019

    So it is the same when you load the whole contents to a CFile or a CMemFile.

    Use CFile::Read: https://docs.microsoft.com/en-us/cpp/mfc/reference/cfile-class?view=vs-2019#read

    Regards, Guido


    I tried below code 

    CMemFile memFile;
    bool b = memFile.Open( L"C:\\test.txt",  CFile::modeReadWrite);
    int Length = memFile.GetLength();
    unsigned char* buffer = new unsigned char[Length];
    memFile.Read((void*)buffer,Length);
    memFile.Close();

    But memFile.GetLength returns 0. whereas if I try with CFile GetLength()  returns some valid length

    CFile f;
    bool b1 = f.Open( L"C:\\test.txt",  CFile::modeReadWrite);
    int Lengh = f.GetLength();
    f.Close();

    Thanks.


    • Edited by sgrm123 Monday, April 15, 2019 6:46 AM
    Monday, April 15, 2019 6:46 AM
  • Given the lack of detail in your query, does the following help:

         Use the CFile::GetLength method to determine the amount of data in the source file.
         Allocate memory to hold this data.
         Use the CMemFile::Attach method to attach the allocated memory to the target file.
         Use the CFile::Read method to read the data from the source file into a buffer.
         Use the inherited CMemFile::Write method to write the data from the buffer to the target file
         Repeat the last two steps until all the data has been copied.

    Monday, April 15, 2019 6:46 AM
  • Given the lack of detail in your query, does the following help:

         Use the CFile::GetLength method to determine the amount of data in the source file.
         Allocate memory to hold this data.
         Use the CMemFile::Attach method to attach the allocated memory to the target file.
         Use the CFile::Read method to read the data from the source file into a buffer.
         Use the inherited CMemFile::Write method to write the data from the buffer to the target file
         Repeat the last two steps until all the data has been copied.

    I am not clear with your steps, whether I need two file pointer?.Could you please provide code snippet?

    Thanks in advance.



    • Edited by sgrm123 Monday, April 15, 2019 7:10 AM
    Monday, April 15, 2019 6:52 AM
  • Hello,

    I'd say, about this way:

    CFile f;
    bool b = f.Open( L"C:\\test.txt",  CFile::modeReadWrite);
    int Length = f.GetLength();
    BYTE* buffer = new BYTE[Length];
    f.Read((void*)buffer,Length);
    f.Close();
    CMemFile memFile;
    memFile.Attach(buffer, Length);

    Regards, Guido


    Monday, April 15, 2019 7:27 AM
  • Hello,

    I'd say, about this way:

    CFile f;
    bool b = f.Open( L"C:\\test.txt",  CFile::modeReadWrite);
    int Length = f.GetLength();
    BYTE* buffer = new BYTE[Length];
    f.Read((void*)buffer,Length);
    f.Close();
    CMemFile memFile;
    memFile.Attach(buffer, Length);

    Regards, Guido


    thank you for the reply.

    I tried to append data to memfile using below code.

    CFile f;
    bool b1 = f.Open( L"C:\\test.txt",  CFile::modeReadWrite);
    int Length = f.GetLength();
    unsigned char* buffer = new unsigned char[Length];
    f.Read(buffer, Length);
    CMemFile memFile;
    memFile.Attach(buffer, Length, 0);
    f.Close();
    memFile.Seek(0,CFile::end);
    memFile.Write("Hai",3);
    	

    But memFile.Write crashes with ASSERT(m_nGrowBytes != 0);

    void CMemFile::GrowFile(SIZE_T dwNewLen)
    {
    	ASSERT_VALID(this);
    
    	if (dwNewLen > m_nBufferSize)
    	{
    		// grow the buffer
    		SIZE_T dwNewBufferSize = m_nBufferSize;
    
    		// watch out for buffers which cannot be grown!
    		ASSERT(m_nGrowBytes != 0);
    If I set some values for nGrowBytes in memFile.Attach function, the function memFile.Seek(0,CFile::end); is not seeting the position at the end.

    Monday, April 15, 2019 7:43 AM
  • Hello,

    I'd say, about this way:

    CFile f;
    bool b = f.Open( L"C:\\test.txt",  CFile::modeReadWrite);
    int Length = f.GetLength();
    BYTE* buffer = new BYTE[Length];
    f.Read((void*)buffer,Length);
    f.Close();
    CMemFile memFile;
    memFile.Attach(buffer, Length);

    Regards, Guido


    thank you for the reply.

    I tried to append data to memfile using below code.

    CFile f;
    bool b1 = f.Open( L"C:\\test.txt",  CFile::modeReadWrite);
    int Length = f.GetLength();
    unsigned char* buffer = new unsigned char[Length];
    f.Read(buffer, Length);
    CMemFile memFile;
    memFile.Attach(buffer, Length, 0);
    f.Close();
    memFile.Seek(0,CFile::end);
    memFile.Write("Hai",3);
    	

    But memFile.Write crashes with ASSERT(m_nGrowBytes != 0);

    void CMemFile::GrowFile(SIZE_T dwNewLen)
    {
    	ASSERT_VALID(this);
    
    	if (dwNewLen > m_nBufferSize)
    	{
    		// grow the buffer
    		SIZE_T dwNewBufferSize = m_nBufferSize;
    
    		// watch out for buffers which cannot be grown!
    		ASSERT(m_nGrowBytes != 0);
    If I set some values for nGrowBytes in memFile.Attach function, the function memFile.Seek(0,CFile::end); is not seeting the position at the end.

    The original question was about how to copy a CFile buffer to a CMemFile. So, this question is answerd.

    Now you want to expand your question and add data to the memfile buffer. Then you must set nGrowBytes. Just read the documentation of CMemFile. For nGrowBytes:

    "If nGrowBytes is 0, CMemFile will set the file length to nBufferSize. This means that the data in the memory block before it was attached to CMemFile will be used as the file. Memory files created in this manner cannot be grown.

    Since the file cannot be grown, be careful not to cause CMemFile to attempt to grow the file. For example, don't call the CMemFile overrides of CFile:Write to write past the end or don't call CFile:SetLength with a length longer than nBufferSize.

    If nGrowBytes is greater than 0, CMemFile will ignore the contents of the memory block you've attached. You'll have to write the contents of the memory file from scratch using the CMemFile override of CFile::Write. If you attempt to write past the end of the file or grow the file by calling the CMemFile override of CFile::SetLength, CMemFile will grow the memory allocation in increments of nGrowBytes. Growing the memory allocation will fail if the memory block you pass to Attach wasn't allocated with a method compatible with Alloc. To be compatible with the default implementation of Alloc, you must allocate the memory with the run-time library function malloc or calloc."

    Regards, Guido


    Monday, April 15, 2019 8:02 AM
  • I tried below code 

    CMemFile memFile;
    bool b = memFile.Open( L"C:\\test.txt",  CFile::modeReadWrite);
    int Length = memFile.GetLength();
    unsigned char* buffer = new unsigned char[Length];
    memFile.Read((void*)buffer,Length);
    memFile.Close();

    But memFile.GetLength returns 0. whereas if I try with CFile GetLength()  returns some valid length

    CFile f;
    bool b1 = f.Open( L"C:\\test.txt",  CFile::modeReadWrite);
    int Lengh = f.GetLength();
    f.Close();

    CMemFile cannot point to a disk file.  It points to a memory file.  Since you did not put anything in memFile, what did you expect memFile.GetLength to return?
    Monday, April 15, 2019 4:16 PM
  • Given the lack of detail in your query, does the following help:

         Use the CFile::GetLength method to determine the amount of data in the source file.
         Allocate memory to hold this data.
         Use the CMemFile::Attach method to attach the allocated memory to the target file.
         Use the CFile::Read method to read the data from the source file into a buffer.
         Use the inherited CMemFile::Write method to write the data from the buffer to the target file
         Repeat the last two steps until all the data has been copied.

    I am not clear with your steps, whether I need two file pointer?.Could you please provide code snippet?

    Thanks in advance.



    You said you wanted to copy data from a CFile to a CMemFile.  Since those are two different types of objects, how do you think you could do it with less than two?

    Even if they were the same type of object, such as regular FILE pointers as defined in the standard headers instead of a Microsoft class, how many would you need to read from one and write to the other?

    There are code snippets in the Microsoft documentation available at
    https://docs.microsoft.com/en-us/cpp/mfc/reference/cfile-class?view=vs-2019 and
    https://docs.microsoft.com/en-us/cpp/mfc/reference/cmemfile-class?view=vs-2019.

    Monday, April 15, 2019 4:24 PM