Is FileChannel#force is equivalent to OutputStream#flush? Do I always have to call it?
Asked Answered
A

1

2

I have a class works like FilterOutputStream.

public class WritableFilterChannel implements WritableChannel {

    public WritableFilterChannel(final WritableByteChannel channel) {
        super();
        this.channel = channel;
    }

    // isOpen(), close() delegates to the channel
    // write(ByteBuffer) overridden to work differently

    protected WritableByteChannel channel;
}

When I pass an instance of FileChannel, there is no way to force() other than close() it.

Is FileChannel#force is equivalent to OutputStream#flush? Do I always have to call it?

Do I have to do like this?

@Override
public void close() {
    if (channel instanceof FileChannel) throws IOException {
        ((FileChannel) channel).force(); // general solution?
    }
    channel.close();
}
Autotomize answered 18/1, 2016 at 16:21 Comment(3)
If channel.close(); doesn’t call force() internally, why should your close() method do it?Packsaddle
@Packsaddle Just because any FileChannel would be wrapped in my class as an instance of WritableFileChannel? Thanks.Autotomize
That doesn’t explain anything. If your close() method delegates to the wrapped channel’s close() method you already have exactly the same behavior, including all mandatory actions performed by that close() method. There are only two scenarios 1) calling force() is required. In that case you don’t need to call it, because channel.close(); will already do it. 2) calling force() is not required. In that case you don’t need to call it, because it is not required. So, in either case, you don’t need to call it. That’s what makes the question so strange. By the way, the answer is 2).Packsaddle
C
2

"Equivalent" is too strong a word. FileChannel.force(false) is similar to OutputStream.flush(). FileChannel's force() method offers stronger guarantees about the state of the file after it returns than OutputStream's flush() method.

Obviously you do not have to close() the FileChannel that you called the force() method on. You should only close the channel when you have finished with it. However, there is no guarantee that closing the channel will cause the equivalent of a force operation on it. If you need the behavior that force() specifies as part of the channel closure then you must explicitly call it the way you are doing in your close() method.

Citrate answered 18/1, 2016 at 16:26 Comment(5)
Calling flush() on a FileOutputStream has no effect at all. So calling this equivalent to force would be “too strong a word”, indeed. We could also say that these operations have nothing in common at all.Packsaddle
@Holger: It weird that someone follows you around upvoting your comments minutes after you make them. It's true that in current and past implementations FileOutputStream.flush() does nothing, but that is an implementation detail that could change (but not likely).Citrate
The contract of of OutputStream.flush() is that “if any bytes previously written have been buffered … such bytes should immediately be written to their intended destination” but FileOutputStream is not buffered. That’s why its flush() method doesn’t do anything. The Channel API is designed for unbuffered I/O in general, as the caller is supposed to control the buffers. So there is no flush method in the first place. force is closer to calling getFD().sync() on a FileOutputStream. Both operations only exists in the file specific specialization rather than the abstraction.Packsaddle
@Holger: How do you know FileOutputStream is not buffered?Citrate
Well, that’s the design since Java 1.0. If you want a buffered outputstream, you have to wrap the FileOutputStream in a BufferedOutputStream. Granted, FileOutputStream’s specification doesn’t say that it will not do buffering, on the other hand, its specification also doesn’t say that it won’t format your hard drive, so how do you know that FileOutputStream doesn’t format you hard drive? Usually by the fact that all classes that provide this feature name it explicitly, so all others do not have this feature.Packsaddle

© 2022 - 2024 — McMap. All rights reserved.