黑马程序员————java基础之Io一

来源:互联网 发布:魔法王座各种升阶数据 编辑:程序博客网 时间:2024/06/05 03:44

-Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------

IO流

IO流用来处理设备之间的数据传输。Java对数据的操作是通过流的方式。Java用于操作流的对象都在IO包中。
输入流和输出流相对于内存设备而言。
将外设中的数据读取到内存中:输入。
将内存的数写入到外设中:输出。
流按操作数据分为两种:字节流与字符流。
字符流简单说就是字节流加编码表

流的抽象基类
字节流的抽象基类:InputStream,OutputStream。
符流的抽象基类:Reader,Writer。
由这四个类派生出来的子类名称都是以其父类名作为子类名的后缀。
IO流常用基类-字符流
一般对于文件的操作都用的是字符流,特别是纯文本文件。字符流读取用Reader,写入用Writer,对于文件可操作的流是Filewrite

Writer具体步骤:
创建一个可以往文件中写入字符数据的字符输出流对象
既然是往一个文件中写入文字数据,那么在创建对象时,就必须明确该文件(用于存储数据的目的地)
如果文件不存在,则会自动创建
如果文件存在,则会被覆盖

FileWriter fw = new FileWriter("demo.txt" );
调用Writer对象中的write(string)方法,写入数据
其实数据写入到临时存储缓冲区中
fw.write( "abcde");
进行刷新,将数据直接写入到目的地中

fw.flush();
关闭流,关闭资源,在关闭前会先调用flush刷新缓冲中的数据到目的地。
fw.close()
注:close方法只能用一次。流关闭以后不能,不能再调用write方法,否则会报如下异常错误:

IO流是有异常的因此要对其进行简单处理这里,这里我们用try和catch对其进行捕获,用finally对流进行关闭。

Reader步骤:

这个分两种一种是定义一个int变量,一个字符的读

一种是定义一个数组作为容器然后一把读

创建一个字符输入流

FileReader fr =new Filereader();
用read方法去读

第一种:

int ch = 0; while((ch = fr.read()) != -1){ System.out.println(( char)ch); }
第二种

char[] buf = new char[3]; int len = 0;while((len = fr.read(buf)) != -1){ System.out.println( new String(buf,0,len)); }
关闭流:

fr.close();
文件简单的读写并加入异常:

public class CopyTextTest{private static final int BUFFER_SIZE = 1024;public static void main(String[] args){ FileReader fr = null;FileWriter fw = null; try{fr = new FileReader("demo.txt" );fw = new FileWriter("copytest_2.txt" ); //创建一个临时容器,用于缓存读取到的字符 char[] buf = new char[BUFFER_SIZE]; //定义一个变量记录读取到的字符数(其实就是往数组里装的字符个数) int len = 0;while((len = fr.read(buf)) != -1){ fw.write(buf,0,len);} } catch(Exception e){26. throw new RuntimeException("读写失败!"); } finally{ if(fw != null){try{ fw.close(); } catch(IOException e){ System.out.println(e.toString());}}if(fr != null){ try{ fw.close(); } catch(IOException e){ System.out.println(e.toString()); }} }} }

把读写综合起来分别创建对象,调用方法先读然后存入数组,在调用写的方法写入文件中

对于关闭流要两个都关闭finally内要try两次

字符流的缓冲区
缓冲区的出现提高了对数据的读写效率。
对应类:
BufferedWriter
BufferedReader
缓冲区要结合流才可以使用。
作用:在流的基础上对流的功能进行了增强。

public class CopyTextBufTest{ public static void main(String[] args) throws Exception { FileReader fr = new FileReader("buf.txt" ); BufferedReader bufr = new BufferedReader(fr); FileWriter fw = new FileWriter("buf_copy.txt" ); BufferedWriter bufw = new BufferedWriter(fw); String line = null; //方式一 while((line = bufr.readLine()) != null){ bufw.write(line); bufw.newLine(); 
bufw.flush(); } //方式二 /* int ch = 0; while((ch = bufr.read()) != -1){ bufw.write(ch); } */ bufr.close(); bufw.close(); } }
装饰设计模式
对原有类进行了功能的改变,增强。
和继承的区别:
如果这个体系需要再进行功能扩展,又多了更多流对象。这样就会发现只为提高功能,导致继承体系越来越臃肿,不够灵活。
装饰比继承灵活。
特点:装饰类和被装饰类都必须所属同一个接口或者父类。

IO流常用基类-字节流
基本操作与字符流类相同。但它不仅可以操作字符,还可以操作其他媒体文件。
程序的读写基本相同

写:

//1、创建字节输出流对象,用于操作文件 FileOutputStream fos = new FileOutputStream( "bytedemo.txt");
 //2、写数据,直接写入到了目的地中 fos.write( "abcdefg".getBytes()); //关闭资源动作要完成
 fos.close();
读:

//读取方式一public static void demo_read1() throws IOException { //1、创建一个读取流对象,和指定文件关联 FileInputStream fis = new FileInputStream("bytedemo.txt" ); //打印字符字节大小,不过要少用,文件太大,可能内存溢出 byte[] buf = new byte[fis.available()]; fis.read(buf); System.out.println( new String(buf)); fis.close(); } //读取方式二 public static void demo_read2() throws IOException { FileInputStream fis = new FileInputStream("bytedemo.txt" ); //建议使用这种读取数据的方式 byte[] buf = new byte[1024]; int len = 0; while((len = fis.read(buf)) != -1){ System.out.println( new String(buf,0,len)); } fis.close(); } //读取方式三 public static void demo_read3() throws IOException { FileInputStream fis = new FileInputStream("bytedemo.txt" ); //一次读取一个字节 int ch = 0; while((ch = fis.read()) != -1){ System.out.print(( char)ch); } fis.close(); } }
字节流的缓冲区:同样是提高了字节流的读写效率

转换流
转换流的由来:
字符流与字节流之间的桥梁
方便了字符流与字节流之间的操作
转换流的应用:
字节流中的数据都是字符时,转成字符流操作更高效。

转换流:
InputStreamReader:字节到字符的桥梁,解码。
OutputStreamWriter:字符到字节的桥梁,编码

BufferedReader bufr = new BufferedReader(newInputStreamReader(System.in)); BufferedWriter bufw = new BufferedWriter(newOutputStreamWriter(System.out)); String line = null; while((line = bufr.readLine()) != null){ if("over" .equals(line)) break; bufw.write(line.toUpperCase()); bufw.newLine(); bufw.flush(); } } }
对于不同读写可以在创建对象是更换。
流的操作规律
1、明确源和目的
源:InputStream Reader
目的:OutputStream Writer
2明确数据是否是纯文本数据
源:是纯文本:Reader
否:InputStream
目的:是纯文本:Writer
否:OutputStream
就可以明确需求中具体要使用哪个体系。
3、明确具体的设备
源设备:
硬盘:File
键盘:System.in
内存:数组
网络:Socket流
目的设备:
硬盘:File
控制台:System.out
内存:数组
网络:Socket流
4、是否需要其他额外功能
是否需要高效缓冲区:
是,就加上buffer
任何Java识别的字符数据使用的都是Unicode码表,但是FileWriter写入本地文件使用的是本地编码,也就是GBK码表。

而OutputStreamWriter可使用指定的编码将要写入流中的字符编码成字节。

public static void writeText() throws IOException { //下面这句代码等同于FileWriter fw = new FileWriter("b.txt"); //FileWriter其实就是转换流指定了本机默认码表的体现,而且这个转换流的子类对象,可以方便操作文本文件。 //简单说:操作文件的字节流+本机默认的编码表。 //这是按照默认码表来操作文件的便捷类 //OutputStreamWriter osw = new OutputStreamWriter(newFileOutputStream("d.txt"),"GBK"); //如果操作文本文件需要明确具体的码表,FileWriter就不行了,必须用转换流。 OutputStreamWriter osw = new OutputStreamWriter(newFileOutputStream("d.txt" ),"UTF-8" ); osw.write( "您好"); osw.close(); } }
什么时候使用转换流呢?
1、源或者目的对应的设备是字节流,但是操作的却是文本数据,可以使用转换作为桥梁,提高对文本
操作的便捷。
2、一旦操作文本涉及到具体的指定编码表时,必须使用转换流。








































0 0
原创粉丝点击