-
Notifications
You must be signed in to change notification settings - Fork 4.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Linux - FileStream.Length, FileStream.Seek & File.ReadAllBytes misbehaves with files in procfs #25571
Comments
Almost all files in proc have zero size and should be read till EOF. Since this is a special file system, I suggest to not make FileStream more complex to support this. |
Shouldn't we at least fix |
The challenge is that for proc (and similar) files we need to allocate a buffer up-front (and deal with it maybe being too small). Whereas for real empty files we don't want to be allocating a buffer at all. |
Maybe there is some API for that... E.g.
|
You mean, stat shows the Type 'proc'? This behavior isn't limited to the proc file system, any file system can do this. |
Yes
What else can behave this way? Here is only proc mentioned:
And I also tried to get size of files under /sys - it returns non-0 size |
Any file system can. I have seen application that export a file system via fuse (https://github.com/libfuse/libfuse) which behave the same way. |
I see. Thanks |
Would it make sense to fix it not 100% of cases but 99 - only for known file systems? |
Would it work if you tried to read a single byte (or read into a small stack-allocated buffer)? If that succeeds, you know the file size is lying and you have to deal with it in a special way. This would mean some seemingly unnecessary allocations and copying for |
Another thing we could try is to use the fact that seeking from the end fails for such files (but this needs to be tested with other file systems that return 0 size to make sure they behave the same way) |
@svick it depends on the file system, but I think it should work for special file systems from the kernel. A small stack-allocated buffer would be good. Then we may have the full data already and we only need to copy it into a byte array. |
And we can combine 2 approaches - for well-known file systems use hardcoded behavior, for unknown - test the file itself |
Maybe I'm going too crazy with checking file system type. Probably reading just small buffer is even cheaper than determining file system type and it is definitely much simpler in terms of implementation |
Yes, a stackalloced read should be enough.
I don't know for sure, but I'd assume this is Linux specific behavior. |
B.T.W. You mentioned FUSE and I found this: https://osxfuse.github.io/ . Could this mean that OSX can also have the same behavior for those file systems? |
Probably it can. It's fine if the change applies to all Unixes. |
Thanks! |
I did the following experiment:
Which reports the following:
https://github.com/dotnet/corefx/blob/a8cfc6a498f0455c59b0030f74cba4dabeee86e1/src/System.IO.FileSystem/src/System/IO/File.cs#L320
This guy relays on FileStream.Length. I'm thinking if FileStream.Length should actually throw for files in procfs and CanSeek should return false for them and File.ReadAllBytes should check CanSeek and if it is false then don't pre-allocate buffer of the final size but allocate it dynamically while reading
The text was updated successfully, but these errors were encountered: