java常用到的知识点总结之IO流

原创 2016年08月31日 15:25:23

IO流:
IO流在java中是会经常用到的,下面对IO流做一个总结。今天主要介绍IO流中的字节流、字符流、转换流、对象流。

首先我们来看字节流,字节流就是对字节进行操作的流对象,对字节进行操作的流对象的基类有两个,一个是InputStream(字节输入流),另外一个是OutputStream(字节输出流).
下面我们来看看这两种流的使用:
首先看InputStream,由于InputStream是一个抽象类,不能够创建对象,所以这里我借助FileInputStream这个类来对一个文件进行读取,FileInputStream是InputStream的一个子类。
public static void main(String[] args) {
		InputStream is = null;
		try {
			is = new FileInputStream("a.txt");
			int len = -1;
			while ((len = is.read()) != -1) {
				System.out.println((char) len);
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (is != null) {
				try {
					is.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
见如上代码:我们能够知道在java Project的项目根目录中有一个a.txt的文件,定义了一个int类型的变量len,然后使用while循环,循环的条件是(len=is.read())!=-1,输入流读取数据的时候,read()读取到的是当前字节所对应的int值,如果到文件的末尾也就是流的末尾的时候就返回-1,接着我们将len转换为char类型就可以看到文件中的内容了。
对于读取到的内容要注意,很多初学者有疑问,我使用字节流去读文件,为什么汉子部分都是?号,英文和数字却是完好无损的,因为英文和数字都只占一个字节,而汉子的话占用2个字节,UTF-8码表中的汉子更是占三个字节。当我们一个字节一个字节地读的话,那么汉字显然就被拆分了,在ASCII码表中查找不到就显示?号了。
那么如果我们一定要字节流能够读取汉字而且能够完好无损地显示该怎么办呢?看如下代码:
<span style="white-space:pre">			</span>..........................
<span style="white-space:pre">			</span>is = new FileInputStream("a.txt");
			int len = -1;
			byte[] bt = new byte[1024];
			while ((len = is.read(bt)) != -1) {
				System.out.println(new String(bt,0,len));
			}
<span style="white-space:pre">			</span>................................

我们可以看到修改的部分,使用InputStream的read方法的一个重载方法read(byte[] b):
参数:b - 存储读入数据的缓冲区。 返回:读入缓冲区的总字节数;如果因为已经到达流末尾而不再有数据可用,则返回 -1。 这样我们的字节数组定义为1024个字节,那么文件中根本达不到1024个字节,所以可以一次性读取出来,然后通过转换成字符串输出这样就可以将汉字完整输出了,因为汉字并没有被拆分。如果文件中的内容大于1024个字节的话,while循环就会进行两次,就会造成换行输出,也就是输出两行。
接着看OutputStream,OutputStream是字符输出流,输出意味着它能够将一些数据输出出去,由于OutputStream也是抽象类不能够创建对象,所以利用多态采用FileOutputStream为例。
public static void main(String[] args) {
		OutputStream os = null;
		try {
			os = new FileOutputStream("b.txt");
			os.write("呵呵\n".getBytes());
			os.write(97);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (os != null) {
				try {
					os.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}

通过上面代码我们可以看到,os = new FileOutputStream("b.txt");我们操作的是项目目录下的文件b,如果在write的时候该文件不存在就会自动创建,如果文件存在就write,但是会将文件之前的内容覆盖掉,如果让它不覆盖呢,我们就使用FileOutputStream(String name,boolean append);这个重载的构造方法,后面的一个布尔值的参数代表是否追加内容。传入true代表追加,不覆盖,false代表不追加 就覆盖。这样我们可以利用os.write()方法对字节或者是字节数组进行写入,这里我们可以写汉字,ASCII表所对应的内容,写汉字时需要将String转换为字节数组写入。
下面我们来接触一下字符流:字符流很显然,可以读取或者写入字节,它们对应的基类是 Writer和Reader,继承自它们的有FileReader和FileWriter.下面来看一下FileReader:
public static void main(String[] args) {
		FileReader reader = null;
		try {
			reader = new FileReader("b.txt");
			char c = (char)reader.read();
			System.out.println(c);;
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (reader != null) {
				try {
					reader.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
代码中使用的是字符流FileReader,它一次可以读取一个字符,所以char c = (char)reader.read();若读取的是汉字转换成字符后也不会变成问号。下面看一下FileWriter
<span style="font-weight: normal;"><span style="white-space:pre">		</span>FileWriter writer = null;
		try {
			writer = new FileWriter("b.txt");
			writer.write("字符流");
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (writer != null) {
				try {
					writer.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}</span>
代码中FileWriter作为字符流,能够直接写出一个字符串,因为字符串也就是一个字符数组。字符流相对于字节流要方便很多。
字符流中最后为大家介绍两种高效流,为什么说他们高效呢?是因为它们在内存中存在一个缓存区,它们分别是BufferedWriter和BufferedReader,和上面两个方法的不同之处在于他们多了两个方法,BufferedWriter拥有newLine()可以换一行,BufferedReader可以readLine()可以一行一行地读取。

转换流:InputStreamReader和OutputStreamWriter.转换流的作用:转换流有两个作用,1.它可以将一个字节流转换为字符流。2.它们在读取或者写入的时候可以指定编码方式。我们来看看InputStreamReader和OutputStreamWriter.
public static void main(String[] args) {
		InputStreamReader reader = null;
		try {
			reader = new InputStreamReader(new FileInputStream("b.txt"));
			int len = -1;
			while((len = reader.read())!=-1){
				System.out.println((char)len);
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (reader != null) {
				try {
					reader.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
通过上面的代码,我们看到InputStreamReader可以读出来的内容转换为char类型,就算是汉字也不会变成?,说明它就是按照字符进行读取的,这就证明了它将FileInputStream字节流转换成了字符流,当然它也可以将内容读取到一个char数组中,原理是和字节流读取到字节数组中一样的。reader = new InputStreamReader(new FileInputStream("b.txt"),"utf-8");可以指定读取时的编码。下面看看字符输出流:
OutputStreamWriter writer = null;
		try {
			writer = new OutputStreamWriter(new FileOutputStream("b.txt"));
			writer.write("字符流");
上面代码看到,字符输出流可以直接输出一个字符串,我们知道字符串也就是一个字符数组,所以它能够直接输出一个字符串是正常的。证明OutputStreamWriter将FileOutputStream转换成了字符流。writer = new OutputStreamWriter(new FileOutputStream("b.txt"),"utf-8");可以指定输出内容的编码格式。
对象流:ObjectOutputStream、ObjectInputStream
对象流其实就是将一个对象转换成流的形式,和将一个流转换为对象。这就需要对象能够进行序列化。那么一个对象如何能够进行序列化和反序列化呢?我们需要了解一个接口,这个接口是标记接口,它是Serializable接口,为什么说它是标记接口呢?因为它的内部什么都没有,它只起到标记的作用,实现了它的类就代表能够被序列化和反序列化。下面我们需要将一个对象以流的形式存入文件中,具体看代码:
public class Test {
	public static void main(String[] args) throws Exception{
		Person p = new Person("张三",15);
		ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("file.txt"));
		oos.writeObject(p);
		
		ObjectInputStream ois = new ObjectInputStream(new FileInputStream("file.txt"));
		Person p1 = (Person) ois.readObject();
		System.out.println(p1);
		oos.close();
		ois.close();
	}
}

class Person implements Serializable{
	public String name;
	public int age;
	public Person(String name, int age) {
		this.name = name;
		this.age = age;
	}
	@Override
	public String toString() {
		return "Person [name=" + name + ", age=" + age + "]";
	}
}
代码中Person类实现了Serializabale接口,代表它可以被序列化,这样我们就可以实例化一个ObjectOutputStream,调用其writeObject方法将Person对象p,写入带文件file.txt中。也可以实例化一个ObjectInputStream将其从文件中读取出来,readObject()方法返回的是一个Object对象,这里我们知道其实他就是Person对象,所以我们可以使用多态的向下转型,将其转换成Person对象,最终输出结果是Person [name=张三, age=15]。
好了今天IO流就总结这些吧!





版权声明:本文为博主原创文章,未经博主允许不得转载。

java中IO流的知识点总结

1.流的概念流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象。即数据在两设备间的传输称为流,流的本质是数据传输,根据数据传输特性将流抽象为各种类,方便更直观的进行数据操作。2.IO流...
  • u011626964
  • u011626964
  • 2015年09月01日 10:39
  • 7263

java常用API知识点总结

黑马程序员_JAVA常用类API(StringBuffer类,数组高级应用,包装类  34人阅读 评论(0) 收藏 举报 ------- android培训、java培训、期待与您交流!---...
  • zhuimengtianya33
  • zhuimengtianya33
  • 2015年08月22日 19:47
  • 1441

Java中的IO流总结

Java中的IO流总结 1. 流的继承关系,以及字节流和字符流。 2. 节点流FileOutputStream和FileInputStream和处理流BufferedInputStream和Bu...
  • u013309870
  • u013309870
  • 2016年08月03日 20:03
  • 1011

Java基础--常用API的总结

1.  Math  2.  Object  3.  Scanner  4.  String---正则表达式---Pattern类,Matcher类  5.  Arrays  6.  Stri...
  • u013905744
  • u013905744
  • 2015年03月23日 13:36
  • 361

最完整的Java IO流学习总结

一、 File类 1、 java.io.File 类是专门对文件进行操作的类。(只能对文件本身进行操作,不能对文件内容操作) 2、 File类是“文件和目录路径名的抽象表示”。 而不是指文件的内容...
  • SilenceOO
  • SilenceOO
  • 2016年03月28日 00:37
  • 595

java IO流学习总结

Java中的流,可以从不同的角度进行分类。     按流的方向分:输入流和输出流。     按处理数据单位分:字节流和字符流。     按实现功能分:节点流和处理流。       输出流:     ...
  • du_minchao
  • du_minchao
  • 2015年10月11日 12:35
  • 16127

Java IO流知识点总结

本主要对java的IO流知识点做比较全面的总结,但是没有很深入阐述。
  • wenzhi20102321
  • wenzhi20102321
  • 2016年09月18日 13:55
  • 1174

IO流总结(基础知识)

IO这章的知识在上面一篇博客也说过一点,主要要体会一下装饰者设计模式和适配器设计模式,这样更利于我们理解复杂的IO体系结构。今天就让我们看一看。不过在讲IO 之前,我们先把文件(File)的知识简单过...
  • u013263323
  • u013263323
  • 2015年05月26日 09:58
  • 981

Java中IO流学习总结

Java中IO流学习总结一.IO流中的结构 字符流:顾名思义,该流只能处理字符,但处理字符速度很快 字节流:可以处理所有以bit为单位储存的文件,也就是说可以处理所有的文件,但是在处理字符上的速度不如...
  • Yue_Chen
  • Yue_Chen
  • 2017年05月26日 18:00
  • 379

Java中常见的IO流及其使用

Java中常见的IO流的介绍及使用: ByteArrayInputStream & ByteArrayOutputStream FileInputStream & FileOutputStream P...
  • sunqunsunqun
  • sunqunsunqun
  • 2015年07月09日 19:54
  • 4112
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:java常用到的知识点总结之IO流
举报原因:
原因补充:

(最多只允许输入30个字)