首页
社区
课程
招聘
未解决 [已解决]fread和fwrite为什么无法读取大于4K对齐.
发表于: 2019-3-9 21:35 2610

未解决 [已解决]fread和fwrite为什么无法读取大于4K对齐.

2019-3-9 21:35
2610
以下代码,多种方式操作文件, 始终会丢失文件尾部.
例:读取138KB的文件,其中当缓冲区4K对齐时读取正常,如果不是4K对齐则仅读取4K对齐的大小,多余的不读取.
比如我读取5120字节,实际只会读取4096.少了1024. 如果设置读取长度为4K却是正常读取,但是又有另一个问题出现
那就是比如我要读取138kb文件. 读到文件尾的时候只会读取4K长度. 多出来的字节不读取和写入. 
比如尾部剩余5120字节,实际只有4096字节被读取出来.
有人知道是为什么吗? 多次测试都是这样的结果,就算我手动fseek 也没有效果.
求知道的大佬告知,指出错误点或者错误点的资料也可以..万分感谢
-===============================

FILE *OpenResFile = fopen(ResDir, "wb+");
if (!OpenResFile)return FALSE;
//移动资源包文件指针
fseek(OpenResFile, 0, SEEK_SET);
//记录资源包文件指针位置;
UINT ResPoint = 0;
for (UINT i = 0; i < FileCount; i++) {
char *pPath = (char*)GvResfile[i].FileName;
OutputDebugStringA(pPath);
OutputDebugStringA("\r\n");
//打开预打包资源文件
if (!pPath) { MessageBox(0, L"打包失败!", nullptr, NULL); break; }
FILE *TmpFile = fopen(pPath, "rb+");
if (!TmpFile) { MessageBox(0, L"打包失败!", nullptr, NULL); break; }
//移动预打包资源文件指针并获取文件大小
fseek(TmpFile, 0, SEEK_END);
UINT FileLen = ftell(TmpFile);
//设置读取缓冲区大小以及次数;
UINT FileBufferLen = 1024* 24, ResCount = 1;
//申请缓冲区;
void *TmpData = LocalAlloc(LMEM_ZEROINIT, FileBufferLen);
if (FileLen > FileBufferLen) {
ResCount = FileLen / FileBufferLen;
}
//重置预打包资源文件指针;
fseek(TmpFile, 0, SEEK_SET);
//读取并打包资源文件;
UINT ReadLen = 0;
do {
ZeroMemory(TmpData, FileBufferLen);
ReadLen = ftell(OpenResFile);
ReadLen = fread(TmpData, sizeof(char), FileBufferLen, TmpFile);
ResCount += ReadLen;
fwrite(TmpData, sizeof(char), ReadLen, OpenResFile);
} while (!feof(TmpFile));
#pragma region 手动fseek
/*for (UINT n = 0; n <= ResCount; n++) {
ZeroMemory(TmpData, FileBufferLen);
if (n == ResCount) {
//打包资源文件尾巴;
UINT EndLen = FileLen - (FileBufferLen * ResCount);
/ *fseek(TmpFile, FileLen - EndLen, SEEK_SET);
fseek(OpenResFile, ResPoint, SEEK_SET);* /
UINT ReadLen = fread(TmpData, sizeof(char), FileBufferLen, TmpFile);
UINT WriteLen = fwrite(TmpData, sizeof(char), EndLen, OpenResFile);
ReadLen = WriteLen;
}
else {
/ *fseek(TmpFile, n*FileBufferLen, SEEK_SET);
fseek(OpenResFile, ResPoint, SEEK_SET);* /
fread(TmpData, sizeof(char), FileBufferLen, TmpFile);
fwrite(TmpData, sizeof(char), FileBufferLen, OpenResFile);
//ResPoint += FileBufferLen;
}
}*/
#pragma endregion
//关闭打开的资源文件;
fclose(TmpFile);


}

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

最后于 2019-3-10 02:53 被ezrealik编辑 ,原因: 已解决
收藏
免费 0
支持
分享
最新回复 (4)
雪    币: 2161
活跃值: (750)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
2
用Windows Api吧, 看你都用MessageBox了
CreateFile/ReadFile/SetFilePointer/CloseHandle
2019-3-10 01:10
0
雪    币: 2161
活跃值: (750)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
3
查了些资料, fopen是带缓冲的, 由CRT管理, 也许与这个有关系.
2019-3-10 02:02
1
雪    币: 1570
活跃值: (383)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
4
sidyhe 查了些资料, fopen是带缓冲的, 由CRT管理, 也许与这个有关系.
嗯,已经解决了.  谢谢了 原因就是出在fopen上.文件尾部实际有读取,但是没有实时存入, 当我即时fclose释放后,就正常了,我一直以为读取存入是实时的.
然后就是不知道为什么fread和fwrite一直是4k对齐..
最后于 2019-3-10 02:52 被ezrealik编辑 ,原因:
2019-3-10 02:51
0
雪    币: 1289
活跃值: (1337)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
fflush强刷应该也是可以的,4K应该是被优化了
2019-3-10 22:20
1
游客
登录 | 注册 方可回帖
返回
//