java学习之字符流和字节流的区别

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_33322074/article/details/87401098

一、字节输出流OutputStream

  1. OutputStream是抽象类,是表示输出字节流的所有超类,操作的数据都是字节,定义了字节输出流的基本共性和方法。OutputStream有大量子类,具体请看javaAPI文档,比较常用的是FileOutputStream 即:将数据写入到File的输出流。

    注意:其中的方法close()方法和Flush()方法的不同,close()自带flush()方法,但是close()一旦使用就会关闭和释放该流的所有资源,即这个流不能再使用了。flush()则是强制写出所有缓冲的所有字节,即将数据强制从缓冲中写入到文档中。

  2. FileOutputStream有哪些用处

    1、可以往指定的文件里写东西.
    2、可以给文档内容进行续写和换行处理,换行符为\r\n添加字符的前面

  3. FileOutputStream需要IO异常处理

    1、因为FileOutStream是往文档里写数据的,必须指定相应的文档,如果这个文档不存在怎么办?那就要抛异常了。
    2、处理异常有两种方式,一是直接抛出throws IOException,另一种是使用try…catch…finally的方式。

    
    		public class FileOutputStreamDemo3 {
    			public static void main(String[] args) {
    				//将路径名赋给file文件,这里并没有创建file.txt,只是将这个路径给File
    				File file = new File("c:\\file.txt");
    				//定义FileOutputStream的引用
    				FileOutputStream fos = null;
    				try {
    					//创建FileOutputStream对象
    					fos = new FileOutputStream(file);
    					//写出数据
    					fos.write("abcde".getBytes());
    				} catch (IOException e) {
    					System.out.println(e.toString() + "----");
    				} finally {
    					//一定要判断fos是否为null,只有不为null时,才可以关闭资源
    					if (fos != null) {
    						try {
    							fos.close();
    						} catch (IOException e) {
    							//如果为空,抛出异常
    							throw new RuntimeException("");
    						}
    					}
    				}
    			}
    		}
    
    	
    
  4. OutputStream字节输出流和File类的区别:

    区别有:
    1、File类是针对文件路径的,有以下功能,可以创建删除一个文件,可以对文件进行copy,可以调取文件的路径,文件名,文件大小,可以将路径下的所有文件放到一个数组里面,可见File类就是对文件和路径的操作,如果往文档里插入一些内容或续写一些数据是不行的。
    2、OutputStream是对文档的操作,专门用于向文档里输入数据的。

#二、字节输入流InputStream

  1. OutputStream是将内存中的数据写出到文件中,而InputStream的作用是将文件中的数据读入到内存中。InputStream和OutputStream正好相对应,前者是将文件中的数据读入到内存中,后者是将内存中的数据写入文件中。也有子类FileInputStream

    注意:FileInputStream有两个读取文件内容的方法,一个是read(),另一个是read(byte[] b),前者是一个字节一个字节的读取,后者是一个数组一个数组的读取当然后者的速度更快。但是这里有个小问题,看代码:

    
    	public class FileInputStreamDemo {
    		public static void main(String[] args) throws IOException {
    			File file = new File("c:\\file.txt");
    			//创建一个字节输入流对象,必须明确数据源,其实就是创建字节读取流和数据源相关联。
    			FileInputStream fis = new FileInputStream(file);
    			//读取数据。使用 read();一次读一个字节。
    			int ch = 0;
    			while((ch=fis.read())!=-1){
    				System.out.println("ch="+(char)ch);
    	
    			// 关闭资源。
    			fis.close();
    		}
    	}
    
    

    下面是用read(byte[] b)方法读取的

    
    			public class FileInputStreamDemo2 {
    				public static void main(String[] args) throws IOException {
    					/*
    					 * 演示第二个读取方法, read(byte[]);
    					 */
    					File file = new File("c:\\file.txt");
    					// 创建一个字节输入流对象,必须明确数据源,其实就是创建字节读取流和数据源相关联。
    					FileInputStream fis = new FileInputStream(file);		
    					//创建一个字节数组。
    					byte[] buf = new byte[1024];//长度可以定义成1024的整数倍。		
    					int len = 0;
    					while((len=fis.read(buf))!=-1){
    						System.out.println(new String(buf,0,len));
    					}
    					fis.close();
    				}
    			}
    		
    

    两者的区别是:read()的方法一次只读一个字节并且返回的是一个编码数字,而read(byte[] b)一次读取数组大小字节,然后再打印这个数组

#三、字符流Reader和Writer

  1. Reader

    Reader是抽象类,Reader的直接子类有InputStreamReader,它的直接子类有FileReader.这表明Reader是字符输入流的祖宗类。

  2. Writer

    Writer是抽象类,Writer的直接子类有OutputStreamWriter,它的直接子类有FileWriter.这表明Writer字符输出流的子类。

#四、字符流和字节流的区别:

  1. 字节流是以字节为单位传递的,因为所有电脑上的东西都是二进制字节,因此可以传递任何数据,比如图片,各种字符等。字节流只能写入字节,读取字节。windows中的默认编码是AscII编码,当你用字节流写入某个文档时只能先转换成ASCII编码,然后再写入文档,当你去查看文档时windows系统默认用ASCII编码将其解码,你才能看懂里面的内容。实际上存储的都是字节编码。当用读取文件内容时,FileReader类也是读取的是字符编码。这就造成了当你用FileReader读取文件内容时读取的内容时数字。例如下面这段代码:

    
    	public class CharStreamDemo {
    		public static void main(String[] args) throws IOException {
    			//给文件中写中文
    			writeCNText();
    			//读取文件中的中文
    			readCNText();
    		}	
    		//读取中文
    		public static void readCNText() throws IOException {
    			FileInputStream fis = new FileInputStream("c:\\cn.txt");
    			int ch = 0;
    			//此处的read()函数读取的是字节,打印出来的是ASCII码
    			while((ch = fis.read())!=-1){
    				System.out.println(ch);
    			}
    		}
    		//写中文
    		public static void writeCNText() throws IOException {
    			FileOutputStream fos = new FileOutputStream("c:\\cn.txt");
    			//注意此处write是将字符串内容转换成字节后写入的,如果不转换成字节数组,是不能写的。
    			fos.write("a中华民族欢迎你".getBytes());
    			fos.close();
    		}
    	}
    
    

    可见字节流是通过字节码的方式读取和输入的。必须通过字节码的形式进行写入和读取。

  2. 字符流的运用

    加入有一个文本文档里面存储的是字节码,你要打印里面的内容,也就是读取到控制台上,你总不能用FileOutputStream打印几个ASCII码数字吧,这时候就需要用到FileWriter字符流了,FileReader的默认编码是gbk.比如这段代码:

    
    		public class CharStreamDemo {
    			public static void main(String[] args) throws IOException {
    				//给文件中写中文
    				writeCNText();
    				//读取文件中的中文
    				readCNText();
    			}	
    			//读取中文
    			public static void readCNText() throws IOException {
    				//读取的是通过FileReader类读取的,读取的是字符流,字符流的方法
    				FileReader fr = new FileReader("D:\\test\\cn.txt");
    				int ch = 0;
    				while((ch = fr.read())!=-1){
    					//输出的字符对应的编码值
    					System.out.println(ch);
    					//输出字符本身
    					System.out.println((char)ch);
    				}
    			}
    			//写中文
    			public static void writeCNText() throws IOException {
    				//通过FileOutputStream写入的是字节编码,文档里存储的是字节码
    				FileOutputStream fos = new FileOutputStream("D:\\test\\cn.txt");
    				fos.write("a中华民族欢迎你".getBytes());
    				fos.close();
    			}
    		}  
    
    
    

    3 . 字符流和字节流的最大区别就是,

    字节流FileInputStream读取方法read()是一个字节一个字节的读取,Write()方法是一个字节一个字节的写入。在gbk当中一个汉字占用2个字节,utf-8中一个汉字占用3个字节,如果一个字节一个字节的读读出来的编码无法组成一个汉字。而如果用字符流,去读取,字符流会根据默认编码一次性的读取一个字符,即若是utf-8编码就会读取3字节,若是gbk编码就会一次读取2个字节。因此字符流是根据字符所占字节大小而决定读取多少字节的。这就是字符流和字节流的本质不同。

猜你喜欢

转载自blog.csdn.net/qq_33322074/article/details/87401098