2

每当我尝试执行我的代码时,我都会遇到 java.lang.OutOfMemoryError: Java heap space。但是,如果我在某些情况下关闭流,错误就会消失,但是由于我的流过早关闭,我会丢失数据。

我对 Java 很陌生,我显然不了解如何管理流。我应该如何以及何时关闭流?

private void handleFile(File source)
{
    FileInputStream fis = null;

    try
    {
        if(source.isFile())
        {
            fis = new FileInputStream(source);
            handleFile(source.getAbsolutePath(), fis);
        }
        else if(source.isDirectory())
        {
            for(File file:source.listFiles())
            {
               if(file.isFile())
               {
                   fis = new FileInputStream(file);
                   handleFile(file, fis);
               }
               else
               {
                   handleFile(file);
               }
            }
         }
     }
     catch(IOException ioe)
     {
         ioe.printStackTrace();
     }
     finally
     {
         try
         {
             if(fis != null) { fis.close(); }
         }
         catch(IOException ioe) { ioe.printStackTrace(); }
     }
}

private handleFile(String fileName, InputStream inputStream)
{
    try
    {
       byte[] initialBytes = isToByteArray(inputStream);
       byte[] finalBytes = initialBytes;

       if(initialBytes.length == 0) return;

       if(isBytesTypeB(initialBytes))
       {
          finalBytes = getBytesTypeB(startingBytes);
       }
       // Other similar method checks
       // .....

       map.put(fileName, finalBytes);
     }
     catch(IOException ioe)
     {
         ioe.printStackTrace();
     }
}

private byte[] isToByteArray(InputStream inputStream)
{
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    byte[] buffer = new byte[1024];

    int nRead;
    while((nRead = inputStream.read(buffer)) != -1)
    {
        baos.write(buffer, 0, nRead);
    }
    return baos.toByteArray();
 }

 private boolean isBytesTypeB(byte[] fileBytes)
 {
     // Checks if these bytes match a particular type
     if(BytesMatcher.matches(fileBytes, fileBytes.length))
     {
         return true;
     }
     return false;
 }

 private byte[] getBytesTypeB(byte[] fileBytes)
 {
     //decompress bytes

     return decompressedBytes;
 }
4

1 回答 1

2

首先,不要读取内存中的整个流。读写时使用缓冲区。

ByteArrayInputStream并且ByteArrayInputStream仅当您确定要读取非常小的流(您需要将其数据重新用于某些操作)并且将数据保存在内存中确实有意义时才使用。否则,您将很快(或意外)耗尽内存。

在 try-catch 块之外定义流并在 finally 块中关闭它们(如果它们不为空)。例如:

void doSomeIOStuff() throws IOException
{
    InputStream is = null;

    try
    {
        is = new MyInputStream(...);
        // Do stuff
    }
    catch (IOException ioExc)
    {
        // Either just inform (poor decision, but good for illustration):
        ioExc.printStackTrace();
        // Or re-throw to delegate further on:
        throw new IOException(ioExc);
    }
    finally
    {
        if (is != null)
        {
            is.close();
        }
    }
}

这样,您的资源在使用后始终会正确关闭。

出于好奇,该handleFile(...)方法真正应该做什么?

于 2013-02-27T16:07:14.350 回答