| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 870 人关注过本帖
标题:求教高手,关于二进制文件读写问题
只看楼主 加入收藏
huangzhenfan
Rank: 1
等 级:新手上路
帖 子:5
专家分:0
注 册:2012-7-15
结帖率:0
收藏
已结贴  问题点数:20 回复次数:8 
求教高手,关于二进制文件读写问题
问题:把一个整数插入到一个记录了若干整数的二进制文件的前部
想法:
假设被插入的整数记录在变量 int i;中
先取出文件中第一个整数存放在变量int t;中
向文件写入 i 的值,然后
i=t;
再从文件中取出第二个整数存放在变量int t;中
向文件写入 i 的值,然后
i=t;
……
依此类推
最后当fread返回值为0时
再写一个数就OK

下面是代码
先预备一个二进制文件#include <stdlib.h>

#include <stdio.h>
int main( void )
{
  FILE *pf=NULL;
  int i = 100 , t ;
  pf = fopen("abc","wb");
  fwrite(&i,sizeof(int),1,pf);
  fclose(pf);
  return 0;
}

复制代码为简单起见,文件里只写了一个整数
下面开始读写
#include <stdlib.h>
#include <stdio.h>
int main( void )
{
  FILE *pf=NULL;
  int i = 99 , t ;
//  pf = fopen("abc","wb");
//  fwrite(&i,sizeof(int),1,pf);
//  fclose(pf);
  pf = fopen("abc","rb+");
  while( fread(&t,sizeof(int),1,pf) ) //读一个数放在t中
  {
      fseek(pf,-(long)sizeof(int) ,SEEK_CUR);//退回原来的位置
      fwrite(&i,sizeof i,1,pf) ;              //写入i
      i = t ;                                //留着下次写入
  }
  fseek(pf,-(long)sizeof(int) ,SEEK_CUR);
  fwrite(&i,sizeof i,1,pf);
  fclose(pf);
  return 0;
}
复制代码结果竟是死循环

很想听听大家对这个BUG的高见
搜索更多相关主题的帖子: 二进制 include 记录 
2012-07-21 10:46
netlin
Rank: 13Rank: 13Rank: 13Rank: 13
等 级:贵宾
威 望:24
帖 子:544
专家分:4308
注 册:2012-4-9
收藏
得分:7 
楼主的思路挺好的!

 while( fread(&t,sizeof(int),1,pf) ) //读一个数放在t中
  {
      fseek(pf,-(long)sizeof(int) ,SEEK_CUR);//退回原来的位置
      fseek(pf,-sizeof(int) ,SEEK_CUR);//换成这句,看看!
      fwrite(&i,sizeof i,1,pf) ;              //写入i
      i = t ;                                //留着下次写入
  }
  fseek(pf,-(long)sizeof(int) ,SEEK_CUR);
  fwrite(&i,sizeof i,1,pf);
(这两句不能再这么写了,直接写一条语句:在最后面添加i值即可。)
  fclose(pf);
  return 0;
}

做自己喜欢的事!
2012-07-21 12:03
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:7 
思路不是这样的。而且你叙述的思路也不是把数据插在前面呀。

授人以渔,不授人以鱼。
2012-07-21 18:26
LShang
Rank: 4
来 自:China
等 级:业余侠客
威 望:3
帖 子:183
专家分:258
注 册:2010-12-24
收藏
得分:7 
我想的是读取文件到内存,插入后再重写文件,效率貌似不高。。。

学如逆水行舟,不进则退
士不可以不弘毅,任重而道远
2012-07-21 20:30
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
跟文件的内容和被插入的数据有关系。效率不好说,超大的文件,读入内存再写就不是那么好了。具体情形具体分析吧。

授人以渔,不授人以鱼。
2012-07-21 20:40
LShang
Rank: 4
来 自:China
等 级:业余侠客
威 望:3
帖 子:183
专家分:258
注 册:2010-12-24
收藏
得分:0 
回复 5楼 TonyDeng
恩恩 不能太死板,灵活运用

学如逆水行舟,不进则退
士不可以不弘毅,任重而道远
2012-07-21 20:44
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
最稳妥保险的做法,是新建一个文件,先把要插入的数据写入,然后把原来的文件追加到后面去。用C直接处理可以,用操作系统的文件合并也可以。这样无论是写还是读,都是单方向扫一遍的,尽量回避把文件指针移来移去,那种定位很不靠谱,变数太多。对大文件,要测试环境的效率,找出每次读写的数据块是多大,1024K还是4096K甚至更大,不同的操作系统这是不同效果的。如果是特大文件,在Windows下可以用MappingFile功能把文件映射为内存,直接用内存的复制和移动操作,数G的文件也不成问题。
收到的鲜花
  • LShang2012-07-21 21:49 送鲜花  3朵   附言:感谢版主

授人以渔,不授人以鱼。
2012-07-21 21:00
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
楼主的代码被局限在特定的数据类型中,我给你一个不限的,用4楼的方法:

程序代码:
#include <cstdio>
#include <cstdlib>

bool CreateNewFile(const char* filename);

void main(void)
{
    const char str[] = "Hello, world!";
    const char filename[] = "test.dat";

    CreateNewFile(filename);

    FILE* file;
    if ((fopen_s(&file, filename, "rb") == 0) && (fseek(file, 0, SEEK_END) == 0))
    {
        long file_size = ftell(file);
        fseek(file, 0, SEEK_SET);
        char* memory = NULL;
        if ((memory = (char*) malloc(file_size * sizeof(char))) != NULL)
        {
            fread(memory, file_size, 1, file);
        }
        if (freopen_s(&file, filename, "wb", file) == 0)
        {
            fwrite(str, sizeof(str), 1, file);
            if (memory != NULL)
            {
                fwrite(memory, file_size, 1, file);
            }
        }
        fclose(file);
        free(memory);
        memory = NULL;
    }
}

bool CreateNewFile(const char* filename)
{
    FILE* file;
    errno_t err = fopen_s(&file, filename, "wb");
    if (errno == 0)
    {
        for (int number = 0; number < 1024; ++number)
        {
            fwrite(&number, sizeof(number), 1, file);
        }
        fclose(file);
    }

    return (errno == 0);
}


[ 本帖最后由 TonyDeng 于 2012-7-21 23:14 编辑 ]

授人以渔,不授人以鱼。
2012-07-21 23:12
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
1楼代码的bug,根据文档介绍,似乎应该在移动文件指针进行读写之前先调用fflush()刷新数据。

授人以渔,不授人以鱼。
2012-07-21 23:17
快速回复:求教高手,关于二进制文件读写问题
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.041802 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved