Reputation: 4165
I'm trying to work out how I can copy a growing file using Java. An example of what I would like to work is the following:
I have used the following code:
InputStream is = new FileInputStream(sourceFile);
OutputStream os = new FileOutputStream(targetFile);
byte[] buf = new byte[8192];
int num;
while ((num = is.read(buf)) != -1) {
os.write(buf, 0, num);
}
But that only copies the content that has so far been downloaded, so I end up with a broken target file.
I have also tested using BufferedInputStream and BufferedOutputStream, but that didn't work either.
Is there any way to achieve what I want?
Thanks
Upvotes: 2
Views: 579
Reputation: 500457
This is going to be tricky, since the copying process has no reliable way of knowing when the download has finished. You could look at whether the file is growing, but the download could stall for a period of time, and you could erroneously conclude that it has finished. If the download fails in the middle, you also have no way of knowing that you're looking at an incomplete file.
I think your best bet is the downloading process. If you control it, you could modify it to store the file in the other location, or both locations, or move/rename it at the end, depending on your requirements.
If you don't control the downloading process, and it's a simple HTTP download, you could replace it with something that you do control.
Upvotes: 2
Reputation: 54705
If you are in control off the file download via HTTP then you could download to a temporary file and then rename the file once the download has completed, thus making the operation atomic.
The alternative is for your file copy process to periodically check the file size of the target file and to only initiate the copy once the file size has stabilised and is no longer increasing. For example, you may elect to record the file size every second and only initiate the copy if the size remains constant for 3 successive poll attempts.
Upvotes: 2