[quote=“jules”]TBH in all my years of hacking, I’ve never needed a dual input/output stream. Seems to me that almost every file operation tends to be either reading or writing, and that when you find yourself needing to do both at once then you’re probably writing code whose behaviour relies on shaky assumptions about how the file-system will behave.
Certainly I’d have thought that if your algorithm is being broken by the writer using an internal buffer, then it could also be affected by the OS doing something similar (I’ve no idea if OSes actually do buffer data before flushing it to disk, but it wouldn’t be surprising if they did).[/quote]
Completely false. Consider what happens if you were to use FILE objects via fopen, fread, and fwrite. As long as you go through just the one FILE object, you will get a consistent view no matter how much reading and writing you do. The OS can definitely buffer data but when you read through the same file handle, it goes through the buffer and everything is consistent.
But with FileInputStream and FileOutputStream, there are two separate file handles. Each one has its own buffer. So writing to the one, will not retrieve that information when reading from the other.
The use-case for dual input/output should be obvious: RandomAccessFile. Currently in JUCE there is no way to reproduce the behavior of a buffered i/o file opened for reading and writing, e.g.:
FILE* f = fopen (path, "rwb+");
Obviously we would want this if we are implementing a database.
Jules you should move the platform specific native bits currently in FileInputStream and FileOutputStream into a new class RandomAccessFile, then change FileInputStream and FileOutputStream to use RandomAccessFile.
Then add createInputStream and createOutputStream to RandomAccessFile. This way you can have two streams that use the same underlying RandomAccessFile. You would probably want to remove the buffering from the stream. If you want buffering it should be done in RandomAccessFile so that the views are consistent.
You can tweak File::createInputStream and File::createOutputStream to just first create a RandomAccessFile and then call the corresponding function on it.
FileInputStream and FileOutputStream will probably need an OptionalScopedPointer to hold the underlying RandomAccessFile