zoukankan      html  css  js  c++  java
  • java IO之字节流和字符流-Reader和Writer以及实现文件复制拷贝

    接上一篇的字节流,以下主要介绍字符流。字符流和字节流的差别以及文件复制拷贝。在程序中一个字符等于两个字节。而一个汉字占俩个字节(一般有限面试会问:一个char是否能存下一个汉字,答案当然是能了,一个char和一汉字一样都占两个字节)。一般用字节流假设定义为奇数个长度是,那么存储汉字时会有乱码问题,Java提供了Reader和Writer两个专门操作字符流的类。

    1 Writer 字符输出流

       此类是抽象类。需用其子类实现。实现了Closeable,Flushable, Appendable三个接口。

       有例如以下的方法:

       Writer append(char c) 将制定字符加入到writer

       void close() 关闭自流

       void flush()刷新改流的缓冲

       void write(char[]  cbuf) 写入字符数组

       void  write(char[] cbuf, int off, int len)写入字符数组的某一部分。

       void write(int c) 写入单个字符

       void write(String str) 写入字符串

       void  write(String str, int off, int len) 写入字符串的某一部分。

     能够看出 Writer是对Char[] 和 String字符串操作,而OutputStream是对byte[]数组操作。

    Writer还能够向流中追加内容。

     以下是Writer的实例,使用其子类FileWriter实例化:

    package andy.io.test;
    
    import java.io.File;
    import java.io.FileWriter;
    import java.io.IOException;
    import java.io.Writer;
    
    
    /**  
     * @author Zhang,Tianyou  
     * version:2014-11-19 下午4:59:24  
     * 
     *  
     */
    
    public class WriterTest {
    
    	/**
    	 * @param args
    	 * @throws IOException 
    	 */
    	public static void main(String[] args) throws IOException {
    		// TODO Auto-generated method stub
    
    		File file = new File("d:" + File.separator + "test.txt");
    		
    		Writer writer = null;
    		
    		writer = new FileWriter(file, true);//第二个參数为向文件追加内容
    		
    		String str = "hello andy !";
    		
    		//方法一
    		writer.write(str.toCharArray());
    		
    		//方法二
    		//writer.write(str);
    		
    		writer.close();
    	}
    
    }
    

     2 Reader 字符输入流

     Reader也是抽象类,事实上现了Closeable,Readable接口。

     其主要还有例如以下的方法:

       void close() 关闭字符输入流

         int read()  读取单个字符。

     
         int read(char[] cbuf)   将字符读入数组。

     
         abstract  int read(char[] cbuf, int off, int len) 将字符读入数组的某一部分。 
         int read(CharBuffer target)  试图将字符读入指定的字符缓冲区。

     

      详细实现例如以下:

      

    package andy.io.test;
    
    import java.io.File;
    import java.io.FileReader;
    import java.io.IOException;
    import java.io.Reader;
    
    
    
    /**  
     * @author Zhang,Tianyou  
     * version:2014-11-19 下午5:11:02  
     * 
     *  
     */
    
    public class ReaderTest {
    
    	/**
    	 * @param args
    	 * @throws IOException 
    	 */
    	public static void main(String[] args) throws IOException {
    		// TODO Auto-generated method stub
    
    		File file = new File("d:" + File.separator + "test.txt");
    		
    		Reader reader = null;
    		
    		reader = new FileReader(file);
    		
    		char[] c = new char[(int) file.length()];
    		
    		//方法一
    		
    		//reader.read(c);
    		
    		//方法二
    		int temp = 0;
    		int len = 0;
    		while ((temp = reader.read()) != -1) {
    			c[len] = (char) temp;
    			++len;
    		}
    		
    		
    		reader.close();
    		
    		System.out.println("内容为:" + new String(c));
    		
    	}
    
    }
    

     3 字节流和字符流的差别

     字节流和字符流的使用很的相似,字节流在操作时本身不会用到缓冲区(内存),是文件本身的直接操作,而字符流在操作是使用了缓冲区。通过缓冲区再操作文件。

    字符流必须使用clos()或者flush()将缓冲区中的流输出。

    而字节流不关闭也可以正常输出。

        其原理例如以下:

       字节流:   程序------------------字节流----------------------文件

      字符流:   程序-------------------字符流----------------------缓存-----------------------------文件


      那究竟用哪个好呢?:全部的文件在硬盘或者在传输的过程中都是以字节的方式进行的,包含图片等都是按字节的方式存储的,而字符是仅仅有在内存中才会形成,所以一般使用字节流。


    3 实现文件从A复制复制到B

      在cmd 中运行  java  FileCopy  源文件    目标文件

    实现思路: 1 将源文件的内容所有读到内存中。并一次性写入到目标文件里。 

                         2  不将源文件的内容读取进来,而是採用边读边写的方式。

    我们肯定採用另外一种,假设一次性将文件读到内存中。必定导致内存溢出,影响性能。


    详细实现例如以下:

    package andy.io.test;
    
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    
    /**
     * @author Zhang,Tianyou version:2014-11-19 下午5:31:21
     * 
     * 
     */
    
    public class FileCopy {
    
    	/**
    	 * @param args
    	 */
    	public static void main(String[] args) {
    		// TODO Auto-generated method stub
    		if (args.length != 2) {// 推断文件參数是否为2
    			System.out.println("文件參数不对。");
    			System.out.println("比如:java FileCopy  源文件路径    目标文件路径");
    			System.exit(1);
    		}
    
    		File srcfile = new File(args[0]);
    		File objfile = new File(args[1]);
    
    		if (!srcfile.exists()) {
    			System.out.println("源文件不存在!

    "); System.exit(1); } InputStream inputStream = null; OutputStream outputStream = null; try { inputStream = new FileInputStream(srcfile); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } try { outputStream = new FileOutputStream(objfile); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } if (inputStream != null && outputStream != null) { try { byte[] buff = new byte[1024]; // 每次读取1024个 int len = 0; while ((len = inputStream.read(buff)) != -1) { outputStream.write(buff, 0, len); } inputStream.close(); outputStream.close(); } catch (IOException e) { e.printStackTrace(); } } } }



    4 Java IO流的类关系例如以下:



     

  • 相关阅读:
    js高级1
    JUC总览
    7 种阻塞队列相关整理
    Exchanger 相关整理
    Semaphore 相关整理
    ConcurrentLinkedQueue 相关整理
    ConcurrentHashMap(1.8) 相关整理
    ConcurrentHashMap(1.7) 相关整理
    ReentrantReadWriteLock 相关整理
    LockSupport 工具相关整理
  • 原文地址:https://www.cnblogs.com/zfyouxi/p/5182972.html
Copyright © 2011-2022 走看看