Java:实现文件的隐藏(图片合成与拆分)--IO流的应用(包你感兴趣)

每日一讲

当你不再执着于过去的努力与懒惰,而专心于眼前的人和事,你才能真正的进步!!!

言归正传,今天我们要讲的是件过分的事情,如果你想要隐藏前女友的照片,不被你现在的女朋友发现的话,我们可以通过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();
        }
    }

结果显示 

我们可以看到,原本的三张图片就被完整的恢复出来咯!

尽管如此,还是有许多地方值得改善的,每次都这样一个个输入字节大小也是非常繁琐的。

好咯,玩笑归玩笑,大家还是要保持专一,对女朋友是,对学习也是,认真对待,变强指日可待!!!

  • 21
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值