`
gaosililn
  • 浏览: 73414 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论

java--IO效率分析

    博客分类:
  • Java
 
阅读更多

在java中,IO模块占着相当重要的位置,IO效率更是关系着软件的效率高低。下面我就对IO的分析进行的一些记录:

相关的基本概念:

流:是数据的有序序列。按照基本的输入输出流的读写数据的不同类型可以分为字节流与字符流。字节流用于读写子节类型的数据(包括ASCMII表中字符),是使用InputStream、OutputStream及他们的子类。字符流用于读写Unicode字符。包括Reader、Writer及他们的子类。

我们在进行读写操作时候,一定的记得读写操作使用的字符集是一致的。若是不一致的话,即使是代码没有问题也会出现乱码的结果。系统使用的默认字符集是不完全一样的,主要是各个CP的问题。我的系统默认字符集是"GBK ",有的是"UTF-8".下面看代码说话吧。

 

			
			FileOutputStream fo=new FileOutputStream("text1.txt");
			String st="华信欢迎你!Wellcome……";
			byte bytes[]=st.getBytes("GBK");
                         //使用默认字符集编码
			fo.write(bytes);
			System.out.println("输出结束!---");
			fo.close();		

 输出截图:

 

			
			FileOutputStream fo=new FileOutputStream("text1.txt");
			String st="华信欢迎你!Wellcome……";
			byte bytes[]=st.getBytes("UTF-8");
                        //使用UTF-8字符集编码
			fo.write(bytes);
			System.out.println("输出结束!---");
			fo.close();	

 结果截图:

 出现乱码是因为读取时候使用默认的"GBK "字符集编码,转为数组写出时候是使用"UTF-8"字符集编码

 

 

字节流套上缓冲流之后,字节先读取到缓冲区当中,当要使用到数据时候可以系统会从缓冲区当中提取数据,这样就可以可以提高读写的效率。若是读取大量的数据时候,每次都从数据源提取数据,若每次都是读取一个字节,想想系统要来回数据源多少回?这样的情况会给系统带来不小的负担。还有就是使用字节数组、缓冲流的时候可以自定义他们的容量的大小,合适的大小也可以提供读写的效率,也不会给系统造成浪费这问题,在开发时候要进行去取大量的数据时候,最好先测试出你所需要的字节数组的最佳容量大小和缓冲区的容量的最佳大小。容量的过大或者过小都会降低效率

下面就有无缓冲流,每次都去字节和每次读取数组进行比较效率。(读取MP4文件进行比较,所使用的缓冲区、数组的大小都是测试当时的最佳容量,过大或者过小的容量对效率问题在这就不展示了)

 

		//使用字节流进行复制
		FileInputStream fi=new FileInputStream("8.mp4");
		FileOutputStream fo=new FileOutputStream("81.mp4");
		//使用读取一个整形
		int i=fi.read();
		while(i!=-1){
			fo.write(i);
			i=fi.read();
		}
		//关闭相关流 注意顺序
		fo.close();
		fi.close();
	

 用时:151960毫秒

 

 

 

		FileInputStream fi=
                             new FileInputStream("8.mp4");
		FileOutputStream fo=
                             new FileOutputStream("81.mp4");
		//使用数组
		byte []bytes=new byte[256*256];
               //测试该文件复制的数组的比较好的数组大小
		while(fi.read(bytes)!=-1){
			fo.write(bytes);
		}
		
		//关闭相关流
		fo.close();
		fi.close();

 用时:109毫秒

 

 

 

		//使用字符流进行复制操作
		FileInputStream fi=
                              new FileInputStream("8.mp4");
		FileOutputStream fo=
                              new FileOutputStream("8w_b.mp4");
		//创建缓冲区 指定缓冲区的容量大小
		BufferedInputStream bi=
                          new BufferedInputStream(fi,256*512);
                //复制该文件比较好的缓冲区的容量大小
		BufferedOutputStream bo= 
                          new BufferedOutputStream(fo,256*512);
		//使用读取一个整形
		int i=bi.read();
		while(i!=-1){
			bo.write(i);
			i=bi.read();
		}
		//关闭相关流 注意顺序
		bo.close();
		bi.close();
		fo.close();
		fi.close();	

 用时:2369毫秒

 

 

 

		FileInputStream fi=
                        new FileInputStream("8.mp4");
		FileOutputStream fo=
                        new FileOutputStream("8w_b.mp4");
		//创建缓冲区
		BufferedInputStream bi=
                        new BufferedInputStream(fi,256*512);
		BufferedOutputStream bo=
                        new BufferedOutputStream(fo,256*512);
		//使用数组
		byte []bytes=new byte[256];//比较好的大小
		while(bi.read(bytes)!=-1){
			bo.write(bytes);
		}

		//关闭相关流  注意顺序
		bo.close();
		bi.close();
		fo.close();
		fi.close();	

 用时:86毫秒

 

提供的用时仅供参考,没有绝对的。若是更大的文件效果的差异更明显。

 

BufferedReader ,BufferedWriter的用法和BufferedWriter与PrintWriter的区别:BufferedWriter写出数据时候一定的记得flush一下,不然不能保证数据完全写出来,而PrintWriter(file,true)当第二个参数为true时候,系统会自动flush。在BufferedWriter当中的方法里没有自动换行的方法,在PrintWriter中就有自动换行的方法。

         //创建相应的流对象
	FileInputStream fi=new FileInputStream("test.txt");
	InputStreamReader ir=new InputStreamReader(fi);
	BufferedReader br=new BufferedReader(ir,100);
	FileOutputStream fo=new FileOutputStream("testw.txt");
	OutputStreamWriter or=new OutputStreamWriter(fo);
        PrintWriter bw=new PrintWriter(or);

 

使用PrintWriter写出数据:

			String st=br.readLine();
			while(st!=null){
				pw.println(st);//PrintWriter的写出方法,自动添加换行符
				st=br.readLine();
			}	

 结果输出截图:

使用BufferedWriter的方法:

			String st=br.readLine();
			while(st!=null){
				bw.write(st);//BufferedWriter的写出方法,没有自动换行
				st=br.readLine();
			}		

 输出结果截图:

而两次操作的元数据文本都是一样的

 

 

有没有想过,如果读取大量的数据时,把文件分成几段同时读取是不是更快呢?

RandomAccessFile(file,"rw/…")随机访问文件类,参数第一个是操作的文件对象,第二个是的可读、可写、可读可写等操作权限。使用该类进行文件的读些时候可以把文件分成合理的若干段并且指定每段的区域大小。值得注意的是,指定的大小不一过大或者过小。区域制定过小的话,在写出数据时候,数据过大会出现数据丢失。区域指定过大会出现浪费资源。比如说,我把文件分成五段,每段指定区域的大小为100字节,但是我在每一段写出6字节的数据,那么文件的大小回事406字节(前面的4段每段100字节,最后一段6字节。在我的PC机上,前面的每段是一百字节,每段后面会有一大段的空白,但是在苹果的PC上,文字看起来是连着的,但是在第一段文字结束后按右箭头按钮光标是不移动的,要按足94字节才移动)。在使用线程对文件进行读写时候,可以不按照顺序进行读写,但是写出的顺序是不会乱的。还是甩代码说话吧。

package com.lilin.io;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.RandomAccessFile;

public class TestBYRandomAccessFile {
/**
 * RandomAccessFile类的测试
 * @param args
 */
	
	static File file=new File("C:\\Users\\gaosi\\Desktop\\1.txt");
	static File file1=new File("testByRAFW.txt");
	public static void main(String[] args) {
		if(file1.exists()){
			file1.delete();
	
		}
		for (int i = 0; i < file.length()/10; i++) {
			new TestBYRandomAccessFileThread(file,file1,1+i).start();
		}
		
		System.out.println("操作完毕");
	}
}

 

package com.lilin.io;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.RandomAccessFile;

public class TestBYRandomAccessFileThread extends Thread {
	private File file,file1;//文件对象
	int blok;//段数
	int l=10;//每段区域的大小
	/**
	 * 构造函数,接收对象以及读写的区域段数
	 * @param file  文件对象
	 * @param blok  段数
	 */
	public TestBYRandomAccessFileThread (File file,File file1,int blok){
		this.file=file;
		this.file1=file1;
		this.blok=blok;
	}
	
	@Override
	public void run() {
		try {
			//创建随机访问文件流对象
			@SuppressWarnings("resource")
			RandomAccessFile raf=new RandomAccessFile(file,"rw");
			RandomAccessFile raf1=new RandomAccessFile(file1,"rw");
			//指定开始读写的帧
			raf1.seek((blok-1)*l);
			raf.seek((blok-1)*l);
			byte []bytes=new byte[10];
//			String st=raf.readLine();
			raf.read(bytes);
			//写出数据
			raf1.write(bytes);
//			raf1.writeChars(st);
			
			
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		
	}

}

 根据比对,数据是一样的。

 

要是要对问件进行复制,Apache提供的一个IO库,里面的提供的方法就非常简单了。

 

                File file1=new File("8.mp4");
		File file2=new File("80.mp4");
	        FileUtils.copyFile(file1, file2);

几行代码就可以搞定复制文件的操作, 是不是超炫的?但是效率就不是非常高的。该类里面还有很多方法,值得去研究研究。

那么问题来了,怎么使用Apache的IO呢?

登陆apache.org

 

 

 

 

 

 
 导入工程里面lib,在Build path一下就可以了直接使用了,不需要创建实例,FileUtils可以当成静态的变量在使用

 

 

 

  • 大小: 7.1 KB
  • 大小: 11.1 KB
  • 大小: 8.3 KB
  • 大小: 7.5 KB
  • 大小: 11.5 KB
  • 大小: 13.6 KB
  • 大小: 16.2 KB
  • 大小: 8.7 KB
  • 大小: 7.2 KB
  • 大小: 23.2 KB
分享到:
评论

相关推荐

    java-source-to-draw.io:从Java源代码生成draw.io图-java source code

    总的来说,"java-source-to-draw.io" 是一个创新的工具,结合了编程语言和图形表示,使得Java源代码的分析和交流变得更加直观和高效。对于任何希望改善代码管理和团队协作的开发者来说,都是一个值得尝试的资源。

    java-util-1.3.1.jar.zip

    它通常包含了一些Java标准库中没有或者功能更加强大的工具类,用于提高开发效率,解决特定问题。1.3.1版本代表了这个库的一个稳定迭代,可能包括了性能优化、新功能的添加以及已知问题的修复。 `java-util-1.3.1....

    Java-IO流基础例题 & 例题源码 & PPT教学文档(黑马程序员详细版).rar

    为了提高读写效率,Java提供了带缓冲功能的流,如BufferedInputStream和BufferedReader。它们在内部维护了一个缓冲区,可以批量读写数据,减少对底层设备的频繁操作。 四、转换流( InputStreamReader 和 ...

    commons-fileupload-io

    commons-io-2.5.jar java学习jar包”提及了两个关键的Java库:Apache Commons FileUpload和Apache Commons IO。这两个库在Java开发中扮演着重要的角色,特别是涉及到文件上传和I/O操作时。 Apache Commons ...

    commons-io-2.4 包含了所有commons-io的jar包和源码

    10. **源码分析**:由于包含源码,开发者可以深入理解Apache Commons IO库的内部工作原理,学习优秀的编程实践,并根据需求进行扩展或定制。 Apache Commons IO 是Java开发中的重要辅助库,它的功能强大且实用,...

    pragmatic-java-engineer,Java Java.zip

    - **IO/NIO**:讨论了Java的输入输出系统,包括流的概念、文件操作以及非阻塞I/O(NIO)的使用。 - **多线程**:讲解了线程的创建与管理,同步机制,如synchronized和Lock,以及并发工具类。 - **网络编程**:...

    adv-java-examples.zip_adv-java-examples_大项目

    13. **性能优化**:可能涉及内存管理、垃圾回收、CPU瓶颈分析等,帮助提升程序的运行效率。 14. **图形用户界面(GUI)**:可能包含Swing或JavaFX的示例,展示如何创建交互式的桌面应用程序。 这些高级Java编程...

    Scalable IO in Java -Doug Lea.rar

    从提供的文件列表来看,"Scalable IO in Java -Doug Lea.pdf"可能是该主题的详细论述,而"1.pptx"可能是相关的演示文稿或课程幻灯片,它们将更深入地阐述这些概念并提供实例分析。阅读这些材料,开发者可以学习如何...

    基于Java的实例源码-二进制IO类与文件复制操作实例.zip

    这个压缩包中的源码很可能是对这些概念的实践应用,通过实际运行和分析这些代码,开发者可以更好地理解和掌握Java中的二进制IO操作和文件复制技术。同时,这也可以作为学习和教学的宝贵资源,帮助初学者快速上手并...

    trinea-java-common.rar java工具类

    通过以上分析,我们可以看出Trinea-java-common作为一个全面的Java工具类库,它在多个方面极大地丰富了Java开发者的工具箱。无论是在日常开发还是项目构建中,都能从中找到适用的功能,提高代码质量和开发效率。因此...

    IO流梳理--及效率分析

    本篇文章将深入梳理Java中的I/O流体系,并对不同类型的流进行效率分析,帮助开发者更好地理解和运用。 Java的I/O流分为四大类:字节流(Byte Stream)、字符流(Character Stream)、对象流(Object Stream)和套接...

    JAVA-IO流学习总结.docx

    ### JAVA IO流学习总结 #### 一、流的概念与分类 **流(Stream)**是一种抽象的概念,用来表示数据的有序集合,这些数据可以被连续读取或写入。在Java中,流是处理输入/输出(I/O)的核心机制,允许程序员以一种统一...

    目录多文件上传-JAVA IO流常用详解

    ### 目录多文件上传-JAVA IO流常用详解 #### 概述 本文将详细介绍一个Java程序中的功能模块——如何实现目录多文件上传,并利用Java IO流进行文件复制操作。该功能可以实现在用户选择一个目录后,自动扫描并上传该...

    imgui-java-main.zip

    Dear ImGui,作为一个强大的即时模式图形用户界面库,被广泛应用于游戏开发、调试工具、数据分析可视化等领域。它的轻量级设计和高效的性能深受开发者喜爱。而“imgui-java-main.zip”文件正是将这一特性引入Java...

    JAVA-WEB开发实战

    此外,可能还会涉及到异常处理、集合框架(如ArrayList和HashMap)以及IO流等核心Java技术。 其次,JAVA-WEB开发离不开Servlet和JSP(JavaServer Pages)。Servlet是JAVA处理HTTP请求的主要工具,而JSP则是一种用于...

    Java NIO与IO性能对比分析.pdf

    本文将分析Java NIO与Java IO在性能上的对比,并尝试找出性能差异的原因,以及探讨哪种编程模型更适合高并发的应用场景。 Java IO模型是一种阻塞型I/O模型,在数据的读写过程中,如果线程在等待数据,将会一直被挂...

    java-version--VSM.rar_VSM JAVA_java VSM_java-version--VSM_vsm_文件

    2. **IO操作**:Java的FileInputStream和BufferedReader等类用于读取文件内容。 3. **文本预处理**:在计算VSM之前,需要对文本进行预处理,包括去除停用词、标点符号,进行词干提取和词形还原,这通常通过自定义...

    io流的全部课件io流是java非常重要的一部分,所以给大家分享一下

    Java中的IO流是程序与外部资源交互的重要工具,它涵盖了数据的输入与输出操作,包括从硬盘、网络、内存等地方读取数据以及向这些地方写入数据。本课件全面探讨了Java IO流系统,旨在帮助开发者深入理解并熟练掌握这...

    javaParser 包 javaparser-core-3.6.16.jar

    import java.io.File; import java.nio.file.Paths; public class Main { public static void main(String[] args) { String sourceCode = new File("path/to/your/java/file.java").getAbsolutePath(); ...

    Scalable io in java.doc

    此外,NIO也被用于大文件处理,如日志文件分析,或者需要高效率读写操作的场景。 NIO的一个典型应用场景是Java的ServerSocketChannel和SocketChannel,它们提供了非阻塞的套接字操作。服务器可以使用Selector监听多...

Global site tag (gtag.js) - Google Analytics