Hej! Tyvärr är koden omöjlig att läsa, eftersom den inte är indenterad. Försök att lägga den mellan < code c++ > < /code > (utan mellanslag) och indentera ordentligt. tja, åtminstone Hoppsan! Hoppas det ser bättre ut nu. Synd att det inte finns någon preview. Ett litet trick för att läsa in en hel fil i minnet.Base64 omvandling
Problem:
Jag har en tid jobbat med att försöka konvertera innehållet i en binärfil (*.bmp) till en textsträng för att kunna lägga till den som en del av en befintlig textfil. Tanken är att jag vid behov ska kunna plocka ut den delen av textfilen som utgör den ”encodade” delen d.v.s. bitmappen i form av en textsträng igen, ”decoda” tillbaka den till en binär fil, en bitmap, vid ett senare tillfälle.
Problemet jag har är att jag kan encoda/decoda vanliga textsträngar men när jag ska decoda en binärfil te.x. bmp eller jpeg då får jag ut en mycket kort bit av filen, bara några k. Orginalfilen kan vara på te.x. 20kb ut kommer 1-3 kb. Det verkar som om den stöter på tecken som den inte klarar av att hantera. Jag (vi) vet att encodningen troligen fungerar okay då den är ganska beprövad. Nytt är behovet av att decoda tillbaka till en bitmap fil och det är då det skiter sig.
Jag har haft en diskussion igång på Microsoft som inte gav något då vi tycks ha ”pratat” förbi varandra. Jag valde att bryta då jag inte kände att det var meningsfullt. Men här är länken:
http://forums.microsoft.com/msdn/showpost.aspx?postid=2271777&siteid=1&sb=0&d=1&at=7&ft=11&tf=0&pageid=0
Förutsättningar:
Grundförutsättningarna är att jag idag jobbar i ett projekt som av olika skäl kompileras i VC++ 6.0 alltså en ganska gammal kompilator. Detta gör att jag inte har tillgång till nyare och smartare typ konverteringar
Nedan kod är kopplad till följande exempel från Microsoft:
http://support.microsoft.com/kb/191239
Här kommer de två funktioner som jag använder i mina encod/decod försök.
< code c++ >
///////////////////////////////////////////////////////////////////////////////
// DESCRIPTION:
// Creates base 64 code from file
// Returns true if everything is okay
//
// INPUT: strInputFile - Path to the file to be encoded
// OUTPUT: strOutput - The encoded file
//
bool encode_binary_to_base64( const CString& strInputFile, CString& strOutput )
{
bool blnReturn = false;
CStdioFile stdFileRead;
//Open and read binary file
int intInputFlags = CFile::modeRead | CFile::typeBinary;
if( stdFileRead.Open( strInputFile, intInputFlags ) )
{
//The source code come from Microsoft from
//http://support.microsoft.com/kb/191239
Base64Coder Coder;
//The size of the buffer to be created must be 75% of
//the string
const int intBufSize = 45;
unsigned char chBuffer[intBufSize];
bool blnStop = false;
// TimeOut to prevent never ending loops
int intTimeOut = 10000000;
// read and encode on line at the time.
for( int i = 0; ! blnStop && i < intTimeOut; ++i )
{
// How many characters have been read
// intBufSize gives you max number of characters that
//are allowed to be read at the time
int intCurrentSize = stdFileRead.Read( chBuffer, intBufSize );
//If theres not enough characters to fil the buffer
//it means that its the last line and we can
//leave the loop
if( intCurrentSize < intBufSize )
{
blnStop = true;
}
// encoding string in buffer.
Coder.Encode( chBuffer, intCurrentSize );
// Get the encoded string.
CString strEncoded = (LPCTSTR)Coder.EncodedMessage();
// exit if the string is empty
if( ! strEncoded.IsEmpty() )
{
blnReturn = true;
}
// Add a "\n" if it's not the last line
if( ! blnStop && i < intTimeOut-1 )
{
strEncoded += _T("\n");
}
// Add the encoded line to output.
strOutput += (LPCTSTR)strEncoded;
}
// close the file.
stdFileRead.Close();
}
return blnReturn;
}
///////////////////////////////////////////////////////////////////////////////
// DESCRIPTION:
// Decode base64-code
//
// INPUT: strInput - The encoded string
// OUTPUT: strOutstrOutputFile - Path to the file to be created.
//
bool decode_base64_to_binary( const CString& strInput, const CString& strOutputFile )
{
bool blnReturn = false;
// open a file
HANDLE hFile = ::CreateFile(strOutputFile, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, 0, NULL);
if (hFile != INVALID_HANDLE_VALUE)
{
//The source code come from Microsoft from
//http://support.microsoft.com/kb/191239
Base64Coder Coder;
//Wreckage from some testing I've done
//char *pEncodeData = "VGhpcyBpcyBhIHRlc3QgDQogT2YgdG
//hlIG\r\nxpbmUNCkJyZWFrcwlEb2RhLgAA=";
const CString testString = "VGhpcyBpcyBhIHRlc3QgDQogT2YgdGhlIG\r\nxpbmUNCkJyZWFrcwlEb2RhLgAA=";
//Convert CString to char
const char* pszText = testString ;
char *pEncodeData = (char *)pszText;
// Decode whats in the pEncodeData
Coder.Decode(pEncodeData);
CString strDencoded = (LPCTSTR)Coder.DecodedMessage();
// exit if the string is empty
if( ! strDencoded.IsEmpty() )
{
blnReturn = true;
}
CFile myFile((int) hFile);
myFile.SetFilePath(strOutputFile);
//Write to my newly created file
myFile.Write((LPCTSTR)strDencoded, strlen(strDencoded));
myFile.Flush();
myFile.Close();
}
else
{
blnReturn = true;
}
return blnReturn;
}
< /code >
Med vänliga hälsningar
KennetSv: Base64 omvandling
I princip så är ju grundregeln att det i filen kan finnas filslutstecken, och det bör du då kunna lösa genom att se till att filen läses binärt, och kolla med "riktiga" funktioner om den är slut. Du verkar åtminstone öppna binärt.
Hur som helst så borde du inte använda microsofts fulsträng, microsofts fulfilstream eller gamla char-arrayer. VC6 bör kunna arbeta med fstream och vector korrekt.
Principlösningen blir då:
{
std::ifstream f(...);
std::vector<unsigned char> v;
unsigned char c;
f >> c;
while(!f.eof())
{
v.push_back(c);
f >> c;
}
return encode(v);
}
Det är dock inte helt uppenbart vad problemet med din kod är, kan du beskriva vad det är för fel?
Sv: Base64 omvandling
strlen(strDencoded)
..låter ju som om det tar slut vid första \0 tecken
Sv:Base64 omvandling
Mvh/KennetSv: Base64 omvandling
<code>
// Öppna för läsning och append(!)
std::ifstream file(filename, std::ios:in|std::ios::binary|std::ios::ate);
// Vi är i slutet av filen så nuvarande position = längden
std::vector<unsigned char> data(file.tellg());
// hoppa tilbaka till början
file.seekg(0, std::ios::beg);
// läs in all data
file.read(&data[0], data.size());
file.close();
Base64Coder Coder;
Coder.Encode(&data[0], data.size());
cout << Code.EncodedMessage();
</code>