TYP: Use Protocols for file-like objects in read/to_*
Fixes #41610, rebased on top of #43855.

This PR does a few things:

1. break `FilePathOrBuffer` apart to not mix basic types and generics
2. use protocols instead of union of specific classes
3. define many fine-grained protocols for the to/read methods/functions

I tested that the protocols are sufficient (need no additional attributes/methods) using mock classes with:

- read_csv (python/c/pyarrow; w/wo compression) and to_csv (w/wo compression)
- to_json and read_json (each w/wo compression)
- to_pickle, read_pickle
- to_excel (openpyxl/xlsxwriter) and read_excel (openpyxl)
- to_stata and read_stata

Future: use many overloads for `get_handle` to return the (wrapped) fine-grained protocols.