一、字节输出流OutputStream
-
OutputStream是抽象类,是表示输出字节流的所有超类,操作的数据都是字节,定义了字节输出流的基本共性和方法。OutputStream有大量子类,具体请看javaAPI文档,比较常用的是FileOutputStream 即:将数据写入到File的输出流。
注意:其中的方法close()方法和Flush()方法的不同,close()自带flush()方法,但是close()一旦使用就会关闭和释放该流的所有资源,即这个流不能再使用了。flush()则是强制写出所有缓冲的所有字节,即将数据强制从缓冲中写入到文档中。
-
FileOutputStream有哪些用处
1、可以往指定的文件里写东西.
2、可以给文档内容进行续写和换行处理,换行符为\r\n添加字符的前面 -
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(""); } } } } }
-
OutputStream字节输出流和File类的区别:
区别有:
1、File类是针对文件路径的,有以下功能,可以创建删除一个文件,可以对文件进行copy,可以调取文件的路径,文件名,文件大小,可以将路径下的所有文件放到一个数组里面,可见File类就是对文件和路径的操作,如果往文档里插入一些内容或续写一些数据是不行的。
2、OutputStream是对文档的操作,专门用于向文档里输入数据的。
#二、字节输入流InputStream
-
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
-
Reader
Reader是抽象类,Reader的直接子类有InputStreamReader,它的直接子类有FileReader.这表明Reader是字符输入流的祖宗类。
-
Writer
Writer是抽象类,Writer的直接子类有OutputStreamWriter,它的直接子类有FileWriter.这表明Writer字符输出流的子类。
#四、字符流和字节流的区别:
-
字节流是以字节为单位传递的,因为所有电脑上的东西都是二进制字节,因此可以传递任何数据,比如图片,各种字符等。字节流只能写入字节,读取字节。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(); } }
可见字节流是通过字节码的方式读取和输入的。必须通过字节码的形式进行写入和读取。
-
字符流的运用
加入有一个文本文档里面存储的是字节码,你要打印里面的内容,也就是读取到控制台上,你总不能用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个字节。因此字符流是根据字符所占字节大小而决定读取多少字节的。这就是字符流和字节流的本质不同。