OutOfMemoryError avec gros fichier

OutOfMemoryError avec gros fichier - Java - Programmation

Marsh Posté le 02-10-2006 à 16:52:24    

Slt,
 
je veut copier le contenu d'un fichier (10G) dans un autre fichier, donc je fait comme ceci:
 
IOUtils.copy(is, out);  
out.close();
is.close();
 
où 'is' est l'inputStream de mon fichier source et 'out' est l'outputStream de mon fichier cible.
 
Seulement voila, dès que mon fichier source commence à faire 1G ou plus j'ai l'erreur OutOfMemoryError.
 
Quelqu'un aurait une autre idée pour ne pas avoir cet erreur?
 
Merci d'avance pour votre aide.

Reply

Marsh Posté le 02-10-2006 à 16:52:24   

Reply

Marsh Posté le 02-10-2006 à 16:58:33    

faire ça de manière plus intelligente, en passant par un buffer ? :o

Reply

Marsh Posté le 02-10-2006 à 17:02:43    

en utilisant nio plutot que commons-io ?

Reply

Marsh Posté le 02-10-2006 à 17:04:36    

ben j'la trouve intelligente ma maniere ;)
mais j'vais regarder avec un buffer, merci pour ton avis

Reply

Marsh Posté le 02-10-2006 à 17:05:54    

ah j'connais pas nio j'vais regarder merci

Reply

Marsh Posté le 02-10-2006 à 17:10:23    

parait que CopyUtils.copy gère mieux les gros fichiers

Reply

Marsh Posté le 02-10-2006 à 17:15:26    

CopyUtils est Deprecated...

Reply

Marsh Posté le 02-10-2006 à 17:21:41    

ah, ok, je savais pas

Reply

Marsh Posté le 02-10-2006 à 17:25:00    

avec les buffer j'ai la meme erreur:
j'ai fait:
 
BufferedInputStream is = new BufferedInputStream(myInputStream);
long l = is.available();
         
BufferedOutputStream out = new BufferedOutputStream(myOutputStream);
for(long i=0;i<l;i++) {
     out.write(is.read());
}
out.flush();
out.close();
is.close();        
 
où 'myInputStream' est l'inputStream de mon fichier source et 'myOutputStream' est l'outputStream de mon fichier cible.

Reply

Marsh Posté le 03-10-2006 à 09:01:03    

donc maintenant tu vas regarder nio j'imagine ? [:itm]
 

Code :
  1. // Create channel on the source
  2.        FileChannel srcChannel = new FileInputStream("srcFilename" ).getChannel();
  3.    
  4.        // Create channel on the destination
  5.        FileChannel dstChannel = new FileOutputStream("dstFilename" ).getChannel();
  6.    
  7.        // Copy file contents from source to destination
  8.        dstChannel.transferFrom(srcChannel, 0, srcChannel.size());
  9.    
  10.        // Close the channels
  11.        srcChannel.close();
  12.        dstChannel.close();


 
(je mets pas le code pour la gestion d'exception, le block finally tout ca hein [:dawao])

Reply

Marsh Posté le 03-10-2006 à 09:01:03   

Reply

Marsh Posté le 03-10-2006 à 10:01:27    

En fait je vient de me rendre compte que ce n'est pas au moment de la copie de fichier que j'ai l'erreur OutOfMemoryError, c'est lorsque je recupere l'inputStream du fichier source:
Code :
 
InputStream in = file.getContent().getInputStream();
 
Comment faire autrement? (file est un FileObject de l'API commons-VFS)

Reply

Marsh Posté le 03-10-2006 à 10:26:49    

zizou771 a écrit :


InputStream in = file.getContent().getInputStream();
Comment faire autrement? (file est un FileObject de l'API commons-VFS)


bha, surement que ca lit le fichier ... te sers pas de cet objet .... utilise un FileInputStream direct ...
 
sinon, pour ceux qui veule un code compatible java < 1.4, vla une classe que j'ai souvent l'occasion de refourguer :

Code :
  1. import java.io.*;
  2. /**
  3. * This class contains usefull methods usually needed when working with streams  
  4. */
  5. public class StreamUtils {
  6. /**
  7.  * the default buffer size is 1Ko
  8.  */
  9. public static final int DEFAULT_BUFFER_SIZE = 1024;
  10. /**
  11.  * copy the data from the input stream to the output stream using the default buffer size
  12.  * @see #DEFAULT_BUFFER_SIZE
  13.  */
  14. public static void copy(InputStream inStream, OutputStream outStream) throws IOException {
  15.  copy(inStream, outStream, DEFAULT_BUFFER_SIZE);
  16. }
  17. /**
  18.  * copy the data from the input stream to the output stream using a buffer with the specied size
  19.  */
  20. public static void copy(InputStream inStream, OutputStream outStream, int bufferSize) throws IOException {
  21.  byte[] buffer = new byte[bufferSize];
  22.  int nbRead;
  23.  while ((nbRead = inStream.read(buffer)) != -1) {
  24.   outStream.write(buffer, 0, nbRead);
  25.  }
  26. }
  27. /**
  28.  * copy the data from the reader to the writer using the default buffer size
  29.  * @see #DEFAULT_BUFFER_SIZE
  30.  */
  31. public static void copy(Reader reader, Writer writer) throws IOException {
  32.  copy(reader, writer, DEFAULT_BUFFER_SIZE);
  33. }
  34. /**
  35.  * copy the data from the reader to the writer using a buffer with the specied size
  36.  */
  37. public static void copy(Reader reader, Writer writer, int bufferSize) throws IOException {
  38.  char[] buffer = new char[bufferSize];
  39.  int nbRead;
  40.  while ((nbRead = reader.read(buffer)) != -1) {
  41.   writer.write(buffer, 0, nbRead);
  42.  }
  43. }
  44. /**
  45.  * read the data in the input stream using the default JVM charset and return it in a String
  46.  */
  47. public static String toString(InputStream inStream) throws IOException {
  48.  return toString(inStream, null);
  49. }
  50. /**
  51.  * read the data in the input stream using the specified charset and return it in a String
  52.  */
  53. public static String toString(InputStream inStream, String charSet) throws IOException {
  54.  InputStreamReader reader = (charSet == null) ?  new InputStreamReader(inStream) : new InputStreamReader(inStream, charSet);
  55.  return toString(reader);
  56. }
  57. /**
  58.  * read the data in the reader and return it in a String
  59.  */
  60. public static String toString(Reader reader) throws IOException {
  61.  CharArrayWriter writer = new CharArrayWriter();
  62.  copy(reader, writer);
  63.  return writer.toString();
  64. }
  65. }


 
et ca s'utilise comme ça :
 

Code :
  1. FileChannel src= new FileInputStream("srcFilename" );
  2.        FileChannel dest= new FileOutputStream("dstFilename" );
  3.        StreamUtils.copy(src, dest);
  4.        src.close();
  5.        dest.close();


(avec une gestion d'exception qui va bien :o)

Reply

Marsh Posté le 03-10-2006 à 10:48:10    

FileInputStream c'est pour du local...

Reply

Marsh Posté le 03-10-2006 à 10:50:39    

zizou771 a écrit :

FileInputStream c'est pour du local...


oui, ben ca marche aussi avec n'importe quel Inpustream que tu auras récupéré de n'importe quelle façon ...

Reply

Marsh Posté le 03-10-2006 à 11:53:14    

mais c'est dès que je veux recuperer l'Inpustream que ca plante:
InputStream in = file.getContent().getInputStream();

Reply

Marsh Posté le 03-10-2006 à 11:54:04    

ben faut pas que tu fasses getContent ...

Reply

Marsh Posté le 03-10-2006 à 12:00:07    

j'ai pas trop le choix si je veux récupérer le contenu non?

Reply

Marsh Posté le 04-10-2006 à 10:28:55    

je suis en train de tester avec RandomAccessContent (equivalent a RandomAccessFile) et j'ai OutofMemoryError des que je veut lire dans le fichier.
 

Code :
  1. RandomAccessContent racIn = file.getContent().getRandomAccessContent(RandomAccessMode.READ);
  2.         RandomAccessContent racOut = flow.getContent().getRandomAccessContent(RandomAccessMode.READ);
  3.         int tailleBuffer=5;
  4.         byte [] tab=new byte[tailleBuffer];
  5.         logger.info(racIn.length());//affiche 1418633216
  6.         logger.info("!!"+racIn.getFilePointer());//affiche 0
  7.             racIn.readByte();


 
j'ai essayé de lire par tout les moyen j'ai toujours la meme erreur.
que ce soit avec:

Code :
  1. byte [] tab=new byte[5];
  2. racIn.readFully(tab,0,4);


ou encore

Code :
  1. byte [] tab=new byte[5];
  2. racIn.readFully(tab);


 
rien y fait je ne comprend pas!! :cry:  

Reply

Marsh Posté le 04-10-2006 à 10:42:59    

t'as été voir les sources de common-VFS ? histoire de voir comment il fait pour les fichiers distants ? parce que si ca se trouve il tente de faire un gros cache local ... [:dawa]

Reply

Marsh Posté le 04-10-2006 à 17:42:09    

Citation :

file est un FileObject de l'API commons-VFS


 
Montre nous le code de construction de la variable file

Reply

Marsh Posté le 04-10-2006 à 17:50:54    

en fait dans les sources il font un:
final InputStream instr = file.getContent().getInputStream();
 
pour récuperer le contenu du fichier source.
Et ca plante si le fichier est enorme!!

Reply

Marsh Posté le 04-10-2006 à 18:15:02    

ton FileObject c'est quoi comme classe concrete ? (FileObject n'est qu'une interface)

Reply

Marsh Posté le 04-10-2006 à 18:16:16    

sftpfileobject

Reply

Marsh Posté le 04-10-2006 à 18:17:17    

ben regarde le code source de SftpFileObject et vois comment ce getContent est fait [:dawa]
comme ca tu verras ce qui merde dedans ! ou pas remarque [:joce]


Message édité par souk le 04-10-2006 à 18:17:53
Reply

Marsh Posté le 05-10-2006 à 01:54:04    

ben vu que ca fait un OutOfMemory c'est sûr qu'ils récupèrent le flux entier en mémoire => c'est une API de merde ...

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed