| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 3710 人关注过本帖
标题:fstream 读取大文件eof()检测失效
只看楼主 加入收藏
ljw970243
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:43
专家分:105
注 册:2011-8-20
结帖率:60%
收藏
已结贴  问题点数:20 回复次数:11 
fstream 读取大文件eof()检测失效
ifstream in("data/log2.txt",ios::in);//文本格式日志文件,约5M
if(!in){
        cerr<<"canon open file!\n";
        return 1;
    }
    while(!in.eof()){//检测是否读取到文件结尾,小文件检测正常,大文件始则死循环
        if(!in.getline(str,140))break; //检测读取状态,失败则跳出循环,eof检测失效只能靠这个.
        len = strlen(str);
        if(len>maxlen){
            maxlen=len;
            mask = n;
            offset = in.tellg();
        }
        //nod.Setdate(str,nod.in);
        n++;
    }
cout<<in.eof();//读取小文件退出后返回值为1,读取大文件则始终为0..
求解!
搜索更多相关主题的帖子: 检测 canon return break while 
2011-09-10 19:46
xg5699
Rank: 7Rank: 7Rank: 7
等 级:黑侠
帖 子:140
专家分:522
注 册:2011-7-27
收藏
得分:0 
程序代码:
ifstream in("data/log2.txt",ios::in);//文本格式日志文件,约5M
if(!in.is_open())//最好用 is_open()函数检测
{
        cerr<<"canon open file!\n";
        return 1;
    }
   in.seekg(0);//将位置定义开头
    while(!in.eof())
    {//检测是否读取到文件结尾,小文件检测正常,大文件始则死循环
        if(!in.getline(str,140))
            break; //检测读取状态,失败则跳出循环,eof检测失效只能靠这个.
        len = strlen(str);
        if(len>maxlen){
            maxlen=len;
            mask = n;
            offset = in.tellg();
        }
        //nod.Setdate(str,nod.in);
        n++;
        in.clear()// 到了eof必须清除eofbit状态的
    }
cout<<in.eof();//读取小文件退出后返回值为1,读取大文件则始终为0..
}

//我水平不够啊看不出哪里读取错误了,你能否把5M读取失败的文件发上来我写一个读取的代码试试呢?

都不结贴我郁闷那!
2011-09-10 22:47
ljw970243
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:43
专家分:105
注 册:2011-8-20
收藏
得分:0 
因为等很久没有找到原因,后来改用C才正常,又意外发现,用了c编译出来程序只有c++编译后的 十分之一不到,而且速度也快多了.
用c++编译后测试时间约700ms,而c编译的约100ms.

///////////////////////
回2L,因为日志文件涉及一些公司的信息,恕不能上传,请见谅.
你可以找个大点的文本文件来试试,
后来分析日志文件,发现最后一行是空的,不知是不是这个原因.
因为小文件是从日志文件截出一小段来测试的,最后一行不是空行.

[ 本帖最后由 ljw970243 于 2011-9-11 14:58 编辑 ]
2011-09-11 14:55
xg5699
Rank: 7Rank: 7Rank: 7
等 级:黑侠
帖 子:140
专家分:522
注 册:2011-7-27
收藏
得分:0 
回复 3楼 ljw970243
首先我用
程序代码:
#include<iostream>
#include<fstream>
using namespace std;
void main()
{
    ofstream fcout("2x.txt");
    for(int i=0;i<59999;i++)
        fcout<<"啊西啊西啊西啊西啊西啊西啊西啊西啊西啊西啊西啊西啊西啊西啊西啊西啊西啊西啊西啊西啊西啊西啊西啊西啊西啊西啊西啊西啊西"<<endl;
    fcout.close();
}
创建了 一个 6M左右的文件
然后在用这个代码读取
程序代码:
#include<iostream>
#include<fstream>
using namespace std;
void main()
{
    char a;
    ifstream fcin("2x.txt");
    if(!fcin.is_open())
    {
        cout<<"打开失败"<<endl;
    }
    else
    {
        while(fcin.get(a))
            cout<<a;
        fcin.close();
    }
/*    for(int i=0;i<59999;i++)
        fcout<<"啊西啊西啊西啊西啊西啊西啊西啊西啊西啊西啊西啊西啊西啊西啊西啊西啊西啊西啊西啊西啊西啊西啊西啊西啊西啊西啊西啊西啊西"<<endl;
    fcout.close();
    */
}
由于要判定fcin是不是读取到了最后并且结束所以我手动打开了2x.txt文件在文件末尾加上了最后2个字,输出看结果

整整读取了10分钟显示完毕了(04年买的电脑),一切正常,不信你自己可以拿我代码做实验  以下是输出结果:
啊西啊西啊西啊西啊西啊西啊西啊西啊西
啊西啊西啊西啊西啊西啊西啊西啊西啊西啊西啊西啊西啊西啊西啊西啊西啊西啊西啊西啊西
啊西啊西啊西啊西啊西啊西啊西啊西啊西
啊西啊西啊西啊西啊西啊西啊西啊西啊西啊西啊西啊西啊西啊西啊西啊西啊西啊西啊西啊西
啊西啊西啊西啊西啊西啊西啊西啊西啊西
啊西啊西啊西啊西啊西啊西啊西啊西啊西啊西啊西啊西啊西啊西啊西啊西啊西啊西啊西啊西
啊西啊西啊西啊西啊西啊西啊西啊西啊西
啊西啊西啊西啊西啊西啊西啊西啊西啊西啊西啊西啊西啊西啊西啊西啊西啊西啊西啊西啊西
啊西啊西啊西啊西啊西啊西啊西啊西啊西最后
请按任意键继续. . .




[ 本帖最后由 xg5699 于 2011-9-11 18:45 编辑 ]

都不结贴我郁闷那!
2011-09-11 18:41
ljw970243
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:43
专家分:105
注 册:2011-8-20
收藏
得分:0 
#include <iostream>
#include <fstream>
using namespace std;
int main(int argc,char **argv){
    ifstream ff;
    char str[191];
    int err;
    ff.open(argv[1],ios::in);
    if(!ff.is_open()){
        cout<<"Cannot open file:"<<argv[1]<<endl;
        return 1;
    }
    cout<<"Eof:"<<ff.eof()<<endl;
    while(!ff.eof()){
        ff.getline(str,190);
        err=ff.fail();
        if(err){
            cout<<"File read error, code:"<<err<<endl;
            break;
        }
    }
    cout<<"Eof:"<<ff.eof()<<endl;
    cout<<"Error code:"<<err<<endl;
    ff.close();
    return 0;
}
读取两个文件小文件
一个结尾是空行,结果读取出错了,另一个结尾随便输个字,就正常结束.
全部文件打包...
test.rar (211.65 KB)

2011-09-11 23:07
ljw970243
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:43
专家分:105
注 册:2011-8-20
收藏
得分:0 
图片附件: 游客没有浏览图片的权限,请 登录注册
2011-09-11 23:08
ljw970243
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:43
专家分:105
注 册:2011-8-20
收藏
得分:0 
不知是不是我的编译器有问题,如果用<stdio.h>的I/O函数,程序就只有二三十KB,而用<iostream>的函数,程序体积就大了10倍,像刚才那个程序就有460KB.
有用过cygwin 编译的文件很小,速度也更快,到其他电脑就要带几个DLL文件.
先用mingw编译,文件大了一些,速度也慢了.
不知你用什么编译的?
2011-09-11 23:15
xg5699
Rank: 7Rank: 7Rank: 7
等 级:黑侠
帖 子:140
专家分:522
注 册:2011-7-27
收藏
得分:0 
回复 7楼 ljw970243
Microsoft Visual Studio 2005
你别急 我睡觉前帮你看下第一个问题

[ 本帖最后由 xg5699 于 2011-9-11 23:56 编辑 ]

都不结贴我郁闷那!
2011-09-11 23:45
xg5699
Rank: 7Rank: 7Rank: 7
等 级:黑侠
帖 子:140
专家分:522
注 册:2011-7-27
收藏
得分:0 
回复 7楼 ljw970243
关于为什么fail函数会返回1等我下班到家在研究,是本身文档出错,我用新建的文档读取程序就不会乱码了,你可以自己试试,我试没有问题
log0.rar (523 Bytes)

你用这个,在用我写的代码
程序代码:
#include <iostream>
#include <fstream>
using namespace std;

int main(int argc,char **argv)
{

    ifstream ff;
    char str;
    int err=0;
    ff.open(argv[1]);
    if(!ff.is_open()){
        cout<<"Cannot open file:"<<argv[1]<<endl;
        return 0;
    }
    cout<<"Eof:"<<ff.eof()<<endl;

   
    while(!ff.eof())
    {
        str=ff.get();
        cout<<str;
    }
   
    if(ff.fail())
    {
        ff.clear();
    err=ff.fail();
        if(err)
        {
            cout<<"File read error, code:"<<err<<endl;
      
        }
    }
    else
    {
        cout<<"ok"<<endl;
    }

    cout<<"Eof:"<<ff.eof()<<endl;
    cout<<"Error code:"<<err<<endl;

    ff.close();
    return 0;
}
就正常了


[ 本帖最后由 xg5699 于 2011-9-12 14:23 编辑 ]

都不结贴我郁闷那!
2011-09-12 00:57
xg5699
Rank: 7Rank: 7Rank: 7
等 级:黑侠
帖 子:140
专家分:522
注 册:2011-7-27
收藏
得分:20 
回复 5楼 ljw970243
到家了,我想了一下,检测错误fail函数和bad函数是不一样的
当缓冲区出现错误,比如说数据丢失,badbit位设置为1,函数bad()检测到badbit位1,就返回真(1). 这样说明数据丢失,这种严重错误无法修复,
而fail函数是流操作失败,比如申请不到内存会出现其他输入错误才为1,这种不是致命错误,可以用clear()函数修复
至于为什么好好的fail函数会返回1呢?根据我的猜测是当读取到eof时函数将eofbit为1,同时将failbit也设置为1,这样做的目的是不能再对文件在读写修改,eofbit为1说明被读取过,如果要重复读取需要将各个标志清零,也就是clear()
说的明白点就是当函数检测到eof,自动将failbit设置为1,但不会将badbit设置为1,也就是说无论任何文件当检测到eof fail函数一定会返回1  除非清标志,既然这样如何判断读取错误呢?就用bad函数
程序代码:
#include <iostream>
#include <fstream>
using namespace std;

int main(int argc,char **argv)
{

    ifstream ff;
    char str;
    int err=0;
    ff.open(argv[1]);
    if(!ff.is_open()){
        cout<<"Cannot open file:"<<argv[1]<<endl;
        return 0;
    }
    cout<<"Eof:"<<ff.eof()<<endl;

   
    while(!ff.eof())    //这个我就不多说了
    {
        str=ff.get();
        cout<<str;  //测试看看是不是乱码,我测试一点问题都没
    }
   
    if(ff.fail())   // fail为1
    {
        if(ff.bad())   //看看bad标志是否为1,假设为1数据读写严重错误无法修复
        {
            err=ff.bad();
         if(err)
        {
            cout<<"File read error, code:"<<err<<endl;
                  return 0;
      
        }
        }
        ff.clear();
   
      
    }
    cout<<"Eof:"<<ff.eof()<<endl;
    cout<<"Error code:"<<err<<endl;

    ff.close();
    return 0;
}

 如果你觉得不满意,可以告诉我你在读写程序是不是要判断文本文件有错误字符还是什么?把你的想法告诉我也许可以帮助你,烧饼节快乐

[ 本帖最后由 xg5699 于 2011-9-12 21:55 编辑 ]

都不结贴我郁闷那!
2011-09-12 21:46
快速回复:fstream 读取大文件eof()检测失效
数据加载中...
 
   



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

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