fread打破在“w”中打开的文件描述符模式。 [英] fread breaks file descriptors opened in "w" mode.

查看:89
本文介绍了fread打破在“w”中打开的文件描述符模式。的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

-----开始PGP签名消息-----

哈希:SHA1


大家好,

出于某些原因,在程序的某个地方,如果可能的话,我希望快速解析整个文件,然后重新开始并让整个分析开始。

我的问题是,我想要解析的FILE *已经远远地打开了

我来自哪里我不知道我的文件在哪个模式*已经打开。

此外,我的文件*可能不是常规文件,而是连续的

流(管道),在这种情况下它不可重绕。


所以我的程序基本上是这样的:


void PreParsing(FILE * my_file)

{

/ *

*测试我的文件*是否可以搜索

* /

if(fseek(my_file,0,SEEK_SET) == 0){


/ *

*如果是这样,请继续进行预解析。

* / < br $>
// ...

fread(buf,BUF_SIZE,1,my_file);

// ...


/ *

*快退文件。

* /

if(fseek(my_file,0,SEEK_SET)!= 0){

//由于我的文件*预计可以查找,因此出现意外错误。

}

}

}


*在Linux 2.6.xx和Solaris 5.10上,


当my_file是一个用w表示的常规文件时作为模式,

- 第一个fseek返回0表示成功:my_file是可搜索的

- fread返回0意味着没有什么可读:预期

,因为文件以w打开是截断的,因此是空的,无论如何,不​​能读取


- 第二个fseek返回0表示成功:my_file可以重绕。


当my_file是一个已经用w表示fopen'的管道时作为模式,

- 第一个fseek返回-1而errno设置为29(非法搜寻)。

这正是我的预期,因为管道不能寻求。


好​​的。因此,在Linux 2.6.xx和Solaris 5.10上,我的代码表现得像我预期的那样,常规文件和管道都是



*在AIX 5.2上,<当my_file是一个用w表示fopen'的管道时,
作为模式,

- 第一个fseek返回-1而errno设置为29(非法搜寻)。

我还是可以的。


但是...

当my_file是一个已经用w表示的常规文件时作为模式,

- 第一个fseek返回0表示成功:my_file是可搜索的

- fread返回0意味着没有什么可读:预期

,因为文件以w打开被截断,因此是空的,无论如何,不​​能读取


- 第二个fseek返回-1并将errno设置为9(错误文件编号)

我对这个错误感到有些惊讶。


事实上,在深入了解之后,在我看来,它似乎是一个

在w中打开的FILE *的fread尝试模式打破它,因为任何后续的

操作(fseek,fwrite甚至fclose!)都会因错误9(Bad

文件编号)而失败。

因此,在AIX上,我的函数无法在其结束时恢复FILE *状态。

所以,我有几个问题:


- 一个畏惧在w中打开的文件*肯定会返回0项,但是它是否真的预期它会使给定的FILE *完全无法使用,即使对于

fclose也是如此!?!仅在AIX上观察到此行为。 Linux和Solaris

有效。

- 给出一个文件*,是否有更好的方法来猜测它打开的模式是什么?试图读取或写入并查看错误?

- 给出一个FILE *,是否有更好的方法来猜测它是否可以被寻找而不是

尝试fseek它?

PS:我在comp.lang.c和comp.unix.aix上发布了我的问题因为我不知道这是否是AIX特定的问题或如果C norm

明确指定fread对只写

文件描述符有不可预测的影响。无论如何,我的目标是找到一个便携式解决方案,使用

作为尽可能少的平台特定的东西。


感谢您的建议。
$ b $bLéna?c ...仍然对AIX的行为感到困惑......

-----开始PGP SIGNATURE -----

版本:GnuPG v2 .0.9(GNU / Linux)

iEYEARECAAYFAkkjPpUACgkQjYEjJATS6Bi55ACgj + RbzOhyjD j63G + ciKo0Iy1B

FuoAn3WsnRc69XXDi2KV0Wt4aOFo0Bpf

= In7u

-----结束PGP SIGNATURE -----

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hello all,

For some reasons, somewhere in a program, I''d like, if possible, to quickly
parse a whole file before rewinding it and letting the full analysis start.
My problem is that the FILE* I want do parse has been fopen''ed far away
from where I am and I don''t know in which MODE my FILE* has been opened.
And additionally, my FILE* may not be a regular file, but a continuous
stream (pipe), in which case it is not rewindable.

So my program basically behaves like this:

void PreParsing( FILE *my_file )
{
/*
* Test if my FILE * is seekable
*/
if( fseek( my_file, 0, SEEK_SET ) == 0 ) {

/*
* If so, go on for the pre-parsing.
*/
//...
fread( buf, BUF_SIZE, 1, my_file );
//...

/*
* Rewind the file.
*/
if( fseek( my_file, 0, SEEK_SET ) != 0 ) {
// unexpected error since my FILE * was expected to be seekable.
}
}
}

* On both Linux 2.6.xx and Solaris 5.10,

when the my_file is a regular file that has been fopen''ed with "w" as mode,
- the first fseek returns 0 meaning success: my_file is seekable
- the fread returns 0 meaning that there was nothing to read: expected
since a file opened in "w" is truncated, hence is empty, and anyhow, cannot
be read!
- the second fseek returns 0 meaning success: my_file could be rewound.

when the my_file is a pipe that has been fopen''ed with "w" as mode,
- the first fseek returns -1 and errno is set to 29 (Illegal seek).
That''s exactly what I expected since a pipe cannot be sought.

Ok. So, on Linux 2.6.xx and Solaris 5.10, my code behaves like I expected
for both regular files and pipes.

* On AIX 5.2,

when the my_file is a pipe that has been fopen''ed with "w" as mode,
- the first fseek returns -1 and errno is set to 29 (Illegal seek).
I''m still OK with that.

but...
when the my_file is a regular file that has been fopen''ed with "w" as mode,
- the first fseek returns 0 meaning success: my_file is seekable
- the fread returns 0 meaning that there was nothing to read: expected
since a file opened in "w" is truncated, hence is empty, and anyhow, cannot
be read!
- the second fseek returns -1 and sets errno to 9 (Bad file number)
I''m a little bit surprised by this error.

In fact, after having had a deeper look on that, it appears to me that a
fread attempt on a FILE * opened in "w" mode breaks it since any subsequent
operation (fseek, fwrite and even fclose !) fails with the error 9 (Bad
file number).
So, on AIX , my function fails to restore the FILE * state at its end.
So, I have a few questions:

- a fread on a FILE * opened in "w" will for sure return 0 item, but is it
really expected that it makes the given FILE * totally unusable even for
fclose !?! This behavior has been observed only on AIX. Linux and Solaris
works.
- given a FILE *, is there a better way to guess in which mode it has been
opened than attempting to read or write it and look at errors ?
- given a FILE *, is there a better way to guess if it can be sought than
attempting a fseek on it ?
PS: I Xposted my problem on both comp.lang.c and comp.unix.aix because I
have no idea whether this is an AIX specific problem or if the C norm
specifies explicitly that fread have unpredictable effects on a write-only
file descriptor. Anyhow, my goal is to find a portable solution that uses
as less platform specific stuff as possible.

Thanks for your advices.
Léna?c ...still puzzled by AIX behavior...
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.9 (GNU/Linux)

iEYEARECAAYFAkkjPpUACgkQjYEjJATS6Bi55ACgj+RbzOhyjD j63G+ciKo0Iy1B
FuoAn3WsnRc69XXDi2KV0Wt4aOFo0Bpf
=In7u
-----END PGP SIGNATURE-----

推荐答案

11月19日上午12:15,Léna?c Huard< ; lenaic.hu ... @ laposte.netwrote:
On Nov 19, 12:15 am, Léna?c Huard <lenaic.hu...@laposte.netwrote:

----- BEGIN PGP SIGNED MESSAGE -----

哈希:SHA1
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1



请不要在邮件中包含这些垃圾...

Please don''t include that crap in your messages...


你好所有,


出于某些原因,在程序的某个地方,如果可能的话,我希望快速

在rewi之前解析整个文件找到它并让全面的分析开始。

我的问题是我想要解析的FILE *已经远远地打开了

我和我在哪里我不知道我的文件*打开了哪种模式。
Hello all,

For some reasons, somewhere in a program, I''d like, if possible, to quickly
parse a whole file before rewinding it and letting the full analysis start.
My problem is that the FILE* I want do parse has been fopen''ed far away
from where I am and I don''t know in which MODE my FILE* has been opened.



嗯,这是一件坏事,如果你想要真正有意义的结果,那么
应该只强制执行一种模式,二进制或文本。 br />

Well that''s a bad thing, if you want truly meaningful results you
should enforce just one mode, binary or text.


此外,我的文件*可能不是常规文件,而是连续的

流(管道),在这种情况下它不是rewindable的。
And additionally, my FILE* may not be a regular file, but a continuous
stream (pipe), in which case it is not rewindable.



将它加载到内存中一次,不要打扰实际文件

倒带。

Load it in memory once, and don''t bother with the actual file
rewinding.


所以我的程序基本上是这样的:


void PreParsing(FILE * my_file)

{

/ *

*测试我的文件*是否可以搜索

* /

if(fseek(my_file,0,SEEK_SET)== 0){
So my program basically behaves like this:

void PreParsing( FILE *my_file )
{
/*
* Test if my FILE * is seekable
*/
if( fseek( my_file, 0, SEEK_SET ) == 0 ) {



除了那个非常强大的电话之外,没有真正测试任何东西。

That isn''t testing anything really, except for that very fseek call.


>

/ *

*如果是这样,请继续进行预解析。

* /

// ...

fread(buf,BUF_SIZE,1,my_file);
>
/*
* If so, go on for the pre-parsing.
*/
//...
fread( buf, BUF_SIZE, 1, my_file );



我想你可能想要fread(buf,1,BUF_SIZE,my_file);

你还应该观察返回值。 />

< snip观察实现>

I think you probably want fread(buf, 1, BUF_SIZE, my_file);
You should also observe the return value.

<snip observations of implementations>


*在AIX 5.2上,

当my_file是一个已经用w表示的常规文件。作为模式,

- 第一个fseek返回0表示成功:my_file是可搜索的

- fread返回0意味着没有什么可读:预期

,因为文件以w打开被截断,因此是空的,无论如何,不​​能读取


- 第二个fseek返回-1并将errno设置为9(错误文件编号)

我对此错误感到有些惊讶。
* On AIX 5.2,
when the my_file is a regular file that has been fopen''ed with "w" as mode,
- the first fseek returns 0 meaning success: my_file is seekable
- the fread returns 0 meaning that there was nothing to read: expected
since a file opened in "w" is truncated, hence is empty, and anyhow, cannot
be read!
- the second fseek returns -1 and sets errno to 9 (Bad file number)
I''m a little bit surprised by this error.



为什么?这是标准所允许的。

Why? That''s allowed by the standard.


事实上,在深入了解之后,在我看来,这是一个

对在w中打开的FILE *的fread尝试模式打破它,因为任何后续的

操作(fseek,fwrite甚至fclose!)都会因错误9(Bad

文件编号)而失败。

因此,在AIX上,我的函数无法在其末尾恢复FILE *状态。
In fact, after having had a deeper look on that, it appears to me that a
fread attempt on a FILE * opened in "w" mode breaks it since any subsequent
operation (fseek, fwrite and even fclose !) fails with the error 9 (Bad
file number).
So, on AIX , my function fails to restore the FILE * state at its end.



嗯,这也是标准所允许的(但它确实听起来像

你的实现有错误)

Well, that''s also allowed by the standard (it does however sound like
your implementation has a bug)


所以,我有几个问题:


- 在w中打开的FILE上的fread *肯定会返回0项,但是它是否真的预期它会使给定的FILE *完全无法使用,即使对于

fclose也是如此!?!仅在AIX上观察到此行为。 Linux和Solaris

有效。
So, I have a few questions:

- a fread on a FILE * opened in "w" will for sure return 0 item, but is it
really expected that it makes the given FILE * totally unusable even for
fclose !?! This behavior has been observed only on AIX. Linux and Solaris
works.



该标准允许标准库的任何功能因任何原因设置errno

。 (也有例外)

The standard allows any function of the standard library to set errno
for any reason. (there are exceptions)


- 给定一个文件*,有没有更好的方法来猜测它打开的模式是什么?试图读取或写入并查看错误?
- given a FILE *, is there a better way to guess in which mode it has been
opened than attempting to read or write it and look at errors ?



标准C中无法做到这一点。

There''s no way to do that in standard C.


- 给出一个文件* ,有没有更好的方法来猜测是否可以寻找它而不是试图对它进行搜索?
- given a FILE *, is there a better way to guess if it can be sought than
attempting a fseek on it ?



标准C中没办法。

No way in standard C.


PS:我在comp.lang上发现了我的问题。 c和comp.unix.aix因为我不知道这是否是AIX特定的问题,或者如果C norm

明确指出fread对写入有不可预测的影响-only

文件描述符。无论如何,我的目标是找到一个便携式解决方案,使用

作为尽可能少的平台特定的东西。
PS: I Xposted my problem on both comp.lang.c and comp.unix.aix because I
have no idea whether this is an AIX specific problem or if the C norm
specifies explicitly that fread have unpredictable effects on a write-only
file descriptor. Anyhow, my goal is to find a portable solution that uses
as less platform specific stuff as possible.



嗯,这个行为的标准还可以。实现

可能有一个bug。我认为这是两组中的热门话题。

Well, the standard is okay with this behavior. The implementation
probably has a bug. It''s topical in both groups I believe.


Léna?c Huard写道:
Léna?c Huard wrote:

-----开始PGP签名消息-----

哈希:SHA1


大家好,


出于某些原因,在程序的某个地方,如果可能的话,我希望快速解析整个文件,然后重新开始并让整个分析开始。

我的问题是FILE *我想要解析已经远远地开始了

我来自哪里我不知道我的文件*在哪个模式下打开。
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hello all,

For some reasons, somewhere in a program, I''d like, if possible, to quickly
parse a whole file before rewinding it and letting the full analysis start.
My problem is that the FILE* I want do parse has been fopen''ed far away
from where I am and I don''t know in which MODE my FILE* has been opened.



你有设计缺陷。

You have a design flaw.


此外,我的FILE *可能不是常规文件,但是连续的

流(管道),在这种情况下它不可重绕。
And additionally, my FILE* may not be a regular file, but a continuous
stream (pipe), in which case it is not rewindable.



你有第二个设计缺陷......


< snip>

You have a second design flaw....

<snip>


>

所以,我有几个问题:


- 关于在w中打开的文件*肯定会返回0项,但是它是否真的预期它会使给定的FILE *完全无法使用,即使对于

fclose
>
So, I have a few questions:

- a fread on a FILE * opened in "w" will for sure return 0 item, but is it
really expected that it makes the given FILE * totally unusable even for
fclose



从只写流中读取AFAIK是未定义的行为。一旦你b $ b做了一些未定义的事情,谁知道会发生什么。


如果你从图书馆书籍中翻页,你能否安全地将它归还给

库?

AFAIK reading from a write-only stream is undefined behaviour. Once you
do something undefined, who knows what will happen.

If you rip pages out of a library book, can you safely return it to the
library?


- 给定一个FILE *,有没有更好的方法来猜测它是哪种模式
比尝试读取或写入并查看错误?
- given a FILE *, is there a better way to guess in which mode it has been
opened than attempting to read or write it and look at errors ?



不幸的是答案是修复程序中的设计缺陷....

Unfortunately the answer is "fix the design flaws in the programme"....


PS:我在comp.lang.c和comp.unix.aix上发布我的问题
PS: I Xposted my problem on both comp.lang.c and comp.unix.aix



可能有针对您问题的AIX特定答案,但我可以''

评论

There may be AIX-specific answers to your problem but I can''t comment on
that


文章< 49 ****************** **** @ newss.free.fr>,
$ b $bLéna?c Huard< le ********** @ laposte.netwrote:
In article <49**********************@news.free.fr>,
Léna?c Huard <le**********@laposte.netwrote:

>由于某些原因,在程序的某个地方,如果可能的话,我希望在重新整理文件并让整个分析开始之前快速解析整个文件。 />我的问题是,我想要解析的FILE *已经远离我所在的地方,并且我不知道我的文件*打开了哪个模式。
另外,我的FILE *可能不是常规文件,而是连续的
流(管道),在这种情况下它不是可以倒带。
>For some reasons, somewhere in a program, I''d like, if possible, to quickly
parse a whole file before rewinding it and letting the full analysis start.
My problem is that the FILE* I want do parse has been fopen''ed far away
from where I am and I don''t know in which MODE my FILE* has been opened.
And additionally, my FILE* may not be a regular file, but a continuous
stream (pipe), in which case it is not rewindable.



我不知道为什么你要处理文件

已经打开写的情况。如果你想从文件中读取,请打开

进行阅读。


另一方面 - 可寻找性 - 完全合理,但我不是

认为你可以在标准C中处理它。如果你(使用Posix系统看起来好像是b $ b)你可以统计底层文件描述符

并且仅在它是普通文件的情况下寻求。


我似乎记得使用至少一个系统,其中fseek()成功

即使在管道提供的搜索是在现有的stdio缓冲区内,

所以只是因为一个fseek()成功,它并不意味着其他人会。


- - 理查德

-

请记得提及我/你留下的录音带。

I''m at a loss as to why you want to handle the case where the file
has been opened for writing. If you want to read from a file, open
it for reading.

The other aspect - seekability - is entirely reasonable, but I don''t
think you can handle it in standard C. If you are (as you appear to
be) using Posix systems, you can stat the underlying file descriptor
and seek only if it is a regular file.

I seem to recall using at least one system where fseek() succeeded
even on pipes provided the seek was within the existing stdio buffer,
so just because one fseek() succeeds, it doesn''t mean others will.

-- Richard
--
Please remember to mention me / in tapes you leave behind.


这篇关于fread打破在“w”中打开的文件描述符模式。的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆