Shouldn't files be closed by the OS when the program ends? If so, why
doesn't the file ever get written?

I tried making my own class which closes the file in finalize(), but
that doesn't necessarily get called either, so that's out. There's no
other destructor type of thing in Java.

I just don't understand why Java can't close the file for me. All
other languages do it and this is supposed to be a high level
language. It actually acts like the file was never opened for writing
at all. It might truncate the file to 0 bytes, but it never writes
data to the file unless you manually close it. Can anyone explain why
the behavior is like this?

finally ...
> Shouldn't files be closed by the OS when the program ends?

Of course files are 'closed' when the Java program
that had them loaded, has exited. No program has
them open, so they are closed.
>...If so, why
> doesn't the file ever get written?
>
> I tried making my own class which closes the file in finalize(), but
> that doesn't necessarily get called either, so that's out. There's no
> other destructor type of thing in Java.
>
> I just don't understand why Java can't close the file for me. All
> other languages do it and this is supposed to be a high level
> language. It actually acts like the file was never opened for writing
> at all. It might truncate the file to 0 bytes, but it never writes
> data to the file unless you manually close it. Can anyone explain why
> the behavior is like this?

Java was designed for robustness, extensibility
and performance, rather than lazy programmers?

The actual necessary step is "pw.flush()". If you're flushing, you don't
need the close. Note that "pw.close()" is actually performing a flush
for you.
> Shouldn't files be closed by the OS when the program ends? If so, why
> doesn't the file ever get written?

Because PrintWriter.close() flushes the stream first but the OS's
closing doesn't flush the stream.
> I tried making my own class which closes the file in finalize(), but
> that doesn't necessarily get called either, so that's out. There's no
> other destructor type of thing in Java.

Finalizers are evil. As you've discovered, they're not always called.
There are also numerous other problems. In short: eschew finalize() if
at all possible.
> I just don't understand why Java can't close the file for me. All
> other languages do it and this is supposed to be a high level
> language. It actually acts like the file was never opened for writing
> at all. It might truncate the file to 0 bytes, but it never writes
> data to the file unless you manually close it. Can anyone explain why
> the behavior is like this?

It's because you're using the API wrong. PrintWriter is a shell around a
generic Writer to make output easier. If you read the API, you'll notice
that it states that it buffers the output. The buffer is only guaranteed
to be committed when it is flushed; the default buffer size appears to
be 8 KiB, so your measly 10-character string isn't being flushed to the
output.

Constructing a FileOutputStream under default settings (internally
performed by the PrintWriter constructor you used) will truncate the
file, but it doesn't write the data until buffers are flushed (not
closed). Note that this feature is actually relatively common in
high-level languages, buffering output data. Remember that something
like disk access is actually very expensive, so buffering is a
tremendous boost in speed.

In short: it's not closing the file, it's flushing the stream when it's
actually written. It just appears to be the stream closure because
closure implies a final flush.

--
Beware of bugs in the above code; I have only proved it correct, not
tried it. -- Donald E. Knuth

Per the PrintWriter javadocs, this constructor creates a PrintWriter
with automatic flushing completely disabled: text is buffered in RAM
(internally, by a BufferedWriter) until a certain number of characters
are written. Nothing is written to the OS until the buffer is full,
flush() is called, or close() is called.

You're also missing this:
try {
> pw.print("Hello world!");

} finally {
> pw.close(); // necessary?
}

The close is not only necessary, but so necessary that you should make
sure it's called on all possible code paths - even if pw.print throws
an exception. Hence the try/finally construct.
>
> }
>
> Shouldn't files be closed by the OS when the program ends? If so, why
> doesn't the file ever get written?

The file is being closed by the OS. However, PrintWriter buffers
writes internally, either until println is called (for autoflush =
true) or until the buffer is full or flushed (for autoflush = false).
The OS has no idea that there's data pending, because your code never
tells it.
> I tried making my own class which closes the file in finalize(), but
> that doesn't necessarily get called either, so that's out. There's no
> other destructor type of thing in Java.

Don't do this. Finalize is never guaranteed to be called and
overriding it slows down garbage collection for passes involving
finalizable objects.
> I just don't understand why Java can't close the file for me. All
> other languages do it and this is supposed to be a high level
> language. It actually acts like the file was never opened for writing
> at all. It might truncate the file to 0 bytes, but it never writes
> data to the file unless you manually close it. Can anyone explain why
> the behavior is like this?

The underlying FileOutputStream is automatically closed by
finalization, but none of the other intermediate streams (at last
count: PrintWriter -> BufferedWriter -> OutputStreamWriter ->
FileOutputStream) will do anything special when they're garbage-
collected. If you want to guarantee that things written to the
PrintWriter are written to the FileOutputStream, flush or close the
writer.

close will flush the Java buffer and call OS close - and OS close
will flush OS buffer. It seems very likely to work.

flush will flush the Java buffer and image termination will
implicit close the file. But is is guaranteed that a image
termination implicit close will flush the OS buffer ? I would
have guessed that to be highly OS specific.

Arne Vajhøj wrote:
> Joshua Cranmer wrote:
>> The actual necessary step is "pw.flush()". If you're flushing, you
>> don't need the close. Note that "pw.close()" is actually performing a
>> flush for you.
>
> Is it ?
>
> close will flush the Java buffer and call OS close - and OS close
> will flush OS buffer. It seems very likely to work.

By "flushing," I mean from the Java API. Even if the OS is buffering
(which it most likely is), if the Java does not flush it to the native
system--which is clearly what is happening here--the OS doesn't see
anything when it foes to flush.
> flush will flush the Java buffer and image termination will
> implicit close the file. But is is guaranteed that a image
> termination implicit close will flush the OS buffer ? I would
> have guessed that to be highly OS specific.

I don't profess to be an expert in filesystems, but for the average
user, an OS flush or close will cause the changes it sees to be
committed so that it is visible externally. The reality is probably much
more convoluted.

--
Beware of bugs in the above code; I have only proved it correct, not
tried it. -- Donald E. Knuth

Joshua Cranmer wrote:
> Arne Vajhøj wrote:
>> Joshua Cranmer wrote:
>>> The actual necessary step is "pw.flush()". If you're flushing, you
>>> don't need the close. Note that "pw.close()" is actually performing a
>>> flush for you.
>>
>> Is it ?
>>
>> close will flush the Java buffer and call OS close - and OS close
>> will flush OS buffer. It seems very likely to work.
>
> By "flushing," I mean from the Java API. Even if the OS is buffering
> (which it most likely is), if the Java does not flush it to the native
> system--which is clearly what is happening here--the OS doesn't see
> anything when it foes to flush.
>
>> flush will flush the Java buffer and image termination will
>> implicit close the file. But is is guaranteed that a image
>> termination implicit close will flush the OS buffer ? I would
>> have guessed that to be highly OS specific.
>
> I don't profess to be an expert in filesystems, but for the average
> user, an OS flush or close will cause the changes it sees to be
> committed so that it is visible externally. The reality is probably much
> more convoluted.

I will not call myself an expert in that area either.

But calling close instead of flush in Java sounds much more safe
to me regarding getting the OS buffer written to the plates.

Arne Vajhøj wrote:
> Joshua Cranmer wrote:
>> Arne Vajhøj wrote:
>>> Joshua Cranmer wrote:
>>>> The actual necessary step is "pw.flush()". If you're flushing, you
>>>> don't need the close. Note that "pw.close()" is actually performing
>>>> a flush for you.
>>>
>>> Is it ?
>>>
>>> close will flush the Java buffer and call OS close - and OS close
>>> will flush OS buffer. It seems very likely to work.
>>
>> By "flushing," I mean from the Java API. Even if the OS is buffering
>> (which it most likely is), if the Java does not flush it to the native
>> system--which is clearly what is happening here--the OS doesn't see
>> anything when it foes to flush.
>>
>>> flush will flush the Java buffer and image termination will
>>> implicit close the file. But is is guaranteed that a image
>>> termination implicit close will flush the OS buffer ? I would
>>> have guessed that to be highly OS specific.
>>
>> I don't profess to be an expert in filesystems, but for the average
>> user, an OS flush or close will cause the changes it sees to be
>> committed so that it is visible externally. The reality is probably
>> much more convoluted.
>
> I will not call myself an expert in that area either.
>
> But calling close instead of flush in Java sounds much more safe
> to me regarding getting the OS buffer written to the plates.

Unless there is something in the contracts for Java flush and close
that I am not aware of. Which is absolutely a possibility.

Joshua Cranmer wrote:
> Note that this feature is actually relatively common in
> high-level languages, buffering output data. Remember that something
> like disk access is actually very expensive, so buffering is a
> tremendous boost in speed.

Anyone want to know why there's two layers of buffering in Java?
It's not that Java doesn't trust the OS buffering. It's because each
trip through JNI to call an OS API routine is expensive.

So Java buffers because each JNI call is expensive. Then the OS buffers
because each disk write is expensive.

Another fifty years from now we'll probably have a big teetering tower
of abstractions and I/O will get buffered at six or seven layers instead
of just two.

Wait, make that three. I think most modern disk controllers do some
buffering of their own, because waiting for the right spot on a platter
to rotate under the write head is expensive, and waiting for the head to
move to a different cylinder is even more expensive.

This is not phpBB. This is Usenet, which is generally pure text. The
standard way of indicating boldness in pure text is with *a pair of
asterisks.*
> It's not that Java doesn't trust the OS buffering. It's because each
> trip through JNI to call an OS API routine is expensive.

I'm not an expert as to where the buffering is, but I'm pretty sure the
call to the OS-level write routines are expensive in and of themselves.
> Another fifty years from now we'll probably have a big teetering tower
> of abstractions and I/O will get buffered at six or seven layers instead
> of just two.

So? There's already high-level API buffering, filesystem buffering, and
probably disk-level buffering as well. As long as they can be reasonably
guarded against concurrency issues, there's no problem.
>
> Wait, make that three. I think most modern disk controllers do some
> buffering of their own, because waiting for the right spot on a platter
> to rotate under the write head is expensive, and waiting for the head to
> move to a different cylinder is even more expensive.
>
> - jenny

--
Beware of bugs in the above code; I have only proved it correct, not
tried it. -- Donald E. Knuth

By design, Usenet is supposed to be usable in raw text mode. It is
bad form to embed HTML, so we use conventions like slash for /italics/
and asterisk for *bold*. Some newsreaders interpret those
conventions, and even grey out sigs set off by "dash dash space" ("--
") on a line by itself. That is up to the newsreader. The rest of us
do it by imagination.

On Mon, 17 Nov 2008 07:32:59 -0800, Lew wrote:
> J. Davidson wrote:
>>> Another fifty years from now we'll probably have a big teetering tower
>>> of abstractions and I/O will get buffered at six or seven layers
>>> instead of just two.
>
> Joshua Cranmer <> wrote:
>> So? There's already high-level API buffering, filesystem buffering, and
>> probably disk-level buffering as well. As long as they can be
>> reasonably guarded against concurrency issues, there's no problem.
>
> "Disks are a hack."
> - Alan Cooper, /About Face/
>
> Disks are a hack because it's too expensive to buy a terabyte of static
> RAM.
>
> Fifty years from now hard disks will be obsolete.

....only if somebody designs reliable non-volatile RAM with either a multi-
decade storage and read-only lifetime or at least a million-fold increase
in the number of write cycles it can handle without failing.

On Mon, 17 Nov 2008, Martin Gregorie wrote:
> On Mon, 17 Nov 2008 07:32:59 -0800, Lew wrote:
>
>> J. Davidson wrote:
>>>> Another fifty years from now we'll probably have a big teetering tower
>>>> of abstractions and I/O will get buffered at six or seven layers
>>>> instead of just two.
>>
>> Joshua Cranmer <> wrote:
>>> So? There's already high-level API buffering, filesystem buffering, and
>>> probably disk-level buffering as well. As long as they can be
>>> reasonably guarded against concurrency issues, there's no problem.
>>
>> "Disks are a hack."
>> - Alan Cooper, /About Face/
>>
>> Disks are a hack because it's too expensive to buy a terabyte of static
>> RAM.
>>
>> Fifty years from now hard disks will be obsolete.
>
> ...only if somebody designs reliable non-volatile RAM with either a multi-
> decade storage and read-only lifetime or at least a million-fold increase
> in the number of write cycles it can handle without failing.

Wrong. Because tape's going to make a comeback - I GUARANTEE IT!

tom

--
Work alone does not suffice: the efforts must be intelligent. -- Charles
B. Rogers

Martin Gregorie wrote:
> ...only if somebody designs reliable non-volatile RAM with either a multi-
> decade storage and read-only lifetime or at least a million-fold increase
> in the number of write cycles it can handle without failing.

Or they develop a different form of offline storage with better
performance than hard drives and higher capacity, which I deem
extremely likely. RAM and hard drives are not the only two ways to
store data even today, so I figure other technologies are just around
the corner, and that doesn't even account for ideas not yet
conceived. Fifty years is eons of innovation in I.T. and electronics.

I have yet to have a hard drive last one decade, much less multiple
decades, so that part of the argument leaves me cold. I know of no
serious project that doesn't back up its hard drives, so I figure my
experience isn't unique.

So I take exception to the "only if" part of your argument.
Additionally, someone very well might come up with "reliable non-
volatile RAM with either a multi-decade storage and read-only lifetime
[which would then be better than hard drives are now][,] or at least a
million-fold increase in the number of write cycles it can handle
without failing."

So far no electronic medium exceeds the read-only lifetime of ink on
paper.

--
Lew
No other virtual reality system has been invented that outperforms the
novel, given a trained user.

Share This Page

Welcome to The Coding Forums!

Welcome to the Coding Forums, the place to chat about anything related to programming and coding languages.

Please join our friendly community by clicking the button below - it only takes a few seconds and is totally free. You'll be able to ask questions about coding or chat with the community and help others.
Sign up now!