java - 我需要在此代码中手动关闭 FileInputStream 吗?

标签 java keystore fileinputstream

我的一个应用程序遇到问题,在处理涉及打开文件和读取内容的大量事务时遇到以下异常:

java.io.FileNotFoundException: /keystore-sample/keystore.jks (Too many open files)

我有以下用java编写的示例代码:

try {  
    EncryptDecryptPassword crypt = new EncryptDecryptPassword();
    String secretKey = "secret123";
    String trustpassencrypted = "ecnrypted1234";
    String trustpass = crypt.decryptPassword(trustpassencrypted.trim(), secretKey.trim());

    File truststore = new File("/keystore-sample/keystore.jks");      
    KeyStore keyStore = KeyStore.getInstance("JKS");    
    keyStore.load(new FileInputStream(truststore), trustpass.toCharArray());
    //Continue with the rest of the code...

} catch (KeyStoreException kse) {            
    System.out.println("Security configuration failed with the following: " + kse.getCause());        
} catch (NoSuchAlgorithmException nsa) {            
    System.out.println("Security configuration failed with the following: " + nsa.getCause());        
} catch (FileNotFoundException fnfe) {            
    System.out.println("Security configuration failed with the following: " + fnfe.getCause());        
} catch (UnrecoverableKeyException uke) {            
    System.out.println("Security configuration failed with the following: " + uke.getCause());        
} catch (CertificateException ce) {            
    System.out.println("Security configuration failed with the following: " + ce.getCause());        
}catch (IOException ioe) {            
    System.out.println("Security configuration failed with the following: " + ioe.getCause());        
}

如您所见,我没有为 FileInput 流声明一个新实例,如下所示:
更正:我的意图是表达我没有将新创建的 FileInputStream 分配给变量并稍后手动关闭它,如下所示:

FileInputStream in = new FileInputStream(truststore);
keyStore.load(in, trustpass.toCharArray());
//once done with the input stream, close it
in.close();

我的问题是: new FileInputStream(truststore) 实际上需要手动关闭还是将由底层 Keystore 类处理?快速浏览一下 Keystore.class 的底层反编译代码,我没有看到这一点。只是为了确认这是否是我遇到异常的特殊原因。

此外,上面的代码实现是否被认为是不好的做法?

编辑:

由于我运行的应用程序环境受到一些限制,这里使用旧的 Java SE 6u34。

最佳答案

I did not declare a new instance for FileInput stream

这种说法毫无意义。不存在“声明一个新实例”这样的事情。您已经创建了一个新实例,只是还没有声明一个引用变量来存储它。这并不能减轻您的负担新实例,或关闭它的责任。

My question is : will new FileInputStream(truststore) actually requires manual closing

是的。

or it will be handled by the underlying Keystore class?

没有。

Quick glance on the underlying decompiled code of Keystore.class, i don't see that. Just to confirm if this is the particular reason why i am hitting the exception.

“打开的文件太多”:您正在泄漏文件描述符,无论是在此处还是在其他地方。

Also, is the code implementation above considered as bad practice?

是的,因为您根本没有关闭FileInputStream。请注意,在 keyStore.load() 之后的行中关闭它是不够的,因为这可能会引发异常。

这些天你会使用 try-with-resources:

File truststore = new File("/keystore-sample/keystore.jks");      
try (FileInputStream fis = new FileInputStream(truststore))
{
    KeyStore keyStore = KeyStore.getInstance("JKS");    
    keyStore.load(fis, ...);
}

即使出现异常,它也会自动为您关闭。

关于java - 我需要在此代码中手动关闭 FileInputStream 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42357988/

相关文章:

java - 如何将 AES 加密中使用的 key 共享给其他应用程序进行解密?

java - 使用 FileInputStream 和 FileOutputStream 作为缓冲区

java - java I/O字节流类的查询

java - 无法合并两个 mp3 文件

java - 从 Java 访问 Scala 独立单例对象

java - 如何将多个段落包装在一个元素中?

http - CFHTTP 不通过 SSL 连接进行连接?

java - 在没有 BouncyCaSTLe 的情况下以编程方式为 SSL Client-Auth 创建客户端证书的任何方法?

java - 参数 'imagePath'此处未初始化

java - PostgreSQL 中的 Query 错误没有返回结果