每日一讲
当你不再执着于过去的努力与懒惰,而专心于眼前的人和事,你才能真正的进步!!!
言归正传,今天我们要讲的是件过分的事情,如果你想要隐藏前女友的照片,不被你现在的女朋友发现的话,我们可以通过IO流技术来实现这个功能!IO流的一些介绍和应用在前一篇文章中也有写道,需要观看哟。
Java:I/O流之输入流和输出流、字节流和字符流详解,附带代码
1.文件隐藏的实质
相信小伙伴看到前面我说的能偷偷藏着前女友的照片一定很兴奋,但是实际上我们是通过将多张图片合成,并且改变扩展名的形式来实现文件的隐藏的。
看起来好像很简单的样子,但实际上不懂这些技术的小伙伴呢,肯定是看不出来,也根本想不到一个不起眼的txt文件中会藏着一堆前女友的照片。
2.图片的合成
图片的合成和前文我讲到的音乐串烧应用大同小异,本质是字节。
2.1代码实现过程
图片的合成运用到字节流,必然是要先读后写。
首先存放想要合成图片的地址,这里使用字符串数组。
String filesPath[]={
"D:/java/Test/1.jpg",
"D:/java/Test/2.jpg",
"D:/java/Test/3.jpg"
};
创建一个类对象用于存放要输出合并的文件名和文件类型。
FileOutputStream fileOutputStream=new FileOutputStream("D:/java/Test/connect.jpg");
在循环内读取所有文件,并进行写文件。
int ch=0;
byte buff[]=new byte[1024];
for (int i = 0; i < filesPath.length; i++) {
//循环一次则读一次文件
FileInputStream fileInputStream=new FileInputStream(filesPath[i]);
//满足流的末尾前进行写文件
while((ch=fileInputStream.read(buff))!=-1)
{
fileOutputStream.write(buff,0,ch);
}
fileInputStream.close();
}
fileOutputStream.close();
最终要记得关闭资源,也就是fileInputStream.close();和fileOutputStream.close();这两句代码,关闭的地方也需要注意,每使用完一次都得关闭。
2.2结果实现
可以看到,我将三张“前女友”的照片完美的合成一张jpg文件了,不过,当我们打开的时候还是只能看到第一张图片,在下文我会进行图片的拆分。
不过这样显然是不够的,女朋友还是一眼就能看出来,所以我们在代码中修改了文件的扩展名,修改为txt文件类型。
FileOutputStream fileOutputStream=new FileOutputStream("D:/java/Test/connect.jpg");
而且我们打开此文件是无法显示内容的。
那么此时,别说是现女友了,鬼都不知道里面是啥。
2.3完整代码
/*
需求分析:将多张图片合成一个文件,实现文件的隐藏(一眼看不出来这是一个图片)
*/
public static void main(String[] args) throws IOException {
String filesPath[]={
"D:/java/Test/1.jpg",
"D:/java/Test/2.jpg",
"D:/java/Test/3.jpg"
};
//建立一个类关于输出合成的文件名
FileOutputStream fileOutputStream=new FileOutputStream("D:/java/Test/connect.txt");
int ch=0;
byte buff[]=new byte[1024];
for (int i = 0; i < filesPath.length; i++) {
//循环一次则读一次文件
FileInputStream fileInputStream=new FileInputStream(filesPath[i]);
//满足流的末尾前进行写文件
while((ch=fileInputStream.read(buff))!=-1)
{
fileOutputStream.write(buff,0,ch);
}
fileInputStream.close();
}
fileOutputStream.close();
}
3.图片的拆分
既然能够合成,也就必然能够拆分。假如某天你想前女友了,打开txt文件,发现自己也看不懂这是啥勒,那也只能望txt而兴,躲在现女友的被子里偷偷哭了。
3.1图片拆分准备
前面我们把图片合成了一个文件,为了不让现女友发现,我们必然要删除原文件,但是删除之前一定是要把每个图片文件的内存大小记录下来,实际上这个也是比较繁琐的 ,但是又是不可避免的。
这里的图片文件内存大小为2814062字节,那么我们需要把三张前女友图片的内存大小都记录下来,放到一个只有自己知道的地方。
3.2代码详解
关于图片的合成分解我们都要始终牢记这是字节流,所以我们就使用IO流,先读后写。
读取文件(已合成文件)
FileInputStream fileInputStream=new FileInputStream("D:/java/Test/connect.txt");
byte buff[]=new byte[2814062];
fileInputStream.read(buff);
再写文件(获取第一张图片)
//再写文件
FileOutputStream fileOutputStream=new FileOutputStream("D:/java/Test/first.jpg");
fileOutputStream.write(buff);
最后关闭资源
//关闭资源
fileOutputStream.close();
fileInputStream.close();
完整代码
public static void main(String[] args) throws IOException {
//先读文件
FileInputStream fileInputStream=new FileInputStream("D:/java/Test/connect.txt");
byte buff[]=new byte[2814062];
fileInputStream.read(buff);
//再写文件
FileOutputStream fileOutputStream=new FileOutputStream("D:/java/Test/first.jpg");
fileOutputStream.write(buff);
//关闭资源
fileOutputStream.close();
fileInputStream.close();
}
那么简简单单的7行代码就能够得到第一张图片文件
看到这个结果,相信就会有小小伙伴问了,怎么只有一张前女友的照片了,肯定不满意,那么我们就来获取第二张图片。
我们则跳过第一张图片的字节内存,也就是在
fileInputStream.skip(2814062);
byte buff[]=new byte[2275868];
此时就能得到第二张图片
完整代码
public static void main(String[] args) throws IOException {
//先读文件
FileInputStream fileInputStream=new FileInputStream("D:/java/Test/connect.txt");
//跳过28144062字节(也就是第一张图片的内存大小)
fileInputStream.skip(2814062);
byte buff[]=new byte[2275868];
fileInputStream.read(buff);
//再写文件
FileOutputStream fileOutputStream=new FileOutputStream("D:/java/Test/second.jpg");
fileOutputStream.write(buff);
//关闭资源
fileOutputStream.close();
fileInputStream.close();
}
3.3代码完善
但是这样又会有小伙伴说了,难不成我这么多张图片我每次都要重新写代码嘛,那不看也罢。别担心,小弟给你完善了代码,我们只需要记住每张图片的字节大小,按顺序输入就好勒。
public static void main(String[] args) throws IOException {
String inputFile = "D:/java/Test/connect.txt"; // 输入的文件路径
String outputDir = "D:/java/Test/"; // 输出目录,保存拆分后的图片
FileInputStream fileInputStream = null;
Scanner input = new Scanner(System.in);
int i = 1;
try {
fileInputStream = new FileInputStream(inputFile);
while (true) {
System.out.print("请输入第" + i + "张照片字节大小 (输入0退出): ");
int inputByte = input.nextInt();
if (inputByte == 0) {
System.out.println("退出图片拆分程序");
break;
}
byte[] buff = new byte[inputByte];
// 从文件中读取指定字节数到缓冲区
int bytesRead = fileInputStream.read(buff);
if (bytesRead != inputByte) {
throw new IOException("读取的字节数与预期不符");
}
// 创建输出文件流,将缓冲区数据写入到新的图片文件中
String outputFile = outputDir + i + ".jpg";
FileOutputStream fileOutputStream = new FileOutputStream(outputFile);
fileOutputStream.write(buff);
fileOutputStream.close();
System.out.println("成功拆分并保存第" + i + "张图片到:" + outputFile);
i++;
}
} finally {
// 关闭输入流和Scanner
if (fileInputStream != null) {
fileInputStream.close();
}
input.close();
}
}
结果显示
我们可以看到,原本的三张图片就被完整的恢复出来咯!
尽管如此,还是有许多地方值得改善的,每次都这样一个个输入字节大小也是非常繁琐的。
好咯,玩笑归玩笑,大家还是要保持专一,对女朋友是,对学习也是,认真对待,变强指日可待!!!