SalkinD
SalkinD

Reputation: 783

Java Copy File, but make sure no other app writes to it

I have following situation: A (foreign) File Server creates files in a directory. My app tries to index some information in these files and move them to another folder, this should happen almost instantly. What is the best way (java) making sure no other app reads/writes to this file?

Upvotes: 0

Views: 89

Answers (4)

Anonymous Coward
Anonymous Coward

Reputation: 3200

I'll assume the worst case : You have no control over the server.

Make an atomic move of the file to a temporal directory. Process it. Finally move the file to its destination.

Use this helper class :

import java.io.File;
import java.io.IOException;
import java.nio.file.AtomicMoveNotSupportedException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;

public class FileHelper
{
    public static File capture(String prefixForTmpDir, File fileToMove )
            throws AtomicMoveNotSupportedException, IOException
    {
        Path tmpDir = Files.createTempDirectory( prefixForTmpDir );
        Path tmpFile = new File( tmpDir.toFile(), "file.tmp").toPath() ;
        Files.move(fileToMove.toPath(), tmpFile, StandardCopyOption.ATOMIC_MOVE );
        return tmpFile.toFile();
    }

    public static void completeMove( File captured, File dest )
            throws AtomicMoveNotSupportedException, IOException
    {
        Files.move( captured.toPath(), dest.toPath(), StandardCopyOption.ATOMIC_MOVE );
        File tmpDir = new File( captured.getParent() );
        tmpDir.delete();
    }
}

And in your app, assuming fil1 is the file you want to process and fil2 is where you wish to move it then you would need to :

final String TMP_DIR = "/tmp or C:\\TMP or some dir where your app can write";
File captured = null;
try
{
    captured = FileHelper.capture( TMP_DIR, fil1 );
    processFile( captured );
    FileHelper.completeMove( captured, fil2 );
}
catch ( AtomicMoveNotSupportedException ex )
{
    if ( captured == null )
    {
        // File could not be moved to temp dir, possibly server is writing to it.
        // will need to retry again
    }
    else
    {
        assert false;
        // File could be moved to temp dir. But then could not be moved out of it.
        // Should not happen.
    }
}

Upvotes: 1

yanana
yanana

Reputation: 2331

Create temporary directory using Files.createTempDirectory, then move the file to the directory and manipulate it. You would have to remove the directory on the end of the operation; e.g. by Runtime.addShutdownHook.

Upvotes: 1

fdreger
fdreger

Reputation: 12495

If you don't control the file server, then probably the only general way would be to move the file to some temporary, private directory on the file server, and then index and move to the final location.

Mind that you will be responsible for any cleaning up, and if you require any transactional properties (like surviving a reset while indexing the file), you will be on your own.

Upvotes: 0

Uma Kanth
Uma Kanth

Reputation: 5629

Encrypt your data, Such that no other application can understand it.

Create a readonly file.

File file = new File("c:/file.txt");
//mark this file as read only, since jdk 1.2
file.setReadOnly();

Upvotes: 0

Related Questions