It's more accurate to say "everything is a file descriptor" instead of "everything is file". For example, sockets are file descriptors, even though they may not be directly exposed in the file system (they may be in Linux, I'm not sure). I'm interested to know in what cases this design fails.
My main issue is that it seems there's a lot of information that is only exposed as a text file in the /proc file system. And writing code to parse those text files is cumbersome, and both slower and more likely to break in the future (if the format of the file changes) than an API call would've been. I'll admit that it's nice that this info is intrinsically available in every environment (like Mono or Java) without having to find some way to do system calls, but when I'm writing a C(++) program, why does the kernel (also written in C) have to generate a text file only for me to immediately parse it back?