ちょっと脱線。
私はバイナリファイルを扱うときはこんなクラス使ってます。
ずーっと前に作ったもので、バイナリの読み書きはかれこれ2年ほどこれしか使ってません。
あんまりきれいなソースじゃないけど、参考にでも。
class Nomal{
public:
static void OpenFail(const char* fileName){}
};
// ファイルを一気に読み込むラッパー
template<class FailHandler>
class ReadOnlyFileBase{
public:
ReadOnlyFileBase(){
m_hFile = INVALID_HANDLE_VALUE;
}
~ReadOnlyFileBase(){
if( m_hFile != INVALID_HANDLE_VALUE) Close();
}
bool Good(){
return m_hFile != INVALID_HANDLE_VALUE;
}
bool Open(const char* fileName, const char* extection){
char temp[MAX_PATH];
sprintf(temp,%s.%s, fileName, extection);
return Open(temp);
}
bool Open(const char* fileName){
m_hFile = CreateFile
(fileName,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,
NULL);
if(m_hFile == INVALID_HANDLE_VALUE){
FailHandler::OpenFail(fileName);
return false;
}
return true;
}
BOOL Read(void* data, DWORD toRead, DWORD* read){
return ReadFile(m_hFile, data , toRead, read, NULL);
}
void Close(){
CloseHandle(m_hFile);
m_hFile = INVALID_HANDLE_VALUE;
}
HANDLE Detach(){
HANDLE ret = m_hFile;
m_hFile = INVALID_HANDLE_VALUE;
}
HANDLE m_hFile;
};
typedef ReadOnlyFileBase<Nomal> ReadOnlyFile;
// ファイルを一気に書き出すラッパー
template<class FailHandler>
class WriteOnlyFileBase
{
public:
WriteOnlyFileBase(){
m_hFile = INVALID_HANDLE_VALUE;
}
WriteOnlyFileBase(const char* fileName, const char* extection){
m_hFile = INVALID_HANDLE_VALUE;
Open(fileName, extection);
}
WriteOnlyFileBase(const char* fileName){
m_hFile = INVALID_HANDLE_VALUE;
Open(fileName);
}
~WriteOnlyFileBase(){
if( m_hFile != INVALID_HANDLE_VALUE) Close();
}
bool Good(){
return m_hFile != INVALID_HANDLE_VALUE;
}
bool Open(const char* fileName, const char* extection){
char temp[MAX_PATH];
sprintf(temp,%s.%s, fileName, extection);
return Open(temp);
}
bool Open(const char* fileName){
m_hFile = CreateFile(fileName, GENERIC_WRITE, FILE_SHARE_READ, NULL,
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if(m_hFile == INVALID_HANDLE_VALUE){
FailHandler::OpenFail(fileName);
return false;
}
return true;
}
BOOL Write(const void* data, DWORD toRead, DWORD* wrtten){
return WriteFile(m_hFile, data , toRead, wrtten, NULL);
}
void Close(){
CloseHandle(m_hFile);
m_hFile = INVALID_HANDLE_VALUE;
}
HANDLE Detach(){
HANDLE ret = m_hFile;
m_hFile = INVALID_HANDLE_VALUE;
}
HANDLE m_hFile;
};
typedef WriteOnlyFileBase<Nomal> WriteOnlyFile;
前回の次のコードなんですが、
UINT nBytesRead = inFile.Read(&m_UINT, sizeof(UINT));
wsprintf (chHEX, %08x, m_UINT);
str = 0x;
str += chHEX;
m_float = (float)strtol(str, &err, 16);
結局次のコードと同じでした。
UINT nBytesRead = inFile.Read(&m_UINT, sizeof(UINT));
m_float = (float)m_UINT;
言い訳なんですが、
バイナリエディッタの 01 AA DF BD 3A ... をfloat型に変換するイメージでした。
>できた結果を、逆に変換しなおす場合はどのような宣言をしてあげればいいんですか??
次のコードで、丸め誤差が発生します。
m_float = (float)m_UINT;
m_float = (float)strtol(str, &err, 16);
発生した誤差は元に戻せないと思います。
VC++ 超初心者のほ~むぺ~じ
の過去ログ 04927 ビット配列をfloatに変換
というのもあります。
>複数のデータをファイルに書込むときはどのようにすればいいんですか??
while (1)
{
nBytesRead = inFile.Read(&m_float, sizeof(float));
if (nBytesRead < sizeof(float)) // if (nBytesRead == 0)
break;
outFile.Write(&m_float, sizeof(float));
/*
次のコード (float を int に変更) でも結果は同じだと思います。
nBytesRead = inFile.Read(&m_int, sizeof(int));
if (nBytesRead < sizeof(int)) // if (nBytesRead == 0)
break;
outFile.Write(&m_int, tsizeof(int));
*/
}
PAIさんへ 今までWIN32のAPIを直接使ってました。
参考にさせていただきます♪☆