JavaIO流中对数据的操作尤为重要,掌握了基本的拷贝操作,才能将各种数据源的操作联系起来。

  先来看看对文件夹的拷贝吧:

 /**
* 利用递归实现文件夹的拷贝操作
* 分析:判断
* 是文件:调用拷贝文件的方法fileCopy(...)
* 是文件夹:创建文件夹,并使用递归实现子文件夹/子文件的判断及操作
* @param src:要拷贝的文件夹源头
* @param dest:要拷贝到的文件夹源头
*/
public static void dirCopy(File src,File dest) {
if(src.isFile()) { //是文件
fileCopy(src, dest);
}else { //是文件夹
dest.mkdirs();
for(File subSrc:src.listFiles()) { //遍历子文件夹/子文件
dirCopy(subSrc, new File(dest,subSrc.getName()));
}
}
}

  对文件的拷贝,我们可以这样写:

 /**
* 实现文件的拷贝
* 输入流读取的同时输出流进行写出
* @param src:要拷贝的文件源头
* @param dest:要拷贝到的文件源头
*/
public static void fileCopy(File src,File dest) {
//1.创建源
//2.选择流
InputStream is = null;
OutputStream os = null;
try {
is = new FileInputStream(src);
os = new FileOutputStream(dest);
//3.操作:分段读取并写出
int len; //接收长度
byte[] flush = new byte[1024]; //缓冲容器,一次读写1k
while((len=is.read(flush))!=-1) {
os.write(flush, 0, len);
}
os.flush(); //写完手动刷新,避免数据在缓冲容器中(当然当流关闭时会自动刷新)
}catch(FileNotFoundException e) {
e.printStackTrace();
}catch(IOException e) {
e.printStackTrace();
}finally {
//4.关闭流,分别关闭,先打开的后关闭
try {
if(os!=null) { //判断是否为空,避免空指针异常
os.close();
}
}catch(IOException e) {
e.printStackTrace();
}
try {
if(is!=null) { //判断是否为空,避免空指针异常
is.close();
}
}catch(IOException e) {
e.printStackTrace();
}
}
}

  以上代码只能实现对文件的拷贝操作,当然适合于拷贝任何格式的数据文件,包括视频、音频、图片等等。但是如果我想将一张图片拷贝到字节数组中呢(这里的字节数组相当于内存),也就是说从文件到字节数组,或着是从字节数组到文件。那么以上代码就具有局限性了,也不易于扩展,来看以下代码:

 /**
* 对接流
* @param is:输入流
* @param os:输出流
*/
public static void copy(InputStream is,OutputStream os) {
//1.创建源
//2.选择流
try {
//3.操作
byte[] flush = new byte[1024]; //缓冲容器
int len; //接收长度
while((len=is.read(flush))!=-1) {
os.write(flush, 0, len);
}
os.flush();
}catch(FileNotFoundException e) {
e.printStackTrace();
}catch(IOException e) {
e.printStackTrace();
}finally {
try {
if(os!=null) {
os.close();
}
}catch(IOException e) {
e.printStackTrace();
}
try {
if(is!=null) {
is.close();
}
}catch(IOException e) {
e.printStackTrace();
}
}
}

  嗯,这样就可以实现以上要求了,但是我们发现:关闭资源的操作一直在,而且都一样,我们可以封装一下,这样在finally中就可以直接调用了。

 /**
* 关闭的方法
* @param is:输入流
* @param os:输出流
*/
public static void close(InputStream is,OutputStream os) {
try {
if(os!=null) {
os.close();
}
}catch(IOException e) {
e.printStackTrace();
}
try {
if(is!=null) {
is.close();
}
}catch(IOException e) {
e.printStackTrace();
}
}

  好了,看看封装的代码,幸亏只有两个流,要是流很多咋办,形参太多,但是我们发现输入流InputStream和输出流OutputStream都实现了同一个接口:Closeable。嗯,这样,我们可以试试JDK1.5的新特性:可变参数。

 /**
* 封装的关闭方法
* @param ios:要关闭的流
*/
public static void close(Closeable... ios) {
for(Closeable io:ios) {
try {
if(io!=null) {
io.close();
}
}catch(IOException e) {
e.printStackTrace();
}
}
}

  现在看似完美了,但我还不太满意,有时候,我觉得手动关闭资源太麻烦了。别急,来看看JDK1.7的新特性:try...with...resources(自动关闭资源)。

 /**
* JDK1.7之后的新特性 try...with...resources:自动关闭资源
* 文件的拷贝
* @param srcPath:要拷贝的源头
* @param destPath:要拷贝到的目的地
*/
public static void copy1(String srcPath,String destPath) {
//1.创建源
File src = new File(srcPath);
File dest = new File(destPath);
//2.选择流
try(InputStream is = new FileInputStream(src);
OutputStream os = new FileOutputStream(dest)) {
//3.操作
byte[] flush = new byte[1024]; //缓冲容器
int len; //接收长度
while((len=is.read(flush))!=-1) {
os.write(flush, 0, len);
}
os.flush();
}catch(FileNotFoundException e) {
e.printStackTrace();
}catch(IOException e) {
e.printStackTrace();
}
}

  大家发现:try里面写的好繁琐,别急,看看JDK1.9的改进版(不过要求你所要关闭的资源是final或等效于final的变量)。

 /**
* JDK1.9之后对 try...with...resources的改进
* 对接流
* @param is:输入流
* @param os:输出流
*/
public static void copy2(InputStream is,OutputStream os) {
//1.创建源
//2.选择流
try(is;os) {
//3.操作
byte[] flush = new byte[1024]; //缓冲容器
int len; //接收长度
while((len=is.read(flush))!=-1) {
os.write(flush, 0, len);
}
os.flush();
}catch(FileNotFoundException e) {
e.printStackTrace();
}catch(IOException e) {
e.printStackTrace();
}
}

  哈哈,看上去是不是简洁很多。对的,随着JDK的新版本发布,越来越多的新技术,也使得代码看起来越简洁,不过对我们的要求也只会越来越高。前段时间JDK12已经出来了,还没用,不过我相信肯定会有好多的新特性,期待,也看好Java,加油。

JavaIO流中的拷贝的更多相关文章

  1. 总结JAVA----IO流中的字节流

    对于IO流中字节流的总结 字节流的概念 由于应用程序,经常需要和文件打交道,所以Inputstream专门提供了读写文件的子类:FileInputStream和FileOutputStream类,如果 ...

  2. 总结JAVA----IO流中的File类

    对于IO流中File类的总结 File类的基本概念 File类只能用于完成对于文件属性(是否存在.可读性.长度)的一些操作,不能用于文件的访问. File类的对象 File类的对象存储的是文件的绝对路 ...

  3. javaIO流实现文件拷贝

    package com.java.demo; import java.io.*; public class CopyDemo { public static void main(String[] ar ...

  4. JAVA-IO流大文件拷贝

    package com.test.io; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import ...

  5. java-IO流-字符流-FileReader、FileWriter、自定义小数组的拷贝、BufferedReader、BufferedWriter、readLine()和newLine()方法、LineNumberReader、使用指定的码表读写字符

    ###21.01_IO流(字符流FileReader) * 1.字符流是什么     * 字符流是可以直接读写字符的IO流     * 字符流读取字符, 就要先读取到字节数据, 然后转为字符. 如果要 ...

  6. JavaIO流(输入输出操作)

    Java中执行输出和输入操作,需要通过IO流.例如最常见的System.out.println()就是一个输出流.IO流的类比较多,但核心体系就是由File. InputStream .OutputS ...

  7. Java学习日记之 Java-IO流

    Java中的IO流在处理上分为字节流和字符流.字节流和字符流的区别 : 1.字节流读取的时候,读到一个字节就返回一个字节:  字符流使用了字节流读到一个或多个字节(中文对应的字节数是两个,在UTF-8 ...

  8. .net学习之集合、foreach原理、Hashtable、Path类、File类、Directory类、文件流FileStream类、压缩流GZipStream、拷贝大文件、序列化和反序列化

    1.集合(1)ArrayList内部存储数据的是一个object数组,创建这个类的对象的时候,这个对象里的数组的长度为0(2)调用Add方法加元素的时候,如果第一次增加元神,就会将数组的长度变为4往里 ...

  9. java中的拷贝(二)深克隆

    浅拷贝(Object类中的clone()方法)是指在拷贝对象时,对于基本数据类型的变量会重新复制一份,而对于引用类型的变量只是对引用进行拷贝. 深拷贝(或叫深克隆) 则是对对象及该对象关联的对象内容, ...

随机推荐

  1. leetcode(js)算法之696计数二进制串

    给定一个字符串 s,计算具有相同数量0和1的非空(连续)子字符串的数量,并且这些子字符串中的所有0和所有1都是组合在一起的. 重复出现的子串要计算它们出现的次数. 示例: 输入: "0011 ...

  2. plugin-barcodescanner 报错

    https://github.com/phonegap/phonegap-plugin-barcodescanner/issues/418 ionic cordova platform rm andr ...

  3. Python1 简介及安装、基础

    Python介绍 Python是面向对象,高级语言,解释,动态和多用途编程语言.Python易于学习,而且功能强大,功能多样的脚本语言使其对应用程序开发具有吸引力. Python的语法和动态类型具有其 ...

  4. LeetCode(85):最大矩形

    Hard! 题目描述: 给定一个仅包含 0 和 1 的二维二进制矩阵,找出只包含 1 的最大矩形,并返回其面积. 示例: 输入: [ ["1","0",&quo ...

  5. Java 获取当前系统的时间

    获取当前系统的时间,每隔一秒,打印一次. import java.util.Date; public class TestDate { public static void main(String[] ...

  6. Unnamed namespaces

    Unnamed namespaces The unnamed-namespace-definition is a namespace definition of the form   inline(o ...

  7. 升级到 Android Studio 3.0 + Gradle 4.1 遇到的一些坑及解决方案

    问题一: Cannot set the value of read-only property 'outputFile' for ApkVariantOutputImpl_Decorated{apkD ...

  8. 如何把网址配置为http和https可以同时访问

    1.打开iis7 ,找到具体站点 2.点击站点后右侧有个绑定按钮 3.点击绑定,增加https,设置端口,ssl选择 iis证书 4.找到ssl设置,要求证书不勾选,客户证书,忽略 5.如果右侧不显示 ...

  9. file /usr/share/mysql/charsets/README from install of MySQL-server-5.1.73-1.glibc23.i386 conflicts with file from package mysql-libs-5.1.73-8.el6_8.i686

    1:也许之前的机器安装过Mysql,但是自己不知道,账号密码也忘记了,又执行安装操作,导致Mysql不兼容问题.Linux上安装MySQL时出现不兼容的解决办法,错误如下所示: [root@maste ...

  10. Oracle 11g 安装过程中“检查网络配置要求 未执行”解决方法

    正在检查网络配置要求... 检查完成.此次检查的总体结果为: 未执行 网上查了一下,很多朋友都遇到这个问题而无从下手,其实解决起来很容易的. 只需要在 Windows XP 中安装 Microsoft ...