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) {
		}

	}

}

相关文章
|
2月前
|
Java
在 Java 中捕获和处理自定义异常的代码示例
本文提供了一个 Java 代码示例,展示了如何捕获和处理自定义异常。通过创建自定义异常类并使用 try-catch 语句,可以更灵活地处理程序中的错误情况。
77 1
|
3月前
|
存储 Java
Java中的HashMap和TreeMap,通过具体示例展示了它们在处理复杂数据结构问题时的应用。
【10月更文挑战第19天】本文详细介绍了Java中的HashMap和TreeMap,通过具体示例展示了它们在处理复杂数据结构问题时的应用。HashMap以其高效的插入、查找和删除操作著称,而TreeMap则擅长于保持元素的自然排序或自定义排序,两者各具优势,适用于不同的开发场景。
56 1
|
3月前
|
存储 Java
【编程基础知识】 分析学生成绩:用Java二维数组存储与输出
本文介绍如何使用Java二维数组存储和处理多个学生的各科成绩,包括成绩的输入、存储及格式化输出,适合初学者实践Java基础知识。
97 1
|
12天前
|
缓存 算法 搜索推荐
Java中的算法优化与复杂度分析
在Java开发中,理解和优化算法的时间复杂度和空间复杂度是提升程序性能的关键。通过合理选择数据结构、避免重复计算、应用分治法等策略,可以显著提高算法效率。在实际开发中,应该根据具体需求和场景,选择合适的优化方法,从而编写出高效、可靠的代码。
25 6
|
2月前
|
Java
在Java中实现接口的具体代码示例
可以根据具体的需求,创建更多的类来实现这个接口,以满足不同形状的计算需求。希望这个示例对你理解在 Java 中如何实现接口有所帮助。
92 38
|
2月前
|
监控 算法 Java
jvm-48-java 变更导致压测应用性能下降,如何分析定位原因?
【11月更文挑战第17天】当JVM相关变更导致压测应用性能下降时,可通过检查变更内容(如JVM参数、Java版本、代码变更)、收集性能监控数据(使用JVM监控工具、应用性能监控工具、系统资源监控)、分析垃圾回收情况(GC日志分析、内存泄漏检查)、分析线程和锁(线程状态分析、锁竞争分析)及分析代码执行路径(使用代码性能分析工具、代码审查)等步骤来定位和解决问题。
|
2月前
|
Java
java 中 IO 流
Java中的IO流是用于处理输入输出操作的机制,主要包括字节流和字符流两大类。字节流以8位字节为单位处理数据,如FileInputStream和FileOutputStream;字符流以16位Unicode字符为单位,如FileReader和FileWriter。这些流提供了读写文件、网络传输等基本功能。
56 9
|
3月前
|
存储 缓存 Java
java基础:IO流 理论与代码示例(详解、idea设置统一utf-8编码问题)
这篇文章详细介绍了Java中的IO流,包括字符与字节的概念、编码格式、File类的使用、IO流的分类和原理,以及通过代码示例展示了各种流的应用,如节点流、处理流、缓存流、转换流、对象流和随机访问文件流。同时,还探讨了IDEA中设置项目编码格式的方法,以及如何处理序列化和反序列化问题。
95 1
java基础:IO流 理论与代码示例(详解、idea设置统一utf-8编码问题)
|
2月前
|
存储 Java 关系型数据库
在Java开发中,数据库连接是应用与数据交互的关键环节。本文通过案例分析,深入探讨Java连接池的原理与最佳实践
在Java开发中,数据库连接是应用与数据交互的关键环节。本文通过案例分析,深入探讨Java连接池的原理与最佳实践,包括连接创建、分配、复用和释放等操作,并通过电商应用实例展示了如何选择合适的连接池库(如HikariCP)和配置参数,实现高效、稳定的数据库连接管理。
72 2
|
2月前
|
Java 关系型数据库 数据库
面向对象设计原则在Java中的实现与案例分析
【10月更文挑战第25天】本文通过Java语言的具体实现和案例分析,详细介绍了面向对象设计的五大核心原则:单一职责原则、开闭原则、里氏替换原则、接口隔离原则和依赖倒置原则。这些原则帮助开发者构建更加灵活、可维护和可扩展的系统,不仅适用于Java,也适用于其他面向对象编程语言。
45 2