文件流共有四类,(FileOutputStream)文件字节输出流,(FileInputStream)文件字节输入流,(FileWriter)文件字符输出流,(FileReader)文件字符输入流。
输入流是用来从文件中读取数据到内存中,输出流的作用是写入数据到文件中。
先看(FileOutputStream)文件字节输出流:
try { // FileOutputStream out=new FileOutputStream(path); 如果只传入一个参数path,则第二个参数默认为false,即原文件内容会新的写入的内容被覆盖 out=new FileOutputStream(path,true); //如果后面参数为true,则在原内容基础上append新内容 String s="hello world"; // out.write(s.getBytes()); 将字符串转换为字节数组,然后写到文件中 out.write(s.getBytes(),0,5); //表示只读取数组中的0到5位 } catch (IOException e) { e.printStackTrace(); }finally { try { if(out!=null){ out.close(); //不要忘记关闭流 } } catch (IOException e) { e.printStackTrace(); } }
注意这里的 path 的上级文件夹一定要全部都存在,否则会报错,提示找不到文件路径。
(FileInputStream)文件字节输入流
FileInputStream in=null; try { // File f=new File(path); // in=new FileInputStream(f); //可传入File对象 in=new FileInputStream(path); //也可直接传入path int i; while((i=in.read())!=-1) { //in.read()每次返回数据中的一个字节,当读到结束,会返回-1 System.out.print((char)i); //将字节转换为字符,然后读出 } } catch (IOException e) { e.printStackTrace(); }finally { try { if(in!=null){ in.close(); //关闭流 } } catch (IOException e) { e.printStackTrace(); } }
该方法将数据一个字节一个字节地读取出来
还有一个方法是建立一个byte数组,将该数组作为缓冲区将数据一段一段的读出
FileInputStream in=null; try { // File f=new File(path); // in=new FileInputStream(f); //可传入File对象 in=new FileInputStream(path); //也可直接传入path byte[] buffer=new byte[1024]; //创建一个1024K的byte数组 // int len = in.read(buffer); // 注意,当read()方法中传入数组时,返回的值就变成了 读取的数据的长度,而不是返回数据中的一个字节 // System.out.println(new String(buffer,0,len)); //根据读取的数据的长度打印出数据内容,这样就把多余的缓存区的空格省略掉了 System.out.println(new String(buffer).trim()); //也可以直接使用trim()方法去掉空格,和上面一行代码效果相同 } catch (IOException e) { e.printStackTrace(); }finally { try { if(in!=null){ in.close(); //关闭流 } } catch (IOException e) { e.printStackTrace(); } }
(FileOutputStream)文件字节输出流和(FileInputStream)文件字节输入流结合使用的案例:
把一个文件的内容读出,然后存到存入另一个文件中
String path2="C://Users/wcl/Desktop/demo2.txt"; FileInputStream in=null; FileOutputStream out=null; try { in=new FileInputStream(path); out=new FileOutputStream(path2); byte[] buffer=new byte[1024]; int len; // while((len=in.read(buffer))!=-1){ //一直向数组中读取数据 // String s=new String(buffer).trim(); //先从byte数组中取出转化为String型 // out.write(s.getBytes(), 0, len); //再将字符串转换成byte型数据,写入文件中 // } len=in.read(buffer); //也可以先获取读取文件的长度 for (int i = 0; i < len; i++) { //然后for循环从byte数组中取出数据写入demo2.txt文件中,和上面的效果相同 out.write(buffer[i]); }
out.flush(); //把缓冲区内容强制写出,清空缓冲区,防止有剩余数据未写出 } catch (IOException e) { e.printStackTrace(); }finally { try { if(out!=null){ out.close(); } if(in!=null){ in.close(); } } catch (IOException e) { e.printStackTrace(); } }
使用字符输入流和字节输入流的操作和字节流基本相同,只不过字节流是以 byte 为基本单元,而字符流是以 char 为基本单元。
不过我们要注意一下两者使用的场景,一般当我们在处理 音频文件、图片 等类型的文件时,一般用字节流。而如果是处理中文内容的,最好使用字符流。
以下内容为从网上收集:
字符流处理的单元为2个字节的Unicode字符,分别操作字符、字符数组或字符串,而字节流处理单元为1个字节, 操作字节和字节数组。所以字符流是由Java虚拟机将字节转化为2个字节的Unicode字符为单位的字符而成的,所以它对多国语言支持性比较好!如果是 音频文件、图片、歌曲,就用字节流好点,如果是关系到中文(文本)的,用字符流好点.
所有文件的储存是都是字节(byte)的储存,在磁盘上保留的并不是文件的字符而是先把字符编码成字节,再储存这些字节到磁盘。在读取文件(特别是文本文件)时,也是一个字节一个字节地读取以形成字节序列.
字节流可用于任何类型的对象,包括二进制对象,而字符流只能处理字符或者字符串; 2. 字节流提供了处理任何类型的IO操作的功能,但它不能直接处理Unicode字符,而字符流就可以。