Garantir flush em processos externos

Tenho uma aplicação que roda externamente um compilador. Em seguida, roda uma outra ferramenta que usa o resultado da compilação para realizar uma série de tarefas. Ambas são escritas em C.

Disparo essas duas aplicações através do Java, usando para isso as classes ProcessBuilder e Process. Aguardo o termino da execução usando waitFor() e depois disso garanto a leitura completo de ambas as streams de saída.

Agora, observei um comportamento estranho: algumas vezes o compilador roda e o Java dispara a outra ferramenta antes que o arquivo gerado por ele esteja completamente gravado no disco. É como se o sistema operacional (no nosso caso o Windows), indicasse ao Java que o processo terminou antes de dar completamente o flush nos arquivos.

Tenho certeza que não é a ferramente que está gerando o arquivo pela metade, pois já conferi isso. Mesmo nas situações onde o erro ocorre, olhar o arquivo externamente mostra um arquivo completo.

Então pergunto. Existe alguma forma de garantir esse flush, seja ela no Java ou no próprio C? No C, a aplicação faz flush() normalmente antes de finalizar.

Não seria o caso de criar uma Thread específica para a gravação dos dados no disco e para o flush() ?!?!?!
Talvez isso lhe garanta que o processo não seja executado pela metade.

Criando uma thread, continuo não garantindo que o processo externo escreveu os dados no disco.

O que vamos tentar fazer é fazer com que o compilador escrito em C dê um fflush() na versão linux, e um _commit() na versão windows. Aparentemente essas duas funções forçam o flush no disco, não simplesmente o esvaziamento dos buffers de memória.

É isso ai…
Foi apenas uma´idéia!
Abraço!

Pra quem garantir a escrita do dado em disco usando o Java, olha só o que eu achei no Java Developers Almanac:

e27. Forcing Updates to a File to the DiskIn some applications, such as transaction processing, it is necessary to ensure that an update has been made to the disk. FileDescriptor.sync() blocks until all changes to a file are written to disk.

[code]
try {
// Open or create the output file
FileOutputStream os = new FileOutputStream(“outfilename”);
FileDescriptor fd = os.getFD();

    // Write some data to the stream
    byte[] data = new byte[]{(byte)0xCA, (byte)0xFE, (byte)0xBA, (byte)0xBE};
    os.write(data);

    // Flush the data from the streams and writers into system buffers.
    // The data may or may not be written to disk.
    os.flush();

    // Block until the system buffers have been written to disk.
    // After this method returns, the data is guaranteed to have
    // been written to disk.
    fd.sync();

} catch (IOException e) {
}[/code]
Fonte: http://www.exampledepot.com/egs/java.io/Sync.html

Notem que o flush só garante o esvaziamento dos buffers da memória. O processo de escrita para o SO, que tem seus próprios buffers, então é possível que um arquivo muito longo continue parcialmente escrito mesmo após o flush. Só com o sync isso fica 100% garantido.

Não achei, entretanto, como um processo que irá ler o arquivo possa perguntar para um SO se esse arquivo está realmente sincronizado. Aparentemente, essa é uma tarefa que deve ser garantida por quem escreve.