JavaSE第九十五讲:Java字符流详解 续

    在上一讲中我们讲解了FileReader,这一讲我们开始学习FileWriter,即向文件中写入字符

1.  FileWriter

1)FileWriter 创建一个可以写文件的Writer 类。 FileWriter继承于OutputStreamWriter.

它最常用的构造方法如下:

FileWriter(String filePath)
FileWriter(String filePath, boolean append)
FileWriter(File fileObj)
append :如果为 true,则将字节写入文件末尾处,而不是写入文件开始处

2) 它们可以引发IOException或SecurityException异常。这里,filePath是文件的完全路径,fileObj是描述该文件的File对象。如果append为true,输出是附加到文件尾的。

3)FileWriter类的创建不依赖于文件存在与否。在创建文件之前,FileWriter将在创建对象时打开它来作为输出。如果你试图打开一个只读文件,将引发一个IOException异常

4) 程序Demo

package com.ahuier.io2;

import java.io.FileWriter;
import java.io.IOException;

public class FileWriter1 {
	public static void main(String[] args) throws Exception {
		String str = "hello world welcome nihao hehe";

		// 要想使用FileWriter,它操纵的字符或者字符数组。而非上诉的字符串.所以要进行以下转换

		// 构造一个字符数组
		char[] buffer = new char[str.length()];
		/*
		 * 查看JDK String类里面的getChars()方法 字符串转换为数组
		 */
		str.getChars(0, str.length(), buffer, 0); // 此时字符数组buffer装的是字符串str了

		FileWriter f = new FileWriter("file2.txt");
		for (int i = 0; i < buffer.length; i++) {
			f.write(buffer[i]); // 将字符数组写到file2.txt文件中
		}
		f.close();
	}
}

编译执行结果,工程目录下生成file2.txt文件,打开显示字符串:hello world welcome nihao hehe

4. CharArrayReader类似字节流中的ByteArrayInputStream

1)CharArrayReader 是一个把字符数组作为源的输入流的实现。该类有两个构造方法,每一个都需要一个字符数组提供数据源

CharArrayReader(char array[ ])
CharArrayReader(char array[ ], int start, int numChars)
这里,array是输入源。第二个构造方法从你的字符数组的子集创建了一个Reader,该子集以start指定的索引开始,长度为numChars

2) 程序Demo:

package com.ahuier.io2;

import java.io.CharArrayReader;
import java.io.IOException;

public class CharArrayReaderTest {
	public static void main(String[] args) throws Exception {
		String tmp = "abcsefg";
		char[] ch = new char[tmp.length()];

		tmp.getChars(0, tmp.length(), ch, 0);
		CharArrayReader input = new CharArrayReader(ch);
		int i;
		while (-1 != (i = input.read())) {
			System.out.println((char) i);
		}
	}
}

编译执行结果输出:

abcsefg

说明】:该例子用到了上述CharArrayReader的两个构造方法

public void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin)

    将字符从此字符串复制到目标字符数组。 要复制的第一个字符在索引 srcBegin 处;要复制的最后一个字符在索引 srcEnd-1 处(因此要复制的字符总数是 srcEnd-srcBegin)。要复制到 dst 子数组的字符从索引 dstBegin 处开始,并结束于索引:dstbegin + (srcEnd-srcBegin) - 1

5. CharArrayWriter

CharArrayWriter 实现了以数组作为目标的输出流。CharArrayWriter 有两个构造方法

1)CharArrayWriter( )
2)CharArrayWriter(int numChars)
3)第一种形式,创建了一个默认长度的缓冲区。
4)第二种形式,缓冲区长度由numChars指定。缓冲区保存在CharArrayWriter的buf 成员中。缓冲区大小在需要的情况下可以自动增长。缓冲区保持的字符数包含在CharArrayWriter的count 成员中。buf 和count 都是受保护的域 (protected)

这边就不再举例子了,它与上面是反过来的

6. BufferedReader[带缓冲功能的]

1)BufferedReader 通过缓冲输入提高性能。它有两个构造方法

BufferedReader(Reader inputStream)
BufferedReader(Reader inputStream, int bufSize)
第一种形式创建一个默认缓冲区长度的缓冲字符流。第二种形式,缓冲区长度由bufSize传入

2)和字节流的情况相同,缓冲一个输入字符流同样提供支持可用缓冲区中流内反向移动的基础。为支持这点,BufferedReader 实现了mark()和reset()方法,并且BufferedReader.markSupported()返回true

7. BufferedWriter

1)BufferedWriter是一个增加了flush()方法的Writer。flush()方法可以用来确保数据缓冲区确实被写到实际的输出流。用BufferedWriter 可以通过减小数据被实际的写到输出流的次数而提高程序的性能。

2) BufferedWriter有两个构造方法:

BufferedWriter(Writer outputStream)
BufferedWriter(Writer outputStream, int bufSize)
第一种形式创建了使用默认大小缓冲区的缓冲流。第二种形式中,缓冲区大小是由bufSize参数传入的

8.字符集的编码

1)ASCII(American Standard Code for Information Interchange,美国信息互换标准代码),是基于常用的英文字符的一套电脑编码系统。我们知道英文中经常使用的字符、数字符号被计算机处理时都是以二进制码的形式出现的。这种二进制码的集合就是所谓的ASCII码。每一个ASCII码与一个8位(bit)二进制数对应。其最高位是0,相应的十进制数是0-127。如,数字“0”的编码用十进制数表示就是48。另有128个扩展的ASCII码,最高位都是1,由一些制表符和其它符号组成。ASCII是现今最通用的单字节编码系统。["a" 表示的97 "A"表示的是65]

2)GB2312[国标码]:GB2312码是中华人民共和国国家汉字信息交换用编码,全称《信息交换用汉字编码字符集-基本集》。主要用于给每一个中文字符指定相应的数字,也就是进行编码。一个中文字符用两个字节的数字来表示,为了和ASCII码有所区别,将中文字符每一个字节的最高位置都用1来表示。

3)GBK[国标码的扩展]:为了对更多的字符进行编码,国家又发布了新的编码系统GBK(GBK的K是“扩展”的汉语拼音第一个字母)。在新的编码系统里,除了完全兼容GB2312外,还对繁体中文、一些不常用的汉字和许多符号进行了编码。

4)ISO-8859-1:是西方国家所使用的字符编码集,是一种单字节的字符集 ,而英文实际上只用了其中数字小于128的部分。[在网页开发中用的比较多,这个码表示不了中文,根据所需要修改成中文支持的]

5)Unicode:这是一种通用的字符集,对所有语言的文字进行了统一编码,对每一个字符都用2个字节来表示,对于英文字符采取前面加“0”字节的策略实现等长兼容。如 “a” 的ASCII码为0x61,UNICODE就为0x00,0x61。(在internet上传输效率较低)
6) UTF-8:Eight-bit UCS Transformation Format,(UCS,Universal Character Set,通用字符集,UCS 是所有其他字符集标准的一个超集)。一个7位的ASCII码值,对应的UTF码是一个字节。如果字符是0x0000,或在0x0080与0x007f之间,对应的UTF码是两个字节,如果字符在0x0800与0xffff之间,对应的UTF码是三个字节(汉字为3个字节)[这种表示方式最广,使用最多,它包含了所有国家的语言,一些大的公司都是用这种编码方式的]

7) 程序Demo

package com.ahuier.io2;

import java.util.Properties;

public class CharSet {
	public static void main(String[] args) {
		Properties p = System.getProperties();
		p.list(System.out);
	}
}

编译执行结果 会输出系统一些编码 方式,这里不贴出来了,了解下即可,不做重点。

9. RandomAccessFile(随机访问文件类)

1) RandomAccessFile包装了一个随机访问的文件。它不是派生于InputStream和OutputStream,而是实现定义了基本输入/输出方法的DataInput和DataOutput接口。它支持定位请求——也就是说,可以在文件内部放置文件指针。

查看JDK Doc文档:

java.lang.Object
  java.io.RandomAccessFile
All Implemented Interfaces:

Closeable, DataInput, DataOutput

[可以发现它实现了DateInput和DateOutput接口所以它是一个既能读,又能写的类]

查看里面的方法,其中有一个方法很经常使用:

public final void writeUTF(String str) throws IOException
  Writes a string to the file using modified UTF-8 encoding in a machine-independent manner.

[写一个字符串到文件,使用UTF-8这种编码方式与机器独立的方式]

它有两个构造方法:

RandomAccessFile(File fileObj, String access) throws FileNotFoundException
RandomAccessFile(String filename, String access) throws FileNotFoundException
第一种形式,fileObj指定了作为File 对象打开的文件的名称。
第二种形式,文件名是由filename参数传入的。
两种情况下,access 都决定允许访问何种文件类型。如果是“r”,那么文件可读不可写,如果是“rw”,文件以读写模式打开

2. 程序Demo:定义一个类,将这个类里面的几个属性写到文件里面,然后再读取出来。

package com.ahuier.io2;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;

public class RandomAccessFile1 {
	public static void main(String[] args) throws Exception {
		Person p = new Person(1, "hello", 5.42);
		RandomAccessFile raf = new RandomAccessFile("test.txt", "rw");
		p.write(raf);

		// 此时raf是随机读,已经读到末尾了,所以要读取之前要调用方法seek();让读的位置重新回到文件开头
		Person p2 = new Person();
		raf.seek(0);
		p2.read(raf);
		System.out.println(p2.getId() + ", " + p2.getName() + ", "
				+ p2.getHeight());
	}
}

class Person {
	int id;
	String name;
	double height;

	public Person() {
	}

	public Person(int id, String name, double height) {
		this.id = id;
		this.name = name;
		this.height = height;
	}

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public double getHeight() {
		return height;
	}

	public void setHeight(double height) {
		this.height = height;
	}

	// 将上述属性写到RandomAccessFile所对应的文件中去,注意写的时候与读的时候必须顺序一致
	public void write(RandomAccessFile raf) throws Exception {
		raf.writeInt(id);
		raf.writeUTF(this.name); // 字符串写入一般用writeUTF这个方法
		raf.writeDouble(this.height);

	}

	public void read(RandomAccessFile raf) throws Exception {
		this.id = raf.readInt();
		this.name = raf.readUTF();
		this.height = raf.readDouble();
	}
}

编译执行结果:

1, hello, 5.42


你可能感兴趣的:(java,java,java,IO,IO,IO)