wood burning stoves 2.0*
The moose likes Java in General and the fly likes FileWriter.write(String str) Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Android Security Essentials Live Lessons this week in the Android forum!
JavaRanch » Java Forums » Java » Java in General
Bookmark "FileWriter.write(String str)" Watch "FileWriter.write(String str)" New topic
Author

FileWriter.write(String str)

sarah Marsh
Ranch Hand

Joined: Mar 06, 2001
Posts: 282
Hello:

After I create a fileWriter, I use
fileWriter.write(message);
to write a very long string to a file.

There's another process B reading the file, how to make sure when process B reads the file, the file is already generated totally?

Thanks a lot!
Keith Lynn
Ranch Hand

Joined: Feb 07, 2005
Posts: 2367
I would wrap a PrintWriter around the FileWriter before writing to the file. Also if you use synchronized methods you can prevent the thread that tries to read from the file from executing until the method that writes to the file is finished.
Jeff Albertson
Ranch Hand

Joined: Sep 16, 2005
Posts: 1780
Because you are dealing with separate processes, the solution is probably outside the realm of Java. The standard solution, as well as a best practice, is to write to a temporary file and then have the writer *rename* the file to its proper directory. Not only does this solve your problem, it keeps your target directory free from junk files caused by the writing program pooping out half way through its writing task, for example.
[ February 03, 2006: Message edited by: Jeff Albertson ]

There is no emoticon for what I am feeling!
Jeff Albertson
Ranch Hand

Joined: Sep 16, 2005
Posts: 1780
BTW, synchronization has no effect on separate processes...
sarah Marsh
Ranch Hand

Joined: Mar 06, 2001
Posts: 282
Actually, the process B is a FTP process, how to make sure in this case?
Keith Lynn
Ranch Hand

Joined: Feb 07, 2005
Posts: 2367
What I meant was have two methods, one in which the writing is done, and one in which the reading is done.
Jeff Albertson
Ranch Hand

Joined: Sep 16, 2005
Posts: 1780
Originally posted by sarah Marsh:
Actually, the process B is a FTP process, how to make sure in this case?


That wasn't addressed to my posts, eh? In renaming, the writer (process A) does the renaming. Process B is unaware of this.
wise owen
Ranch Hand

Joined: Feb 02, 2006
Posts: 2023
Java Thread Programming: Implement Read & Write Locks.
Jeff Albertson
Ranch Hand

Joined: Sep 16, 2005
Posts: 1780
I'm just pouring vinegar on this thread!

If you are thinking of using locks, be warned. As the API for java.nio.channels/FileLock states:

Whether or not a lock actually prevents another program from accessing the content of the locked region is system-dependent and therefore unspecified. The native file-locking facilities of some systems are merely advisory, meaning that programs must cooperatively observe a known locking protocol in order to guarantee data integrity. On other systems native file locks are mandatory, meaning that if one program locks a region of a file then other programs are actually prevented from accessing that region in a way that would violate the lock. On yet other systems, whether native file locks are advisory or mandatory is configurable on a per-file basis. To ensure consistent and correct behavior across platforms, it is strongly recommended that the locks provided by this API be used as if they were advisory locks.

I've always found file locks to be advisory. YMMV
sarah Marsh
Ranch Hand

Joined: Mar 06, 2001
Posts: 282
Jeff,

I posted the second one before I saw your response.

But how to make sure the file creation is done before the renaming? synchronization here?

Thanks.
Ernest Friedman-Hill
author and iconoclast
Marshal

Joined: Jul 08, 2003
Posts: 24183
    
  34

Originally posted by sarah Marsh:
Jeff,

I posted the second one before I saw your response.

But how to make sure the file creation is done before the renaming? synchronization here?

Thanks.


They're both done by the same process, so you simply do them in order.

1) Write file
2) Close it
3) Rename it


[Jess in Action][AskingGoodQuestions]
sarah Marsh
Ranch Hand

Joined: Mar 06, 2001
Posts: 282
Should I do something like this:
fileWriter.write(message);
fileWriter.close();
// then rename it
...


fileWriter.close(); will wait for writing to be done?
Jeff Albertson
Ranch Hand

Joined: Sep 16, 2005
Posts: 1780
Originally posted by sarah Marsh:

fileWriter.close(); will wait for writing to be done?


I took a quick in the API assuming there would be such an assurance, but I didn't find it. It may be there, but if not, you can always explicitly sync up with your file system:

It's important that you do this in order: flush/sync/close. If you sync first, then any data buffered in memory is not considered and if you sync after closing, that's an error -- one must sync on an open file.

Again, I'm not sure this is strictly needed, but it can't hurt (okay, sync can slow things down a little, but that's the price of ordering operations.)
[ February 03, 2006: Message edited by: Jeff Albertson ]
sarah Marsh
Ranch Hand

Joined: Mar 06, 2001
Posts: 282
what if I use FileWriter(File file) not FileWriter(FileDescriptor fd),
there's no sync() method on 'file' object? Thanks again!
Jeff Albertson
Ranch Hand

Joined: Sep 16, 2005
Posts: 1780
... You'll have to rewrite your code. File objects merely represent the path rather than the file as a resource. What's happening in your code is that the FileWriter's constructor is creating a FileOutputStream but it is not exposing it. You'll have to rewrite your code slightly to be more deliberate.
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
I never liked FileWriters much anyway, as they don't let you specify an encoding. So this is just another reason not to use them. Note that you can also use a FileChannel or MappedByteBuffer, both of which have a force() method that does basically the same thing as sync().

As for assurances in the API, in fact the API for Writer specifically tells us that (a) close() implies flush(), but also (b) flush() does not guarantee an immediate write to the file:

"If the intended destination of this stream is an abstraction provided by the underlying operating system, for example a file, then flushing the stream guarantees only that bytes previously written to the stream are passed to the operating system for writing; it does not guarantee that they are actually written to a physical device such as a disk drive."

So, it does seem that a sync() or force() is necessary to ensure the file is completely written before the move, in general. Annoying but true...


"I'm not back." - Bill Harding, Twister
Jeff Albertson
Ranch Hand

Joined: Sep 16, 2005
Posts: 1780
Originally posted by Jim Yingst:
I never liked FileWriters much anyway...


I'm always suspicious of derived classes that only define constructors.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: FileWriter.write(String str)
 
Similar Threads
BufferedWriter Vs FileWriter
How not to hard-code file location in java?
Dumping MySql database
Enter in text file
File Navigation Exception