Java利用IO流复制照片完整示例和详细分析

简介: import java.io.FileInputStream;import java.io.FileOutputStream;/** * 该篇博客已经Deprecated,请参见I/O流的梳理和小结 * http://blog.
import java.io.FileInputStream;
import java.io.FileOutputStream;
/**
 * 该篇博客已经Deprecated,请参见I/O流的梳理和小结 
 * http://blog.csdn.net/lfdfhl/article/details/525761242
 * 注意事项:
 * int java.io.FileInputStream.read(byte[] b) throws IOException
 * 方法的官方文档描述:
 * Reads up to b.length bytes of data from this input stream into an array of bytes. 
 * This method blocks until some input is available. 
 * 即可以这么理解:
 * FileInputStream会不断地读取字节数据到字节数组b中.
 * 只要读了一次,那么我们就相应地执行一次写的操作:
 * fileOutputStream.write(temp,0,len);
 * 什么情况下这个读的过程会终止呢?
 * 当已经读取到数据末尾的时候,有个标识符-1;表示已经到了末尾.
 * 
 * 有种不太恰当的理解:
 * FileInputStream会一次次地读取字节数据到字节数组b中.
 * 每读一次后,就会稍微暂停一下,然后执行
 * fileOutputStream.write(temp,0,len);
 * 进行数据写的操作.
 * 
 * 其实如下理解更合适一些:
 * FileInputStream是在不断地读数据(而不要想象成带有暂停性质的一次次地读取).
 * 只是它每读一次的数据必然不超过b.length的大小,但有可能是不一样的长度,
 * 比如:在极多数情况下,最后一次的时候读取的字节数会小于b.length大小.
 * 每采用read()方法读一次呢,读到的数据就会存到字节数组b中,并且该方法
 * 还返回了这次读取的字节的多少(len).
 * 于是我们对字节数组b中从o到len的数据进行写操作:
 * fileOutputStream.write(temp,0,len);
 * 
 * 现在就明白了为什么使用:
 * fileOutputStream.write(temp);
 * 是不准确的,很可能导致复制后的照片比原始照片大.
 * 因为fileOutputStream.write(temp);方法每次都是
 * 写了b字节数组大小的数据,而不是已经b中实际有多少
 * 数据.
 * 这样的操作在前几次是没有什么问题的,因为每次装的
 * 都是b字节数组大小的数据,但是最后一次往往是装不满
 * b的.所以每次应该根据b中的实际数据到底有多少来进行
 * 操作即采用fileOutputStream.write(temp,0,len);
 * 可以兼顾到每一次.
 */
public class CopyPhoto {
	public static void main(String[] args) {
		CopyPhoto copyPhoto = new CopyPhoto();
		copyPhoto.copy();
	}

	private void copy() {
		try {
			FileInputStream fileInputStream=new FileInputStream("D:\\c.jpg");
			FileOutputStream fileOutputStream=new FileOutputStream("D:\\new.jpg");
			int len=0;
			byte temp []=new byte[1024*8];;
			while((len=fileInputStream.read(temp))!=-1){
				  System.out.println("len="+len);
				  //It is right
				    fileOutputStream.write(temp,0,len);
				  //It is wrong
				  //fileOutputStream.write(temp);
			}
			fileOutputStream.close();
			fileInputStream.close();
		} catch (Exception e) {
		}

	}

}

相关文章
|
安全 Java 编译器
new出来的对象,不一定在堆上?聊聊Java虚拟机的优化技术:逃逸分析
逃逸分析是一种静态程序分析技术,用于判断对象的可见性与生命周期。它帮助即时编译器优化内存使用、降低同步开销。根据对象是否逃逸出方法或线程,分析结果分为未逃逸、方法逃逸和线程逃逸三种。基于分析结果,编译器可进行同步锁消除、标量替换和栈上分配等优化,从而提升程序性能。尽管逃逸分析计算复杂度较高,但其在热点代码中的应用为Java虚拟机带来了显著的优化效果。
390 4
|
监控 Java API
现代 Java IO 高性能实践从原理到落地的高效实现路径与实战指南
本文深入解析现代Java高性能IO实践,涵盖异步非阻塞IO、操作系统优化、大文件处理、响应式网络编程与数据库访问,结合Netty、Reactor等技术落地高并发应用,助力构建高效可扩展的IO系统。
402 0
|
11月前
|
存储 Java Go
【Java】(3)8种基本数据类型的分析、数据类型转换规则、转义字符的列举
牢记类型转换规则在脑海中将编译和运行两个阶段分开,这是两个不同的阶段,不要弄混!
417 2
|
11月前
|
Java Go 开发工具
【Java】(9)抽象类、接口、内部的运用与作用分析,枚举类型的使用
抽象类必须使用abstract修饰符来修饰,抽象方法也必须使用abstract修饰符来修饰,抽象方法不能有方法体。抽象类不能被实例化,无法使用new关键字来调用抽象类的构造器创建抽象类的实例。抽象类可以包含成员变量、方法(普通方法和抽象方法都可以)、构造器、初始化块、内部类(接 口、枚举)5种成分。抽象类的构造器不能用于创建实例,主要是用于被其子类调用。抽象类中不一定包含抽象方法,但是有抽象方法的类必定是抽象类abstract static不能同时修饰一个方法。
396 1
|
11月前
|
Java Unix Go
【Java】(8)Stream流、文件File相关操作,IO的含义与运用
Java 为 I/O 提供了强大的而灵活的支持,使其更广泛地应用到文件传输和网络编程中。!但本节讲述最基本的和流与 I/O 相关的功能。我们将通过一个个例子来学习这些功能。
396 1
|
12月前
|
数据采集 存储 弹性计算
高并发Java爬虫的瓶颈分析与动态线程优化方案
高并发Java爬虫的瓶颈分析与动态线程优化方案
|
Java 测试技术 API
Java IO流(二):文件操作与NIO入门
本文详解Java NIO与传统IO的区别与优势,涵盖Path、Files类、Channel、Buffer、Selector等核心概念,深入讲解文件操作、目录遍历、NIO实战及性能优化技巧,适合处理大文件与高并发场景,助力高效IO编程与面试准备。
|
存储 Java Linux
操作系统层面视角下 Java IO 的演进路径及核心技术变革解析
本文从操作系统层面深入解析Java IO的演进历程,涵盖BIO、NIO、多路复用器及Netty等核心技术。分析各阶段IO模型的原理、优缺点及系统调用机制,探讨Java如何通过底层优化提升并发性能与数据处理效率,全面呈现IO技术的变革路径与发展趋势。
295 3
|
SQL Java 数据库连接
Java IO流(一):字节流与字符流基础
本文全面解析Java IO流,涵盖字节流、字符流及其使用场景,帮助开发者理解IO流分类与用途,掌握文件读写、编码转换、异常处理等核心技术,通过实战案例提升IO编程能力。
|
数据采集 搜索推荐 算法
Java 大视界 -- Java 大数据在智能教育学习社区用户互动分析与社区活跃度提升中的应用(274)
本文系统阐述 Java 大数据技术在智能教育学习社区中的深度应用,涵盖数据采集架构、核心分析算法、活跃度提升策略及前沿技术探索,为教育数字化转型提供完整技术解决方案。