J'utilise MappedByteBuffer pour écrire des enregistrements dans un fichier. Voici mon code. Il lance BufferOverflowException lorsque j'augmente le nombre de lignes à écrire. Cela fonctionne bien pour 10 millions numberOfRows. Si j'augmente numberOfRows à 100 millions, il lance BufferOverlowException !?MappedByteBuffer - BufferOverflowException
public static void writeOneFile() throws IOException{
File file = File.createTempFile("outputfile", ".txt", new File("C:\\Data\\Output"));
//f.delete();
RandomAccessFile fileAccess = new RandomAccessFile(file, "rw");
FileChannel fileChannel = fileAccess.getChannel();
long bufferSize = (long) (Math.pow(10240, 2));//(long)(Math.pow(30720, 2));//(long) (Math.pow(1024, 2));//(long)Integer.MAX_VALUE;
MappedByteBuffer mappedBuffer = fileChannel.map(FileChannel.MapMode.READ_WRITE, 0, bufferSize);
long startPosMappedBuffer = 0;
long million = 1000000;
long numberOfRows = million * 100; //million * 200 ;//1000;//million * 200 ; //200 million
long startTime = System.currentTimeMillis();
long counter = 1;
//byte[] messageBytes = (counter+"").getBytes(Charset.forName("UTF-8"));
//long bufferSize = (counter + "\n").getBytes(Charset.forName("UTF-8")).length * 1000;
while(true)
{
if(!mappedBuffer.hasRemaining())
{
startPosMappedBuffer += mappedBuffer.position();
mappedBuffer = fileChannel.map(FileChannel.MapMode.READ_WRITE, startPosMappedBuffer, bufferSize);
}
mappedBuffer.put((counter + System.lineSeparator()).getBytes(Charset.forName("UTF-8"))); //+ System.lineSeparator() //putLong(counter); //);
//mappedBuffer.rewind();
counter++;
if(counter > numberOfRows)
break;
}
fileAccess.close();
long endTime = System.currentTimeMillis();
long actualTimeTaken = endTime - startTime;
System.out.println(String.format("No Of Rows %s , Time(sec) %s ", numberOfRows, actualTimeTaken/1000f)) ;
}
Des indices sur le problème?
Édition 1: Le problème d'exception est résolu et résolu comme ci-dessous.
Édition 2: Concernant la meilleure option pour la performance.
@EJP: voici le code utilisant DataOutputStream autour de BufferedOutputStream.
static void writeFileDataBuffered() throws IOException{
File file = File.createTempFile("dbf", ".txt", new File("C:\\Output"));
DataOutputStream out = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(file)));
long counter = 1;
long million = 1000000;
long numberOfRows = million * 100;
long startTime = System.currentTimeMillis();
while(true){
out.writeBytes(counter + System.lineSeparator());
counter++;
if (counter > numberOfRows)
break;
}
out.close();
long endTime = System.currentTimeMillis();
System.out.println("Number of Rows: "+ numberOfRows + ", Time(sec): " + (endTime - startTime)/1000f);
}
.......... Merci
'MappedByteBuffers' ont pratiquement nul effet sur la performance. Vous devriez commencer par un 'DataOutputStream' autour d'un' BufferedOutputStream' et ensuite voir si vous avez vraiment un problème de performance d'E/S. – EJP
@EJP: Merci pour votre commentaire. J'ai essayé tous les deux de dériver l'approche optimale. Mes résultats pour 100 millions de disques sont:
DataOutputStream -> Nombre de lignes: 100000000, Temps (s): 31,707 MappedByteBuffer -> Nombre de lignes: 100000000, Temps (s): 16,576 – Gana
Puis-je savoir la raison vers le bas vote? Est-ce le changement de portée de la question? – Gana