I2PSnarkServlet / SnarkManager DirMonitor
Opened 10 years ago
Last modified 6 years ago
#371accepteddefect
I2PSnarkServlet / SnarkManager DirMonitor
Reported by:John DooOwned by:zzz Priority: minor Milestone: 0.9.25 Component: apps/i2psnark Version: 0.8.2 Keywords:
Cc:
Parent Tickets:
Sensitive: no
Description
I2PSnarkServlet "Create".equals(action)" already contains a note that a newly created .torrent metainfo file could be read by DirMonitor? before it is completely written to disc (" _DirMonitor? could grab this first, maybe hold _snarks lock?")
A simple solution is to create the file with a temporary suffix first (".torren_"), and only rename it to its final name after the stream has been closed:_
So my suggestion is:
private static final String TEMP_TORRENT_SUFFIX = ".torren_";
File torrentFile = new File(baseFile.getParent(),baseFile.getName() + TORRENT_SUFFIX);
File tempTorrentFile = new File(baseFile.getParent(),baseFile.getName() + TEMP_TORRENT_SUFFIX);
…
out.close();
tempTorrentFile.renameTo(torrentFile);
The same solution can also be used in FetchAndAdd?, as there is a similar problem: during the timed the fetched .torrent file is copied from the temporary directory to the data directory, DirMonitor? could try to read the partially copied file.
A different way to accomplish the same result is to aquire an exclusive FileLock? on the destination file. The steps are:
File destination = …;
FileOutputStream? fOut = new FileOutputStream?(destination);
OutputStream? out = new BufferedOutputStream?(fOut);
FileChannel? fc = fOut.getChannel();
FileLock? fileLock = fc.tryLock(); _non-block
[copy the content from in to out]
fileLock.release();_
This could be incorporated in FileUtil?.copy(String source, String dest, boolean overwriteExisting, boolean lockDestination).
Sincerely Yours
John Doo