我正在编写一个加密和解密文件的小工具。加密文件将添加到zip-archive中。到目前为止,以下代码正在运行。我可以加密任何文件,但文本文件。如果我选择一个文本文件,那么它就是不完整的。如果有以下文字: "一两三测试检查测试"它变得像#34;一两三个测试che"。
没有异常抛出只缺少几个字节。任何其他文件(pdf,mp3,mp4,exe等)都是完整的。
package encryptme.crypto;
import encryptme.fileoperations.FileIn;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.KeyPair;
import java.security.NoSuchAlgorithmException;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import javax.crypto.Cipher;
import javax.crypto.CipherOutputStream;
import javax.crypto.NoSuchPaddingException;
public class Encrypt {
private String algorithm;
private int keylength;
private Key key;
private KeyPair keypair;
private File[] source;
private String destination;
public Encrypt(String a, int kl, Key k, File[] s, String dest) {
this.algorithm = a;
this.keylength = kl;
this.key = k;
this.source = s;
this.destination = dest;
this.output = o;
}
public void encOut() {
CipherOutputStream cout = null;
ZipOutputStream zout = null;
OutputStream out = null;
Cipher cipher;
try {
out = new FileOutputStream(this.destination);
System.out.println(this.destination);
zout = new ZipOutputStream(out);
cipher = Cipher.getInstance(this.algorithm);
cipher.init(Cipher.ENCRYPT_MODE, this.key);
for (int i = 0; i < this.source.length; i++) {
FileInputStream in = new FileInputStream(this.source[i].getAbsolutePath());
ZipEntry ze = new ZipEntry(this.source[i].getName());
zout.putNextEntry(ze);
cout = new CipherOutputStream(zout, cipher);
byte[] buffer = new byte[1024];
long bytesRead = 0;
for (bytesRead = 0; (bytesRead = in.read(buffer)) != -1;) {
cout.write(buffer, 0, (int) bytesRead);
}
zout.closeEntry();
in.close();
}
} catch (NoSuchAlgorithmException ex) {
Logger.getLogger(Encrypt.class.getName()).log(Level.SEVERE, null, ex);
} catch (NoSuchPaddingException ex) {
Logger.getLogger(Encrypt.class.getName()).log(Level.SEVERE, null, ex);
} catch (InvalidKeyException ex) {
Logger.getLogger(Encrypt.class.getName()).log(Level.SEVERE, null, ex);
} catch (FileNotFoundException ex) {
Logger.getLogger(Encrypt.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(Encrypt.class.getName()).log(Level.SEVERE, null, ex);
} finally {
try {
if (cout != null) {
cout.close();
}
if (zout != null) {
zout.close();
}
if (out != null) {
out.close();
}
} catch (IOException ex) {
Logger.getLogger(Encrypt.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
使用jFileChooser选择要加密的文件,并将其添加到一个数组中,该数组作为参数传入上面的类。我想过将PrintWriter用于那些通过结尾识别它们的文本文件,例如&#39; TextFile.txt的&#39;或者&#39; textfile.odt&#39;。但是,如果文件没有像#text;&#39;
那样的结尾,我该怎么办?我对Java和编码一般都很陌生,所以我希望有一个错误导致问题。
答案 0 :(得分:0)
您需要在致电cout
之前关闭zout.closeEntry
,以便清除密码已缓冲的任何剩余数据。不幸的是,cout.close()
会调用zout.close()
,这是我们绝对不想要的,因为这会阻止您编写任何其他条目。
我会使用CloseShieldOutputStream from commons-io:
cout = new CipherOutputStream(new CloseShieldOutputStream(zout), cipher);
此类旨在阻止close()
调用传播到基础包装流(在本例中为zout
)。
答案 1 :(得分:-1)
我不是100%肯定你的要求,但是你想要清理你收到的加密类文件吗?确实有一种方法是查看文件扩展名:
public class ImageFileFilter implements FileFilter {
private String[] imageExtentions = {"png", "jpg", "gif" };
@Override
public boolean accept(File file) {
for(String ext : imageExtentions){
if(file.isFile()){
if(file.getName().toLowerCase().endsWith(ext))
return true;
}
}
return false;
}
}
上面的示例是一个应该处理图像扩展的类,但它是通用的,因此它适用于传递给accept方法的任何扩展。关键是要实现FileFilter接口,然后您可以清理文件。
编辑: 啊,你编辑了你的问题,这使你更清楚你想要什么,这不是我给出的答案所解决的。