Do (cheap) SD modules support file I/O?
There are Uno compatible SD shields which are great for prototyping IF you are using an Uno, they don't work too well with a Nano.  The modules are fine, but you end up with wires everywhere, but they do work with more formats of Arduino.

The ability to do file operations is separate to the protocol you use to talk to the module (SPI).  Lots of device (not just SD cards) use SPI, but not all of them do file operations.  An LCD, a GPIO expander, an EEPROM memory chip are all examples of devices that could use SPI.

What actions the SD module/shield is capable of is really up to the library/software.  The module will have to comply to some set of standards and this will let the caller perform certain operations.  Lets say one of the operations is to read one byte from an address.  This operation would need to be used by the library to read a file, also it would need to use it to find where the file is.  It would also need it when writing a file, because it would need to know what free space was left on the card.  You are shielded from all this by the Library you probably have a read file, write file and delete file function.  (This is an example of abstraction which you will see a lot in programming).

The will also have a set of standards to allow a controller to interface with the module, SPI, I2C, Serial or a proprietary one.  These communication protocols allow the controller to send the file commands to the module, like the read command above, and lets the module return data to the controller.  

So to answer your question 


If you use a module and shield that use the same IC (chip) to access
the SD card and the same library then they will almost always behave
the same.
If you use two different shield (different ICs) which
need different libraries then they MIGHT have different
functionality.
If you use two different shields which use the SAME library then the MIGHT have the same or different functionality.


Summary : Yes No Maybe :)

If you want something special find a library that does what you want and then find a bit of hardware supported by that library that also does it.  Otherwise, chances are you will be fine.

==== Edit ===

When you think of hardware/software abstraction think of it as a Television.  You deal with the TV at the very highest level, you turn it on/off and change channels.  

When you change channel what really happens is the remote control converts your button press into an encoded infra-red signal which hopefully hits the TV and the TV decodes this and executes some code which selects a pre-programmed channel.

Now you don't care about that all you care about is you press the button and you favourite soap opera appears on the screen.

There is another level of abstraction that is happening when the TV selects the pre-programmed channel, it has to convert the signal into some reference to the stored information that produces some information that is passed to the tuner and....  Well it just gets silly, you just want to watch your soap.

So back to the subject in question, you buy a SD reader module, you find a library that works with it and in your code you call WriteFile().  Does it really matter how it does it?  Do you care that the library is scattering you bytes across the SD card? Well as long as it retrieves it no not really?  Does it matter that WriteFile() is actually storing it on the hard disk of a PC somewhere in the world?

Your call to WriteFile() is abstracted away from the underlying process hiding it, because it doesn't really matter.  Most of the libraries use this Abstraction process, look at the code in Wire.cpp, it looks really simple when you are calling read() and write() but it isn't.