您的位置:首页 > 编程语言 > Java开发

java 字节流操作数据数据的几种情形分析

2015-06-03 18:32 375 查看

输入和输出的简单介绍说明

java类库中的I/O类分为输入和输出两部分,可以在JDK文档里的类层次结构中查看到。任何Inputstream或Reader派生而来的类都含有名为read()的基础方法,用于读取单个字节或者字节数组。同样任何Outputstream或者Writer派生而来的类都有名为write()的基础方法,用于写单个字节或者字节数组。但是,实际操作中我们通常不会用这些方法,因为效率非常低。而是通过叠合多个对象来提供所期望的功能(也就是装饰器设计模式,这里先提及一下该设计模式)。

总结性说明

自我感觉java 中I/O类库让人迷惑的主要原因就是:创建单一的结果流,却需要创建多个对象,也就是叠合多个对象

代码说明(我们来对比看下四个读写数据的方法)

效率极低下的readMethod1()

/**
* 运行会发现虽然可以同样的完成需求
* 但是readMethod1()方法读取效率极其低
* 因此在实际操作开发过程中不要直接使用I/O流对数据进行操作
* 而是要通过叠合多个对象来提供所期望的功能
* (这也就是装饰器设计模式)
*
*
* 1、在创建FileInputStream对象时会抛出FileNotFoundException异常
*   这是因为要操作的的数据源有可能不存在
*
* 2、在使用FileInputStream的read()方法时
*   if an I/O error occurs 会抛出I/O异常
*
* @param file
* @param file_type
* @throws IOException
*/
public static void readMethod1(File file, String file_type)
throws IOException {

FileInputStream FIStream = new FileInputStream(file);
FileOutputStream FOStream = new FileOutputStream("copy1" + file_type);
int ch = 0;
while ((ch = FIStream.read()) != -1) {
FOStream.write(ch);
}
FIStream.close();
FOStream.close();
}


带有危险readMethod2()

/**
* 运行readMethod2()方法我们可以看到对文件进行操作可以迅速完成
* 这里就是使用了一个自定义的字节数组用来对操作数据进行缓冲
* 至于对文件是否使用缓冲技术为何有大么大的差异 可以参考相关文章说明
* 这里就不再介绍
*
* 但是仔细观察会发现创建的缓冲数组的大小是通过
* FileInputStream对象的available()方法实现的,因此我们就需要谨慎使用该方法
* 这里的示例是对mp3文件进行操作如果被操作的文件非常大  当创建这个字节数组的时候就会发生内粗爆满
* 是有一定危险的  谨慎使用
* @param file
* @param file_type
* @throws IOException
*/
public static void readMethod2(File file, String file_type)
throws IOException {
FileInputStream FIStream = new FileInputStream(file);
FileOutputStream FOStream = new FileOutputStream("copy2" + file_type);
int ch = 0;
//创建一个缓冲字节数组
byte[] buf = new byte[FIStream.available()];
while ((ch = FIStream.read(buf)) != -1) {
FOStream.write(buf);
}
FIStream.close();
FOStream.close();
}


自定义的高效readMethod3()(与类库中的一些类有异曲同工之妙)

/**
* 运行readMethod3()方法 我们可以发现  该方法与readMethod2()方法的
* 运行效率相差没有多少
*
* 可以说明 字节数组的大小对运行效率是没有影响的 因此在实际操作中
* 就可以使用该方法代替readMethod2()方法使用
*
* 这是因为是缓存技术起到的效果
* 至于对文件是否使用缓冲技术为何有大么大的差异 可以参考相关文章说明
* 这里就不再介绍
*
* @param file
* @param file_type
* @throws IOException
*/
public static void readMethod3(File file, String file_type)
throws IOException {
FileInputStream FIStream = new FileInputStream(file);
FileOutputStream FOStream = new FileOutputStream("copy3" + file_type);
int ch = 0;
//创建一个缓冲字节数组
byte[] buf = new byte[1024];
while ((ch = FIStream.read(buf)) != -1) {
FOStream.write(buf);
}
FIStream.close();
FOStream.close();
}


叠合方式实现高效的readMethod4()

/***
* 第一眼看该方法  你是不是感觉该方法的效率也是同样低下  哈哈  可不要被它的表面所欺骗
* 这个方法中使用的一些类正是通过叠合的方式来完成期望的功能 这里使用过的java自身
* 提供的两个缓冲类 BufferedInputStream  BufferedOutputStream
* 这就是装饰器设计模式的体现
* 所以它的效率和readMethod3()可以说是一样的
* 这一点是可以通过源码看出的 BufferedInputStream类重写了其父类的read()方法
* 重写之后就是添加了一个自定义缓冲数组buf 有兴趣的可以查看源码 这里就不进行列出了
* @param file
* @param file_type
* @throws IOException
*/
public static void readMethod4(File file, String file_type)
throws IOException {
FileInputStream FIStream = new FileInputStream(file);
FileOutputStream FOStream = new FileOutputStream("copy4" + file_type);
//创建缓冲字节流  并关联 文件流
BufferedInputStream BIStream = new BufferedInputStream(FIStream);
BufferedOutputStream BOStream = new BufferedOutputStream(FOStream);

int ch = 0;
while ((ch = BIStream.read()) != -1) {
FOStream.write(ch);
}
FIStream.close();
FOStream.close();
}


在主函数中分别调用四个方法

/**
* 1、在主函数中分别调用四个方法
*   可以很清楚的看到它们的实现效率
*
* 2、可以使用不同的数据源进行对比操作
*
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
File file = new File("0.mp3");
String fileName = file.getName();
// 获取操作文件类型名
String file_type = fileName.substring(fileName.lastIndexOf("."),
fileName.length());
//      readMethod1(file, file_type);
//      readMethod2(file, file_type);
//      readMethod3(file, file_type);
readMethod4(file, file_type);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: