现在的位置: 首页 > 综合 > 正文

彻底学习Java IO

2013年01月09日 ⁄ 综合 ⁄ 共 3230字 ⁄ 字号 评论关闭

一直对java的io都心存畏惧。到了找工作的最后季节,fight!

流:用于处理设备上的数据。 用于处理设备上的数据。 用于处理设备上的数据。
IO 有具体的分类: 有具体的分类:
1,根据处理的数类型不同:字节流和字符流。
2,根据流向不同:输入流和输出流。
字符流的由来:
因为文件编码的不同,而有了对字符进行高效操作流象。 原理:其实就是基于字节流读取时,去查了指定的码表
字节流和字符流的区别:

1,字节流读取的时候,到一个就返回。

字符流使用了字节流读到一个或多个字节,去查指定的编码表,将查到的字符返回。
2,字节流可以处理所有类型数据如图片mp3、avi等。
而字符流只能处理字符数据。

结论:只要是纯文本数据,都要优先考虑字符流来处理。其他的都要使用字节流。

----------------------------------------------------------------------

IO体系,具备的功能就只有两个:读写

字符流的处理方式:

InputStream、OutputStream

字节流的处理方式:

Reader、Writer

在java中,子类类名的后缀通常是父类的名字。而前缀通常都表明了子类的功能。

读一个文本文件并打印:

package comz;

import java.io.File;
import java.io.FileReader;
import java.io.IOException;

public class T {
	public static void main(String[] args) throws IOException {
		FileReader r = new FileReader(new File("d:\\a.txt"));
		char[] cs = new char[500];
		int len = 0;
		int count = 0;
		while ((len = r.read(cs)) != -1) {
			count++;
			System.out.println(new String(cs, 0, len));
		}
		r.close();
		System.out.println(count);
	}
}

这里用到了FileReader。是按照字符流的方式处理的.--------------

下面说一下缓冲。

缓冲的存在是为了增强流的功能而存在的。所以建立缓冲区的时候首先要有流对象的存在。

其实缓冲内部还是用了流的功能,只不过是把读进来的数据暂时放在数组中存储罢了。

------------------

处理字符流的时候,使用的是char数组,在处理字节流的时候,使用的是byte数组    

 FileInputStream fis = new FileInputStream(new File("d:\\a.txt"));
		byte[] ss = new byte[1024];
		while (true) {
			int c = fis.read(ss);
			if (c == -1) {// 到达结尾
				break;
			} else {
				System.out.println(new String(ss));
		         }
		}

--------------------------------------

字节流可以处理任意的文件。比如说我们要copy一个图片,那么,可以
 

看bufferedinputstream的源码,

可以知道,虽然我们没有设置buffer的大小,这里默认了就是8192个byte了。

------------------------------------------------------------

下面是一个比较有意思的点。

---------------

在java的IO系统中,除了字节流和字符流之外,还存在把二者相互转换的功能。

具体就体现在:

InputStreamReader和OutputStreamWriter

这二者是字符流体系中的成员。

他们本身就是字符流,而又有转换功能,所以在构造的时候要传入字节流作为参数。

看二者的构造函数:

他们的构造函数都是传入一个字节流作为参数。

当然二者还有其他的构造函数,可以指定编码表等。

操作文件的字符流对象,是这些转换类的子类。看以下类结构:

转换流已经完成了编码转换的工作。所以对于直接操作文本文件的filereader来说,就不用再重新定义了!

所以,需要注意,在对文本文件进行操作的时候,是使用filereader,则使用的是默认编码表。如果要自己制定编码表,则必须使用转换流。

比如说,FileReader r = new FileReader(new File("d:\\a.txt"));

操作这个文件的时候使用的是系统默认的GBK编码。

如果a.txt中的数据是通过utf8编码的,那么就必须这样子来用:

InputStreamReader r=new InputStreamReader(new FileInputStream(new File("d:\\a.txt")),"UTF-8");

----------------------------------------

用于合并多个流的sequenceinputstream:

package comz;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.SequenceInputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;

public class T {
	public static void main(String[] args) throws IOException {
		ArrayList<InputStream> al = new ArrayList<InputStream>();

		al.add(new FileInputStream("d:\\" + 2 + ".txt"));
		al.add(new FileInputStream("d:\\" + 3 + ".txt"));
		al.add(new FileInputStream("d:\\" + 1 + ".txt"));

		Enumeration<InputStream> en = Collections.enumeration(al);
		SequenceInputStream sis = new SequenceInputStream(en);// 将三个数据源合并到一个数据源

		FileOutputStream fos = new FileOutputStream(new File("d:\\5.txt"));

		int len = 0;
		byte[] bu = new byte[1024];
		while ((len = sis.read(bu)) != -1) {
			fos.write(bu, 0, len);
		}

		sis.close();
		fos.close();

	}
}

--------------------

下面看一下DateInputStream。

在实习的时候做过C#版本的一个东西,内容就是使用流将界面上操作的东西保存起来。内容就是每次都保存一个int或者double或者是字符等。与DateInputStream的功能类似。
---------------------------------------------

这些操作数组的流对象,数据的源是内存,目的也是内存。

所以这些流在使用的时候不需要close。这几个流的出现,实际上就是以流的思想来操作数组而已。

-----------------------------

编码问题

tomcat服务器的默认编码是iso8859-1

-------------------------------

数据使用了什么样的编码方式进行编码,就需要用什么样的编码方式进行解码。

抱歉!评论已关闭.