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

	}

}

相关文章
|
6天前
|
Java 开发工具
【Azure Storage Account】Java Code访问Storage Account File Share的上传和下载代码示例
本文介绍如何使用Java通过azure-storage-file-share SDK实现Azure文件共享的上传下载。包含依赖引入、客户端创建及完整示例代码,助你快速集成Azure File Share功能。
169 3
|
19天前
|
Java Go 开发工具
【Java】(9)抽象类、接口、内部的运用与作用分析,枚举类型的使用
抽象类必须使用abstract修饰符来修饰,抽象方法也必须使用abstract修饰符来修饰,抽象方法不能有方法体。抽象类不能被实例化,无法使用new关键字来调用抽象类的构造器创建抽象类的实例。抽象类可以包含成员变量、方法(普通方法和抽象方法都可以)、构造器、初始化块、内部类(接 口、枚举)5种成分。抽象类的构造器不能用于创建实例,主要是用于被其子类调用。抽象类中不一定包含抽象方法,但是有抽象方法的类必定是抽象类abstract static不能同时修饰一个方法。
159 1
|
19天前
|
Java Unix Go
【Java】(8)Stream流、文件File相关操作,IO的含义与运用
Java 为 I/O 提供了强大的而灵活的支持,使其更广泛地应用到文件传输和网络编程中。!但本节讲述最基本的和流与 I/O 相关的功能。我们将通过一个个例子来学习这些功能。
116 1
|
19天前
|
存储 Java Go
【Java】(3)8种基本数据类型的分析、数据类型转换规则、转义字符的列举
牢记类型转换规则在脑海中将编译和运行两个阶段分开,这是两个不同的阶段,不要弄混!
131 2
|
29天前
|
IDE Java 关系型数据库
Java 初学者学习路线(含代码示例)
本教程为Java初学者设计,涵盖基础语法、面向对象、集合、异常处理、文件操作、多线程、JDBC、Servlet及MyBatis等内容,每阶段配核心代码示例,强调动手实践,助你循序渐进掌握Java编程。
218 3
|
1月前
|
Java
怎么用Java 代码示例来展示继承的实现
本文通过Java代码示例展示继承机制:Animal为父类,Cat和Dog继承其属性与方法,并实现构造函数调用、方法重写与特有功能扩展,体现代码复用与多态特性。
77 4
|
1月前
|
Java
java入门代码示例
本文介绍Java入门基础,包含Hello World、变量类型、条件判断、循环及方法定义等核心语法示例,帮助初学者快速掌握Java编程基本结构与逻辑。
262 0
|
1月前
|
数据采集 存储 弹性计算
高并发Java爬虫的瓶颈分析与动态线程优化方案
高并发Java爬虫的瓶颈分析与动态线程优化方案
Java API 开发者
55 0
|
2月前
|
安全 Java 编译器
new出来的对象,不一定在堆上?聊聊Java虚拟机的优化技术:逃逸分析
逃逸分析是一种静态程序分析技术,用于判断对象的可见性与生命周期。它帮助即时编译器优化内存使用、降低同步开销。根据对象是否逃逸出方法或线程,分析结果分为未逃逸、方法逃逸和线程逃逸三种。基于分析结果,编译器可进行同步锁消除、标量替换和栈上分配等优化,从而提升程序性能。尽管逃逸分析计算复杂度较高,但其在热点代码中的应用为Java虚拟机带来了显著的优化效果。
81 4