Java基础日记———IO流(上)
来源:互联网 发布:网络信用卡 编辑:程序博客网 时间:2024/06/03 13:06
一.概述
1.IO流用来处理设备之间的数据传输 。
2.Java对数据的操作是通过流的方式。
3.Java用于操作流的对象都在IO包中。
4.流按操作数据分为两种:字节流与字符流。
编码表进程:ASCII–>GB2312(中)–>GBK(中)–>Unicode(各个国家的进行重新编排,两个字节表示)–>UTF-8
–>仅为时间关系,不含其他。各个表的编码方式不同。
字符流就是为了适应编码表的多样化,可以指定处理文字是按照的编码表。
5.流按流向分为:输入流,输出流。
IO流常用基类:
字节流抽象基类:InputStream,OutputStream
字符流抽象基类:Reader,Wirter
由这四个类派生出来的子类名称都是以其父类名作为子类名的后缀。
二.IO体系
1.字符流
(1)抽象类write:创建并写入文件。以操作文本文件来演示:FileWriter
①writer写文件
代码示例:
FileWriter fw = new FileWriter("demo.txt");//创建一个FileWriter对象,并且对象一被初始化必须明确要操作的文件。 fw.write("asdasdasd");//调用write方法。 fw.flush();//刷新缓冲区,将数据存入“目的地” fw.close();//关闭流资源(必需操作)。
注意点:
FileWriter初始化文件后将会创建到指定的目录下,如果该目录下存在该文件,那么原文件将会被覆盖。
flush和close的区别:flush只是刷新缓冲区,流可以继续使用;但是,close操作在刷新缓冲区后,将会关闭流资源。
②续写文件:
FileWriter(String fileName, boolean append):根据给定的文件名以及指示是否附加写入数据的 boolean 值来构造 FileWriter 对象。
代码示例:
FileWriter fw = new FileWriter("demo.txt",true);
③异常处理: 第一种直接抛出异常:throws IOException; 第二种使用try/catch:
FileWriter fw = null; //在这里声明是因为这样finally中才不报错。 try { fw = new FileWriter("demo.txt"); fw.write("abcdefg"); } catch (IOException e) { System.out.println("catch:"+e.toString()); } finally { try { if(fw!=null) //为了健壮性,判断fw是否为空 fw.close(); //必须操作,可以放在finally中 } catch (IOException e) { System.out.println(e.toString()); } }
(2)抽象类Reader:读文件①读文件读取方式一
代码示例:
FileReader fr = new FileReader("demo.txt"); //创建对象 int c= 0; while((c = fr.read())!=-1){ System.out.print((char)c); } fr.close();
注意点:
创建一个文件读取流对象,需要和指定名称的文件相关联。而且保证文件存在,否则报错。
read():一次读一个字符。而且会自动往下读。
read的返回值:作为整数读取的字符,范围在 0 到 65535 之间 (0x00-0xffff),如果已到达流的末尾,则返回 -1 。
读取方式二:通过字符数组进行读取。
FileReader fr = new FileReader("demo.txt"); char[] buf = new char[1024]; int num = 0; while((num=fr.read(buf))!=-1) { System.out.println(new String(buf,0,num)); } fr.close();
注意点: 定义一个字符数组。用于存储读到的字符。 该read(char[])返回的是读到字符个数即定义时char的个数,读到最后会返回-1。
小例子
·复制文件主要代码示例:
FileReader fr2 = new FileReader("demo.txt"); FileWriter fw = new FileWriter("F:\\demo3.txt"); char[] ch = new char[2048]; while(fr2.read(ch)!=-1){ fw.write(ch); } fr2.close(); fw.close();
(3)字符流缓冲区
目的:缓冲区是为了提高流的读取效率,所以没有空参数的构造函数。而且创建缓冲区前必须要先有流对象。
原理:缓冲区对象里封装了数组,先把数据存储起来编程一个对象,在进行读写。
①BufferWreiter
代码示例:
FileWriter fw = new FileWriter("buf.txt"); //创建一个字符写入流对象 BufferedWriter bufw = new BufferedWriter(fw); //将流对象传递给缓冲区构造函数即可 bufw.write("asdas\r\ndasd"); //写入操作 bufw.flush();//写入都要刷新 bufw.close();//关闭的是缓冲区的流对象,所以不用fw.close();
特有方法: newLine():写入一个行分隔符。 方便跨平台使用:在windows中换行是\r\n,而Linux中是\r。
②BufferReader
FileReader fr = new FileReader("buf.txt"); //创建一个读取流对象 BufferedReader bubr = new BufferedReader(fr); String s = null; while((s=bubr.readLine())!=null){ System.out.println(s); } bubr.close();
特有方法: readLine():读取一行。 readLine读取的返回值是String类型,当返回null是为文件的结尾。 readLine只返回回车符之前的内容,并不包含每行的结尾换行符。③装饰设计模式: 当想要对已有的对象进行功能增强时, 可以定义类,将已有对象传入,基于已有的功能,并提供加强功能。 那么自定义的该类称为装饰类。 装饰类通常会通过构造方法接收被装饰的对象。 并基于被装饰的对象的功能,提供更强的功能。装饰类设计模式与继承的区别: MyReader//专门用于读取数据的类。 |--MyTextReader |--MyBufferTextReader |--MyMediaReader |--MyBufferMediaReader |--MyDataReader |--MyBufferDataReader class MyBufferReader { MyBufferReader(MyTextReader text) {} MyBufferReader(MyMediaReader media) {} } 上面这个类扩展性很差。 找到其参数的共同类型。通过多态的形式。可以提高扩展性。 class MyBufferReader extends MyReader { private MyReader r; MyBufferReader(MyReader r) {} } MyReader//专门用于读取数据的类。 |--MyTextReader |--MyMediaReader |--MyDataReader |--MyBufferReader 以前是通过继承将每一个子类都具备缓冲功能。 那么继承体系会复杂,并不利于扩展。 现在优化思想。单独描述一下缓冲内容。 将需要被缓冲的对象。传递进来。也就是,谁需要被缓冲,谁就作为参数传递给缓冲区。 这样继承体系就变得很简单。优化了体系结构。 装饰模式比继承要灵活。避免了继承体系臃肿。 而且降低了类于类之间的关系。 装饰类因为增强已有对象,具备的功能和已有的是相同的,只不过提供了更强功能。 所以装饰类和被装饰类通常是都属于一个体系中的。
包装类示例:
LineNumberReader(Reader in):使用默认输入缓冲区的大小创建新的行编号 reader。
2.字节流 字符流也是字节流,只有多了一个字符的编码表。 与字节流类似,相同部分只代码示例;不同部分会重点介绍。(1)OutputStream:字节输出流
代码示例:
FileOutputStream fos = new FileOutputStream("fos.txt"); fos.write("abcde".getBytes()); //不用刷新 fos.close();
(2)InputStream:字节输入流
代码示例:
FileInputStream fis = new FileInputStream("fos.txt"); int ch = 0; while((ch=fis.read())!=-1) { System.out.println((char)ch); } fis.close();
上面的例子是一个一个读字节,比较麻烦。 可以对其进行修改:定义一个换成数组,一个数组一个数组的往外读取(也就是缓冲区): byte[] buf = new byte[1024]; int len = 0; while((len=fis.read(buf))!=-1) { System.out.println(new String(buf,0,len)); }特有方法: available():返回此输入流下一个方法调用可以不受阻塞地从此输入流读取(或跳过)的估计字节数。通俗来讲也就是返回文件的字节数,包括回车符等。(3)字节流缓冲区
代码示例:
BufferedInputStream bufis = new BufferedInputStream(new FileInputStream("c:\\0.mp3")); BufferedOutputStream bufos = new BufferedOutputStream(new FileOutputStream("c:\\1.mp3")); int by = 0; while((by=bufis.read())!=-1) //返回值是int类型而字符流缓冲区读一行时返回的是String类型 { bufos.write(by); } bufos.close(); bufis.close();
3.读取键盘录入 (1)通过刚才的键盘录入一行数据并打印其大写,发现其实就是读一行数据的原理。也就是readLine方法。 readLine方法是字符流BufferedReader类中的方法。而键盘录入的read方法是字节流InputStream的方法。 那么可以将字节流转换为字符流进行操作,同时方便对字符流操作可以使用缓冲区。 字节流与字符流之间的桥梁:Reader的子类: InputStreamReader(InputStream in):创建一个使用默认字符集的 InputStreamReader。 OutputStreamWriter(OutputStream out):创建使用默认字符编码的 OutputStreamWriter 获取键盘录入对象。 InputStream in = System.in; 将字节流对象转成字符流对象,使用转换流。InputStreamReader InputStreamReader isr = new InputStreamReader(in); 为了提高效率,将字符串进行缓冲区技术高效操作。使用BufferedReader BufferedReader bufr = new BufferedReader(isr); 可以合为一句,即成为键盘录入最常见的写法:BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in)); 输出与之类似就是:BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(System.out));
代码示例:
BufferedReader bf = new BufferedReader(new InputStreamReader(System.in)); BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out)); String line = null; while((line=bf.readLine())!=null){ bw.write(line.toUpperCase()); bw.newLine(); bw.flush(); } bf.close(); bw.close(); }
(2).最简单,最强大的,就是用Scanner类
public static void main(String [] args) { Scanner sc = new Scanner(System.in); System.out.println(“请输入你的姓名:”); String name = sc.nextLine(); System.out.println(“请输入你的年龄:”); int age = sc.nextInt(); System.out.println(“请输入你的工资:”); float salary = sc.nextFloat(); System.out.println(“你的信息如下:”); System.out.println(“姓名:”+name+“\n”+“年龄:”+age+“\n”+“工资:”+salary); }
4.流操作的基本规律: 最痛苦的就是流对象有很多,不知道该用哪一个。 通过三个明确来完成。(1)明确源和目的。 源:输入流。InputStream Reader 目的:输出流。OutputStream Writer。(2)操作的数据是否是纯文本。 是:字符流。 不是:字节流。(3)当体系明确后,在明确要使用哪个具体的对象。 通过设备来进行区分: 源设备:内存,硬盘。键盘 目的设备:内存,硬盘,控制台。举例:(1)将一个文本文件中数据存储到另一个文件中。复制文件。 源:因为是源,所以使用读取流。InputStream Reader 是不是操作文本文件。 是!这时就可以选择Reader 这样体系就明确了。 接下来明确要使用该体系中的哪个对象。 明确设备:硬盘。上一个文件。 Reader体系中可以操作文件的对象是 FileReader 是否需要提高效率:是!加入Reader体系中缓冲区 BufferedReader. FileReader fr = new FileReader("a.txt"); BufferedReader bufr = new BufferedReader(fr); 目的:OutputStream Writer 是否是纯文本 是!Writer 设备:硬盘,一个文件。 Writer体系中可以操作文件的对象FileWriter 是否需要提高效率:是! 加入Writer体系中缓冲区 BufferedWriter FileWriter fw = new FileWriter("b.txt"); BufferedWriter bufw = new BufferedWriter(fw);(2)需求:将键盘录入的数据保存到一个文件中。 这个需求中有源和目的都存在。 那么分别分析 源:InputStream Reader 是不是纯文本?是!Reader 设备:键盘。对应的对象是System.in. 不是选择Reader吗?System.in对应的不是字节流吗? 为了操作键盘的文本数据方便。转成字符流按照字符串操作是最方便的。 所以既然明确了Reader,那么就将System.in转换成Reader。 用了Reader体系中转换流,InputStreamReader InputStreamReader isr = newInputStreamReader(System.in); 需要提高效率吗?需要!BufferedReader BufferedReader bufr = new BufferedReader(isr); 目的:OutputStream Writer 是否是存文本?是!Writer。 设备:硬盘。一个文件。使用 FileWriter。 FileWriter fw = new FileWriter("c.txt"); 需要提高效率吗?需要。 BufferedWriter bufw = new BufferedWriter(fw);
- Java基础日记———IO流(上)
- Java基础日记———IO流(下)
- 【java基础】——IO流(上)
- Java基础——IO流(上)
- 黑马程序员——学习日记15 java IO流 (上)
- 黑马程序员——Java基础->IO流(上)
- Java基础——IO流(上)之字符流
- 黑马程序员——Java基础---IO(输入输出)(上)
- 黑马程序员——java基础---IO(上)
- 黑马程序员-JAVA基础学习日记八——IO流的学习总结
- 黑马程序员——基础学习日记(IO流)
- 黑马程序员--java基础日记--IO流
- Java基础日记———Java的三大特性(上)
- Java基础—IO流
- java基础—-IO流
- java基础—IO流
- java基础—IO流
- Java基础——IO(流)
- NFinal AJAX返回
- OpenGL ES 入门
- vs2010打开资源视图
- VC编译时出现 cannot open file '.'.\Debug\Test1.sbr': No such file or directory 怎么关闭Browser Info
- wince隐藏任务栏与去除桌面图标 快捷方式
- Java基础日记———IO流(上)
- 一切成功源于积累——20150706 外汇经典之跳空窗口回补 欧美跳空 窗口回补 二回目
- 解决警告“ld: warning: directory not found for option”
- 编码方式
- Error:(24, 13) Failed to resolve: com.android.support:recyclerview-v7:20.+ <a href="install.m2.repo"
- 使用ORACLE在线重定义将普通表改为分区表
- Linux的test命令
- Oracle 表被其他的 过程/视图 引用
- 将16进制字符串转换为整数输出