IO编程之输入流
来源:互联网 发布:ubuntu如何卸载qq 编辑:程序博客网 时间:2024/04/30 16:02
------- android培训、java培训、期待与您交流! ----------
IO编程(1)
1 Input 输入概述
输入流分为字符流和字节流,计算机内部存贮的都是字节流,是字符流的底层,由于码表的存在,在字节数据的基础上进行包装得到字节流。主要的输入设备有键盘,磁盘,光盘等。数据的输入为程序提供初始化的数据,比如tomcat的服务器,用户通过配置文件的方法为 tomcat 设置内存上线等,而这些配置文件基本上位于磁盘上,因而需要将其从磁盘读取,这就需要用到 I/O编程了,当然I/O编程远远不止这些。
1.1 输出流的层次结构
1.2 字符数据的编码问题
ASCII 数据可以采用一个字节的方式就可以存贮,但是由于世界上的字符数据众多,一个字节难以全部表示,所以要拓展到用两个字节表示。全部用两个字节,就有些浪费空间。实际中,ASCII 采用一个字节表示,GBK等编码用两个字节表示。
2 字符输入流的基本用法
package cn.gxufe;import java.io.*;/** * Reader 的基本用法 * 演示读取单个字符,和多个字符的用法 * @author 荣英洁 */public class ReaderDemo {public static void main(String[] args) {//单个字符readSingleCharacter();//多个字符readPluralityCharacter();}/** * 读取单个字符 */public static void readSingleCharacter(){FileReader reader = null;try {//指定要读取的文件对象reader = new FileReader("E:/hm/aaa.txt");//出入所用到的字符集System.out.println("字符集编码:"+reader.getEncoding());int temp;//读到文件末尾,返回 -1 表示结束//读取到数据类型 int , 通过 强制类型转换(根据系统的码表查找)成 单个字符while((temp=reader.read())!=-1){System.out.print((char)temp);}} catch (Exception e) {e.printStackTrace();}finally{if(reader!=null)try {reader.close();} catch (IOException e) {e.printStackTrace();}}}/** * 读取多个字符 */public static void readPluralityCharacter(){FileReader reader = null;try {reader = new FileReader("E:/hm/aaa.txt");//出入所用到的字符集System.out.println("字符集编码:"+reader.getEncoding());//记录读取到的字符个数int len;//每次最多读取的字符数char b[] = new char[20];/** * 如果读取的到的字符长度为 0 表示没有可读数据 */while((len=reader.read(b))>0){System.out.print(new String(b,0,len));}} catch (Exception e) {e.printStackTrace();}finally{if(reader!=null)try {reader.close();} catch (IOException e) {e.printStackTrace();}}}}
2.2基于单个字符的读取,实现对字符数据逐行读取
package cn.gxufe;import java.io.File;import java.io.FileNotFoundException;import java.io.FileReader;import java.io.IOException;/** * 基于 字符流 FileReader 的单个字符读取方法, * 采用迭代模式实现,对数据进行读取 * @author 荣英洁 */public class MyReader{private FileReader fileReader = null;private String line="";public MyReader(File file) throws FileNotFoundException {fileReader = new FileReader(file);}public MyReader(String s) throws FileNotFoundException{fileReader = new FileReader(s);}public String getMyReadLine(){return this.line;}/** * 判断是否还有下一行数据 * @return */public boolean hasNextLine(){/** * window 系统的的换行符号是 \r\n 所以在遇到 ‘\r’字符时,继续循环 * 遇到'\n' 表示读取一行的数据结束 *///数据的缓存StringBuffer buffer = new StringBuffer();this.line = "";//记录每行读取到的数据int temp=0;//记录每次读取到的单个字符try {while((temp = fileReader.read())!=-1){char a = (char)temp;if(a=='\r')continue;else if(a=='\n'){line = buffer.toString();return true;}else{buffer.append(a);}}} catch (IOException e) {e.printStackTrace();try {this.close();} catch (IOException ea) {ea.printStackTrace();}}line = buffer.toString();if(line.equals("")){return false;}else{return true;}}public void close() throws IOException{if(this.fileReader!=null)this.fileReader.close();}}
3 字节输入流的用法
3.1 InputStream 的基本用法
package cn.gxufe;import java.io.*;/** * @author 荣英洁 * */public class InputSreamDemo {public static void main(String[] args) throws Exception {//单个字节的读取readSingleByte();System.out.println();//多个字节的读取readNumberBytes();}/** * 按照逐个字节的方式读取字符数据 * @throws Exception */public static void readSingleByte() throws Exception{InputStream inputStream = new FileInputStream("E:/hm/aaa.txt");/* *len=inputStream.read() 用于读取每次得到的字节数据 * 由 AScii 表可知 0-127 属于 AScii 字符数据 * 如果拿到的 int 数据不再这个范围,则表明是非 AScii 字符,即GBK编码。 * 而 AScii 采用一个字节,GBk用两个字节。 */int data;//用于保存读取到的 每个字节的数据byte b[] = new byte[2]; //用于保存读取的相邻的GBK数据的字节int i=0;//用户标记b 保存了几个数据while((data=inputStream.read())!=-1){// 大于 127 则说明是 GBK数据if(data>127){b[i] = (byte)data;if (i==1){System.out.print(new String(b));i=0;}else{i++;}}else{ // ASCII 数据System.out.print(((char)data));}}inputStream.close();}/** * 按照多个字节的方式读取字符数据 * @throws Exception */public static void readNumberBytes() throws Exception{InputStream inputStream = new FileInputStream("E:/hm/aaa.txt");int len;//用于保存读取到的 每个字节的数据byte data[] = new byte[4]; //用于保存读取的相邻的GBK数据的字节StringBuffer buffer = new StringBuffer();while((len=inputStream.read(data))>0){String s = new String(data,0,len);buffer.append(s);}System.out.println(buffer.toString());inputStream.close();}}
基于多个字节读取的方式,如果遇到中文,有可能会产生中文乱码问题,例如:所要读取的字符串 是 “fds股份 ” ,而每次读取四个字节,那么第一次读取的时,只能读到 “股” 的第一个字节,读不到第二个字节,这就引起了乱码,“fds股份 ” 采用上述基于多个字节的方式读取 会得到的结果是“fds?煞?”。要解决这个问题,就要注意所读取到的字节是否是 ASCII 数据。非 ASCII 就要用两个字节表示一个字符。
3.2 基于逐个字节数据的读取,实现对字符数据逐行读取
package cn.gxufe.input;import java.io.*;/** * 采用迭代模式,基于单个字节的读取,实现对数据逐行读取 * @author 荣英洁 */public class MyInputStream {public static void main(String[] args) throws FileNotFoundException {MyInputStream inputStream = new MyInputStream("E:/hm/aaa.txt");//判断是否有一行数据while (inputStream.hasLine()) {System.out.println(inputStream.getMyReadLine());}}private InputStream inputStream = null;private String line="";public MyInputStream(String path) throws FileNotFoundException{inputStream = new FileInputStream(path);}public MyInputStream(File file) throws FileNotFoundException{inputStream = new FileInputStream(file);}/** * 判断是否还有数据 * @return */public boolean hasLine(){StringBuffer buffer = new StringBuffer();line="";try {int temp;byte b[] = new byte[2];//中文字符,字节缓存区int i=0;while((temp = inputStream.read())!=-1){//读到有两个字节表示的非 ASCII 字符if(temp>127){b[i]=(byte)temp;if(i==1){i=0;buffer.append(new String(b));}elsei++;}//Ascii 字符else{if((char)temp =='\r')continue;if((char)temp =='\n'){this.line = buffer.toString();return true;}elsebuffer.append((char)temp);}}} catch (IOException e) {e.printStackTrace();}this.line = buffer.toString();if(!this.line.equals("")){return true;}return false;}/** * 返回当前行数据 * @return */public String getMyReadLine(){return this.line;}}
4 总结
通过对上述的基本操作,明白了数据的存储形式,以及底层的实现方式是基于对单个字节操作,在此基础上实现对字符的操作,为之后学习的各种包装流夯实了基础,以及加强了对编码了的理解。
0 0
- IO编程之输入流
- 【java编程】IO流之SequenceInputStream类合并输入流再输出
- Java IO之文件输入、输出流
- 黑马程序员---高级网络编程 io 输入,输出流
- 【java编程】IO流之管道流
- Java编程基础之IO流
- java编程之io流学习总结
- IO(输入流)
- IO流输出输入
- java io 输入流
- IO输出输入流
- Python之IO编程
- IO流基础之FileInputStream(输入流)
- IO之字节输入流FileOutputStream、字节输出流FileInputStream
- 初学Java,IO之推回输入流(四十四)
- java IO 学习小结之输入流InputStream
- java io系列23之 BufferedReader(字符缓冲输入流)
- IO之转换流与重定向标准输入/输出
- 【互动问答分享】第13期决胜云计算大数据时代Spark亚太研究院公益大讲堂
- javaee开发常用jar作用
- LinkedHashMap和HashMap的比较使用
- CodeSmith绿色化的情况下,又能使之正常工作
- 关于Python中的yield
- IO编程之输入流
- mysql (MySql Command Line Client) 保存数据后乱码
- 代码混淆
- 委托构造函数
- 深入理解java.lang.Runtime
- 9.png图片的处理
- Json转换报错java.lang.IllegalArgumentException的解决方案!
- 从头开始学习c语言
- Cocoa 框架 For iOS(二)对象的分配初始化、内省、单例