在用c语言解决固定大小文件的读写问题 时,仅仅实现了任意位置的读,但是只能在文件末尾添加新内容,文件指针的定位对写入操作没有任何作用,初始程序如下:
#include "stdlib.h"
#include "stdio.h"
typedef struct
{
int processRecordCounter;//当前生产记录个数
int runInformationCounter;//当前运行记录个数
}PROCESS_INFOR_COUNTER;
int main(int argc, char* argv[])
{
FILE* fp;
int pos;
PROCESS_INFOR_COUNTER pi;
fp = fopen("test","ab+");
//读取记录个数
if (fseek(fp, 0 - sizeof(PROCESS_INFOR_COUNTER), SEEK_END) < 0)//第一次写记录
{
pi.processRecordCounter = 0;
pi.runInformationCounter = 0;
}else
{
pos = ftell(fp);
rewind(fp);
pos = ftell(fp);
fread(&pi,sizeof(PROCESS_INFOR_COUNTER), 1, fp);
pos = ftell(fp);
pi.processRecordCounter = 10;
pi.runInformationCounter = 10;
}
rewind(fp);
pos = fseek(fp,0L, 0);
pos = ftell(fp);
pos = fwrite(&pi, sizeof(PROCESS_INFOR_COUNTER), 1, fp);
pos = ftell(fp);
fclose(fp);
return 0;
}
为了解决随机的读写问题,在此采用了文件内存方法:改进后程序如下所示:
// file.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "stdlib.h"
#include "stdio.h"
#include "windows.h"
typedef struct
{
int processRecordCounter;//当前生产记录个数
int runInformationCounter;//当前运行记录个数
}PROCESS_INFOR_COUNTER;
typedef struct
{
int produceNumber;//生产次数
int craftID;//工艺编号
char starttime[30]; //开始时间
char endtime[30]; //结束时间
float IAverage; //电流平均
float VAverage; //电压平均
float PAverage; //压力平均
}PRODUCE_RECORD_ITEM;
PRODUCE_RECORD_ITEM processRecordItem;//生产记录
typedef struct
{
char item[80];
char itemTime[50];
}RecordItem,AlaInfo;
void ErrorExit(LPTSTR lpszFunction)
{
TCHAR szBuf[80];
LPVOID lpMsgBuf;
DWORD dw = GetLastError();
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
dw,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &lpMsgBuf,
0, NULL );
wsprintf(szBuf,
"%s failed with error %d: %s",
lpszFunction, dw, lpMsgBuf);
MessageBox(NULL, szBuf, "Error", MB_OK);
LocalFree(lpMsgBuf);
ExitProcess(dw);
}
int main(int argc, char* argv[])
{
//Open the data file.
HANDLE hFile = CreateFile( "test",
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL);
DWORD dwBytesInBlock =sizeof(PRODUCE_RECORD_ITEM)*100 + sizeof(PROCESS_INFOR_COUNTER);//+sizeof(RecordItem)*1000 ;
//Create the file-mapping object
HANDLE hFileMapping = CreateFileMapping(hFile,
NULL,
PAGE_READWRITE,
0,
dwBytesInBlock,
NULL);
//We no longer need access to the file object 's handle.
CloseHandle(hFile);
void* pbFile= (void*)MapViewOfFile(hFileMapping,
FILE_MAP_ALL_ACCESS,
0,
0,
dwBytesInBlock
);
// ErrorExit(NULL);
char st[] = {"2007-9-10-10.10"};
PROCESS_INFOR_COUNTER* pi = (PROCESS_INFOR_COUNTER*)pbFile;
PRODUCE_RECORD_ITEM* pitem = (PRODUCE_RECORD_ITEM*)(pi + 1);
if (pi->runInformationCounter < 0)
pi->runInformationCounter = 0;
else if (pi->runInformationCounter > 1000)
pi->processRecordCounter = 99 ;
for (int i = 0; i < 303; i++)
{
if (i == 301)
{
int k = 10;
}
pitem->craftID = pi->processRecordCounter;
strcpy(pitem[pi->processRecordCounter].endtime, st);
strcpy(pitem[pi->processRecordCounter].starttime, st);
pitem[pi->processRecordCounter].IAverage = (float)i;
pitem[pi->processRecordCounter].PAverage = (float)i;
pitem[pi->processRecordCounter].produceNumber= i;
FlushViewOfFile(&pitem[pi->processRecordCounter], sizeof(PRODUCE_RECORD_ITEM));
pi->processRecordCounter = (++pi->processRecordCounter) % 100;
pi->runInformationCounter = (++pi->runInformationCounter) % 1000;
FlushViewOfFile(pbFile, sizeof(PROCESS_INFOR_COUNTER));
}
//Unmap the view; we don 't want multiple views
//in our address space
UnmapViewOfFile(pbFile);
CloseHandle(hFileMapping);
return 0;
}
以上虽然解决了问题,但是对于采用标准C无法实现随机读写的问题仍然找不到原因,希望路过此地的高人指点迷津。
#include "stdlib.h"
#include "stdio.h"
typedef struct
{
int processRecordCounter;//当前生产记录个数
int runInformationCounter;//当前运行记录个数
}PROCESS_INFOR_COUNTER;
int main(int argc, char* argv[])
{
FILE* fp;
int pos;
PROCESS_INFOR_COUNTER pi;
fp = fopen("test","ab+");
//读取记录个数
if (fseek(fp, 0 - sizeof(PROCESS_INFOR_COUNTER), SEEK_END) < 0)//第一次写记录
{
pi.processRecordCounter = 0;
pi.runInformationCounter = 0;
}else
{
pos = ftell(fp);
rewind(fp);
pos = ftell(fp);
fread(&pi,sizeof(PROCESS_INFOR_COUNTER), 1, fp);
pos = ftell(fp);
pi.processRecordCounter = 10;
pi.runInformationCounter = 10;
}
rewind(fp);
pos = fseek(fp,0L, 0);
pos = ftell(fp);
pos = fwrite(&pi, sizeof(PROCESS_INFOR_COUNTER), 1, fp);
pos = ftell(fp);
fclose(fp);
return 0;
}
为了解决随机的读写问题,在此采用了文件内存方法:改进后程序如下所示:
// file.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "stdlib.h"
#include "stdio.h"
#include "windows.h"
typedef struct
{
int processRecordCounter;//当前生产记录个数
int runInformationCounter;//当前运行记录个数
}PROCESS_INFOR_COUNTER;
typedef struct
{
int produceNumber;//生产次数
int craftID;//工艺编号
char starttime[30]; //开始时间
char endtime[30]; //结束时间
float IAverage; //电流平均
float VAverage; //电压平均
float PAverage; //压力平均
}PRODUCE_RECORD_ITEM;
PRODUCE_RECORD_ITEM processRecordItem;//生产记录
typedef struct
{
char item[80];
char itemTime[50];
}RecordItem,AlaInfo;
void ErrorExit(LPTSTR lpszFunction)
{
TCHAR szBuf[80];
LPVOID lpMsgBuf;
DWORD dw = GetLastError();
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
dw,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &lpMsgBuf,
0, NULL );
wsprintf(szBuf,
"%s failed with error %d: %s",
lpszFunction, dw, lpMsgBuf);
MessageBox(NULL, szBuf, "Error", MB_OK);
LocalFree(lpMsgBuf);
ExitProcess(dw);
}
int main(int argc, char* argv[])
{
//Open the data file.
HANDLE hFile = CreateFile( "test",
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL);
DWORD dwBytesInBlock =sizeof(PRODUCE_RECORD_ITEM)*100 + sizeof(PROCESS_INFOR_COUNTER);//+sizeof(RecordItem)*1000 ;
//Create the file-mapping object
HANDLE hFileMapping = CreateFileMapping(hFile,
NULL,
PAGE_READWRITE,
0,
dwBytesInBlock,
NULL);
//We no longer need access to the file object 's handle.
CloseHandle(hFile);
void* pbFile= (void*)MapViewOfFile(hFileMapping,
FILE_MAP_ALL_ACCESS,
0,
0,
dwBytesInBlock
);
// ErrorExit(NULL);
char st[] = {"2007-9-10-10.10"};
PROCESS_INFOR_COUNTER* pi = (PROCESS_INFOR_COUNTER*)pbFile;
PRODUCE_RECORD_ITEM* pitem = (PRODUCE_RECORD_ITEM*)(pi + 1);
if (pi->runInformationCounter < 0)
pi->runInformationCounter = 0;
else if (pi->runInformationCounter > 1000)
pi->processRecordCounter = 99 ;
for (int i = 0; i < 303; i++)
{
if (i == 301)
{
int k = 10;
}
pitem->craftID = pi->processRecordCounter;
strcpy(pitem[pi->processRecordCounter].endtime, st);
strcpy(pitem[pi->processRecordCounter].starttime, st);
pitem[pi->processRecordCounter].IAverage = (float)i;
pitem[pi->processRecordCounter].PAverage = (float)i;
pitem[pi->processRecordCounter].produceNumber= i;
FlushViewOfFile(&pitem[pi->processRecordCounter], sizeof(PRODUCE_RECORD_ITEM));
pi->processRecordCounter = (++pi->processRecordCounter) % 100;
pi->runInformationCounter = (++pi->runInformationCounter) % 1000;
FlushViewOfFile(pbFile, sizeof(PROCESS_INFOR_COUNTER));
}
//Unmap the view; we don 't want multiple views
//in our address space
UnmapViewOfFile(pbFile);
CloseHandle(hFileMapping);
return 0;
}
以上虽然解决了问题,但是对于采用标准C无法实现随机读写的问题仍然找不到原因,希望路过此地的高人指点迷津。