I personally do not see a problem with the module doing the i/o as long as it does proper error handling. Having an interface that it easy to use will make it more useful to people.
One idea is that you routines could expect different parameters depending on how the user wants to handle the i/o. For example someone could pass you in a string with the file name if they don't care if you do the i/o. Or they could pass in existing filehandles if they want to handle it themself.
And finally one other thing that could be done is to have the method(s) return the data, but then also provide methods that will deal with reading and writing the data as well. That way they are not forced to use your i/o handling, but instead can add an extra line or two of code to use it.