2

非同期ファイル チャネルを使用してファイル (一時ファイル) にデータを書き込む Java プログラムを開発しました。
ファイルにエントリを書き込むたびに、そのサイズをチェックする 2 番目のメソッドが呼び出され、そのサイズが 10000 バイトなどのしきい値のサイズを超えている場合は、すべてのファイルの内容を別のファイル (永続的なデータレコード) に移動する必要があります。 .
一時ファイルがまだ別のスレッドによってアクセスされている間に、一時ファイルから永続ファイルにデータを移動するときにデータが失われないようにするには、何を使用すればよいですか。

4

4 に答える 4

2

10,000 バイトは大した量ではなく、わずか 10kb 未満です。したがって、このすべてのデータをキューにバッファリングし、サイズを超えると、一時ファイルをクリア (削除-作成) し、キュー データを永続的なストレージ ファイルにフラッシュできると思います。

于 2013-09-18T06:32:29.717 に答える
1

これが私があなたのために書いたコードです...

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);
    }

}

そして、私は以下のようにそれを使用しました

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();
        }

    }

}
于 2013-09-19T07:22:09.413 に答える
1

ファイルを閉じて名前を変更し、新しいファイルを開くだけです。あなたはこれを考えすぎています。

于 2013-09-18T06:48:55.277 に答える