zoukankan      html  css  js  c++  java
  • Java I/O基础

      字节流和字符流的区别,字节流一次读取一个字节,字符流一次读取的是一个Unicode码,读取了2个字节。

          可以以文本编辑器打开的可以使用字符流读取,否则用字符流读取可能就会出错。图像文件就需要用字节流读取,不能用字符流操作。

          字节流的基类是InputStream和OutputStream,字符流的基类是Reader和Writer。

          读取并复制图片的代码,读取到缓存,一边读一边写。 ps:文件的相对路径要写什么看看System.getProperty("user.dir")就知道了,这个是基础路径。   

    public class FileIOTest {
    	public static void main(String [] args) throws IOException{
    		
    		int BYTE_SIZE = 1;
    		int SAVE_SIZE = 1024;
    		int i = 0;
    		byte[] buff = new byte[BYTE_SIZE]; // 每次读的缓存
    		byte[] save = new byte[SAVE_SIZE]; // 保存前缓存
    	
    		BufferedInputStream bf = new BufferedInputStream(new FileInputStream(new File("src/pattern/decorator/a.jpeg")));
    		FileOutputStream  fs = new FileOutputStream(new File("src/pattern/decorator/b.jpeg"));
    		while (bf.read(buff) != -1) { // 一个字节一个字节读
    		    save[i] = buff[0];
    		    if (i == SAVE_SIZE - 1) { // 达到保存长度时开始保存
    		     fs.write(save, 0, SAVE_SIZE);
    		     save = new byte[SAVE_SIZE];
    		     i = 0;
    		    } else {
    		     i++;		    
    		   }		   		   
    		}
    		// 最后这段如果没达到保存长度,需要把前面的保存下来
    		if (i > 0) {
    		   fs.write(save, 0, i);
    		}   		
    		fs.close();
    		bf.close();
    	}
    }
    

       流的关闭应该放到finally中,上面的是不太合适的。

          

           下面是关于大文件读取的一些数据,原文为:

           http://aronlulu.iteye.com/blog/1018370

           读取文件大小:1.45G 
    第一种,OldIO: 

    Java代码  收藏代码
    1. public static void oldIOReadFile() throws IOException{  
    2.     BufferedReader br = new BufferedReader(new FileReader("G://lily_947.txt"));  
    3.     PrintWriter pw = new PrintWriter("G://oldIO.tmp");  
    4.     char[] c = new char[100*1024*1024];  
    5.     for(;;){  
    6.         if(br.read(c)!=-1){  
    7.             pw.print(c);  
    8.         }else{  
    9.             break;  
    10.         }  
    11.     }  
    12.     pw.close();  
    13.     br.close();  
    14. }  


    耗时70.79s 


    第二种,newIO: 

    Java代码  收藏代码
    1. public static void newIOReadFile() throws IOException{  
    2.         FileChannel read = new RandomAccessFile("G://lily_947.txt","r").getChannel();  
    3.         FileChannel writer = new RandomAccessFile("G://newIO.tmp","rw").getChannel();  
    4.         ByteBuffer bb = ByteBuffer.allocate(200*1024*1024);  
    5.         while(read.read(bb)!=-1){  
    6.             bb.flip();  
    7.             writer.write(bb);  
    8.             bb.clear();  
    9.         }  
    10.         read.close();  
    11.         writer.close();  
    12.           
    13.     }  


    耗时47.24s 


    第三种,RandomAccessFile: 

    Java代码  收藏代码
    1. public static void randomReadFile() throws IOException{  
    2.         RandomAccessFile read = new RandomAccessFile("G://lily_947.txt","r");  
    3.         RandomAccessFile writer = new RandomAccessFile("G://random.tmp","rw");  
    4.         byte[] b = new byte[200*1024*1024];  
    5.         while(read.read(b)!=-1){  
    6.             writer.write(b);  
    7.         }  
    8.         writer.close();  
    9.         read.close();  
    10.     }  


    耗时46.65 

    第四种,MappedByteBuffer: 

    Java代码  收藏代码
    1. public static void mappedBuffer() throws IOException{  
    2.         FileChannel read = new FileInputStream("G://lily_947.txt").getChannel();  
    3.         FileChannel writer = new RandomAccessFile("G://buffer.tmp","rw").getChannel();  
    4.         long i = 0;  
    5.         long size = read.size()/30;  
    6.         ByteBuffer bb,cc = null;  
    7.         while(i<read.size()&&(read.size()-i)>size){  
    8.             bb = read.map(FileChannel.MapMode.READ_ONLY, i, size);  
    9.             cc = writer.map(FileChannel.MapMode.READ_WRITE, i, size);  
    10.             cc.put(bb);  
    11.             i+=size;  
    12.             bb.clear();  
    13.             cc.clear();  
    14.         }  
    15.         bb = read.map(FileChannel.MapMode.READ_ONLY, i, read.size()-i);  
    16.         cc.put(bb);  
    17.         bb.clear();  
    18.         cc.clear();  
    19.         read.close();  
    20.         writer.close();  
    21.           
    22.     }  


    耗时:36 

    前三种读法对应的资源占用图如下: 
    相对于最后一种内存直接映射方式前面的测试其实无意义,基本秒杀。。。。。 
    对于很大的文件直接分块映射时内存会不够,这是因为MappedByteBuffer未被释放造成的,sun未提供直接回收MappedByteBuffer区域的方法,这个时候有两种方法解决,第一种比较愚笨的: 

    Java代码  收藏代码
    1.           System.gc();   
    2.          System.runFinalization();   
    3.          try {  
    4.     Thread.sleep(3000);  
    5. catch (InterruptedException e) {  
    6.       
    7.     e.printStackTrace();  
    8. }  


    第二种网上找来的,利用反射调用clean方法: 

    Java代码  收藏代码
    1. public static void unmap(final MappedByteBuffer buffer) {  
    2.         if (buffer == null) {  
    3.             return;  
    4.         }  
    5.         AccessController.doPrivileged(new PrivilegedAction<Object>() {  
    6.             public Object run() {  
    7.                 try {  
    8.                     Method getCleanerMethod = buffer.getClass().getMethod("cleaner", new Class[0]);  
    9.                     if (getCleanerMethod != null) {  
    10.                         getCleanerMethod.setAccessible(true);  
    11.                         Object cleaner = getCleanerMethod.invoke(buffer, new Object[0]);  
    12.                         Method cleanMethod = cleaner.getClass().getMethod("clean", new Class[0]);  
    13.                         if (cleanMethod != null) {  
    14.                             cleanMethod.invoke(cleaner, new Object[0]);  
    15.                         }  
    16.                     }  
    17.                 } catch (Exception e) {  
    18.                     e.printStackTrace();  
    19.                 }  
    20.                 return null;  
    21.             }  
    22.    
    23.         });  
    24.     }  


    以上两种方法感觉都别扭,还有就是可以自己分割成物理文件再循环调用,这个也不太美观。 
    速度也会减慢好多。

  • 相关阅读:
    .Net Core 微服务学习一
    微服务学习一
    软件开发基本接口学习二
    浏览器根对象window之操作方法
    浏览器根对象window之caches
    Angular面试题三
    浏览器根对象window之performance
    Angular面试题二
    浏览器根对象window之screen
    浏览器根对象window之history
  • 原文地址:https://www.cnblogs.com/lnlvinso/p/3933772.html
Copyright © 2011-2022 走看看