我试图读取我的加密文件并将其解密的内容放入列表中,但是一些朝向末尾的行随机分割或者分成一半到新行。有什么想法,为什么它这样做? (在解密方法中)。顺便说一下缓冲区是1024,如果有帮助的话。
public Crypto() {
try {
PBEKeySpec keySpec = new PBEKeySpec(password.toCharArray());
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBEWithMD5AndDES");
SecretKey key = keyFactory.generateSecret(keySpec);
ecipher = Cipher.getInstance("PBEWithMD5AndDES");
dcipher = Cipher.getInstance("PBEWithMD5AndDES");
byte[] salt = new byte[8];
PBEParameterSpec paramSpec = new PBEParameterSpec(salt, 100);
ecipher.init(Cipher.ENCRYPT_MODE, key, paramSpec);
dcipher.init(Cipher.DECRYPT_MODE, key, paramSpec);
} catch (Exception e) {
}
}
@SuppressWarnings("resource")
public static List<String> decrypt(String file) {
List<String> list = new LinkedList<String>();
try {
InputStream in = new CipherInputStream(new FileInputStream(file), dcipher);
int numRead = 0;
while ((numRead = in.read(buffer)) >= 0) {
list.add(new String(buffer, 0, numRead);
}
} catch (IOException e) {
e.printStackTrace();
}
return list;
}
答案 0 :(得分:1)
read
上的Stream
方法只是将一些Byte
读入缓冲区。因此,您的代码以1024大小的块读取文件,并将每个块读取保存到List
。
有几种方法可以逐行阅读Stream
,我建议BufferedReader
final List<String> list = new LinkedList<String>();
try {
final BufferedReader reader = new BufferedReader(new InputStreamReader(new CipherInputStream(new FileInputStream(file), dcipher)));
String line;
while ((line = reader.readLine()) != null) {
list.add(line);
}
} catch (IOException e) {
e.printStackTrace();
}
有一点需要注意的是,InputStreamReader
执行了从Byte
到String
的隐式转换,这需要进行编码。默认情况下,将使用平台编码,这意味着您的代码依赖于平台。您的原始代码也是如此,因为new String(byte[])
也使用默认的平台编码。
我建议始终明确指定编码:
final BufferedReader reader = new BufferedReader(new InputStreamReader(new CipherInputStream(new FileInputStream(file), dcipher), "UTF-8"));
或String
构造函数
new String(bytes, "UTF-8")
将String
写入File
的任何代码都是如此:
try {
try (final BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new CipherOutputStream(new FileOutputStream(file), dcipher), "UTF-8"))) {
writer.append(data);
}
} catch (IOException ex) {
e.printStackTrace();
}
这样,您可以避免在其他操作系统上运行应用程序时出现令人讨厌的意外,因为每个系列使用不同的默认编码(Linux上为UTF-8
,Windows上为ISO-8859-1
,Mac上为MacRoman
另一个注意事项是,您没有关闭Stream
(或现在Reader
) - 这是必要的,可以在java 6中的finally
中使用,也可以使用新{ {1}} java 7的构造。
try-with-resources