FileInputStream (Read) - Não existem recursos de sistema suficientes
7 respostas
G
gabriel.amoedo
Estou com um problema chato com o FileInputStream.
Tenho um algoritmo de criptografia onde antes da operação, eu preciso colocar o arquivo no FileInputStream e no final dela utilizo o FileOutputStream.
Se o arquivo possuir menos de uns 80MB, a operação flui normalmente quando eu coloco o FileInputStream.read().
Agora passou disso, esse read dá problema. Diz que não existem recursos suficientes e fecha tudo.... sendo que eu faço essa mesma operação utilizando STRING ou File como parâmetro (seria um New FileInputStream())....
A parte relevante do código é essa daqui e o erro é exatamente no read. Alguém faz idéia do que pode ser?
publicBooleancriptografa(Stringorigem){
try{
Filefile=newFile(origem);if(file.isFile()){
//LêoarquivoasercriptografadoFileInputStreamfis=newFileInputStream(file);byte[]texto=newbyte[fis.available()];fis.read(texto); //Aqui está dando PROBLEMA
Error: Não existem recursos de sistema suficientes para concluir o serviço solicitado
java.lang.OutOfMemoryError: Java heap space
at com.sun.crypto.provider.SunJCE_f.b(DashoA13*..)
at com.sun.crypto.provider.SunJCE_ab.b(DashoA13*..)
at com.sun.crypto.provider.PBEWithMD5AndDESCipher.engineDoFinal(DashoA13*..)
at javax.crypto.Cipher.doFinal(DashoA13*..)
at br.gov.inpi.prgguardtec.security.FileCrypt.criptografa(FileCrypt.java:78)
at br.gov.inpi.prgguardtec.web.RegistroBean.armazenarMidia(RegistroBean.java:214)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.apache.el.parser.AstValue.invoke(AstValue.java:262)
at org.apache.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:278)
at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:105)
at org.primefaces.component.fileupload.FileUpload.broadcast(FileUpload.java:279)
at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:752)
at javax.faces.component.UIViewRoot.processDecodes(UIViewRoot.java:928)
at com.sun.faces.lifecycle.ApplyRequestValuesPhase.execute(ApplyRequestValuesPhase.java:78)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:508)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.primefaces.webapp.filter.FileUploadFilter.doFilter(FileUploadFilter.java:77)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at br.gov.inpi.prgguardtec.web.filter.LoginFilter.doFilter(LoginFilter.java:30)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:224)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:169)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
E
entanglement
Gabriel, evite carregar o arquivo inteiro na memória para criptografá-lo. Não sei que algoritmo você usa, mas normalmente nunca é necessário carregar mais que 1 KB de dados de cada vez para criptografar alguma coisa.
vai dar sempre problemas se seu arquivo for só um pouquinho grande (80 MB é muita coisa para você carregar).
E
entanglement
Hum, você está usando PBEWithMD5AndDESCipher. Realmente você não precisa carregar tudo.
J
juno.rr
Tinha respondido a mesma coisa do colega acima (demorei pra responder)…
E
entanglement
Uma forma bem boboca de criptografar alguma coisa é encapsular o seu FileInputStream em um CipherInputStream, passando seu Cipher como parâmetro.
Isso fará que cada “read” retorne os dados já criptografados do arquivo.
Outra forma é encapsular seu FileOutputStream em um CipherOutputStream .
Cada “write” irá gravar os dados criptografados no disco.
Exemplo perfeito.
Funcionou redondinho!!!
Ajustei o meu código, usei um byte[] de 4kb mesmo… A memória ficou bem tranquila…
Vou testar com um byte[] maior pra ver se fica mais rápido sem consumir muita memória.
Obrigado brother!!!