Frage

I developed a java program which is writing data into a file(temporary file) using asynchronousFileChannel.
Now each time it writes a entry to the file a second method will be called which will check for its size and if its size exceeds a pre thresold size say 10000 bytes,all the file contents should be moved to a different file(permanent Datarecord).
What should i use so that no data should be lost while moving data from temp file to permanent file while the temporary file is still been accessed by different threads.

War es hilfreich?

Lösung 3

Here's the code I wrote for you...

public class RollMyFile {

    private long FILE_MAX_SIZE;
    private String fileName;

    /**
     * Constructor to take in the initial file name and the maxFileSize
     * @param fileNameToStartWith
     */
    public RollMyFile(String fileNameToStartWith, long maxFileSize) {
        this.fileName = fileNameToStartWith;
        this.FILE_MAX_SIZE = maxFileSize;
    }

    /**
     * Synchronized to roll over to a new file
     * 
     * @param fileChannel
     * @return
     * @throws IOException
     */
    public synchronized AsynchronousFileChannel rollMeIfNeeded(AsynchronousFileChannel fileChannel) throws IOException {
        if(fileChannel.size()>FILE_MAX_SIZE) {
            this.fileName = getNewRolledFileName(this.fileName);
            File file = new File(this.fileName);
            file.createNewFile();
            fileChannel = getAsyncChannel(this.fileName);
        }
        return fileChannel;
    }

    /**
     * Change this to create a new name for the roll over file
     * @param currentFileName
     * @return
     */
    public String getNewRolledFileName(String currentFileName) {
        if (currentFileName.contains(".")) {
            currentFileName = currentFileName.substring(0,
                    currentFileName.lastIndexOf('.'));
        }
        return currentFileName+ "." + Calendar.getInstance().getTimeInMillis();
    }

    /**
     * This is where you request to write a whole bunch of stuff that
     * you said you want to store
     * 
     * @param stuffToWrite
     * @throws IOException
     */
    public void write(StringBuffer stuffToWrite) throws IOException {
        AsynchronousFileChannel fileChannel = getAsyncChannel(this.fileName);
        fileChannel = rollMeIfNeeded(fileChannel);
        ByteBuffer byteBuffer = ByteBuffer.wrap(stuffToWrite.toString().getBytes());
        fileChannel.write(byteBuffer, fileChannel.size());
    }

    /**
     * Change this to how ever you 'open' the AsynchronousFileChannel
     * 
     * @param givenFileName
     * @return
     * @throws IOException
     */
    private AsynchronousFileChannel getAsyncChannel(String givenFileName) throws IOException {
        return AsynchronousFileChannel.open(Paths.get(givenFileName), StandardOpenOption.WRITE);
    }

}

And I used it like below

public class Tester {

    public static void main(String[] args) {

        RollMyFile rmf = new RollMyFile("my-current-file", 1000);
        try {
            for(int i=1; i<1000; i++) {
                rmf.write(new StringBuffer(" lots of important stuff to store... "));
                System.out.println(i);
            }
            System.out.println("end");
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

}

Andere Tipps

10,000 bytes is not very much, it is just <10kb. So I think you can buffer all this data in queue and when size exceeds you can clear(delete-create) temporary file and flush queue data to permanent storage file.

Since you are using AsynchronousFileChannel, there is always a problem that when one of your methods is trying to move the file, another thread might be trying to read/write to it.

You need to do the move by other means.

If what you are doing is logging, which I think you might be doing - use a FileHandler to roll the file. See an example here - http://kodejava.org/how-do-i-create-a-rolling-log-files/

You can also see some discussion about rolling files here - Rolling file implementation

Another one on stackoverflow - Rolling logs by both size and time

And another one - How to write statistical data into rolling files in java

Hope this helps. Good Luck.

Just close the file, rename it, and open a new one. You're overthinking this.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top