3、字符流
我们已经介绍了字节流类并详细地讲解了字节流。虽然字节流的功能十分强大,它能直接或间接地处理任何数据类型的输入和输出操作,但是它却不能直接操作16位的Unicode字符。这时提供直接的字符输入和输出就显得非常有必要了。
1)、如何读取Unicode字符
Reader和Writer类处在字符流类的顶层,是所有字符流类的基类。同时它们都是抽象的,它们仅提供了基本的函数类型,没有具体实现,所以不能直接生成对象。要通过其子类来生成所需的对象,同时必须重写Reader和Writer类中的方法。下面是它们的主要方法:
Reader方法:
>read():从输入流中读取下一个字符,并以int类型返回。如遇输入流的末尾则返回-1
>read(char[] buffer):读取长度为buffer.length的字符到buffer中,返回本次读取的字符数;
>read(char[] buffer , int off , intlen):同上,写入buffer中从下标off开始的位置,并返回本次读取的字符数。
>close():关闭当前的输入流;
>skip(long n):跳过n个字符,返回实际跳过的字符数;
>mark(int readlimit):在输入流的当前位置设置标记,该标记在从流中读取readlimit个字符前都保持有效;
>markSupported():测试调用的流是否支持mark()/reset();
>ready():测试输入流是否准备好读取字符;
>reset():重置输入指针到先钱设定的标记处。
Writer方法:
>write(int c):将指定的字符c作为数据写入输出流,下面是对其的重写:
>write(char[]buffer):将buffer中长度为buffer.length个字符的数据写入输出流;
>write(char[] buffer , int off , intlen):同上,将buffer中从下标off开始的长度为len个字符的数据写入输出流;
>write(String str):将字符串str写入输出流;
>write(String str , intoff , int len):将字符串中以off为起点的len个字符写入输出流;
>close():关闭当前的输出流,同时释放相关的系统资源;
>flush():刷新输出流。
上述方法在调用时如果出现错误,将会跑出一个IOException异常。
2)、读取字符文件
FileReader和FileWriter类分别继承了Reader和Writer类,它们重写了父类中的所有方法,主要用于字符文件的读写操作。FileReader类用于读取字符文件的内容,每次赌气一个字符或一个字符数组。FileWriter类用于写入字符文件的内容,每次写入一个字符或一个字符串。
FileReader类的两个常用的构造函数如下:
> FileReader(StringfilePath)//filePath指被打开并被读取数据的文件的全路径
>FileReader(FilefileObj)//fileObj指被打开并被读取数据的文件
下面的实例讲解了FileReader的使用方法:
public static voidmain(String[] args) {
try {
FileReader fr = newFileReader("D:\\桌面\\桌面\\安卓开发工具\\学习笔记\\test1.txt");
//每次读取一个字符
char[] c = new char[1];
while (fr.read(c) != -1)
System.out.print(new String(c));
fr.close();
} catch (Exception e) {
e.printStackTrace();
}
}
FileWriter类常用的构造函数如下:
>FileWriter(String filePath)
>FileWriter(String filePath , boolean append)
>FileWriter(String fileObj)
FileWriter对象的创建不依赖文件是否存在。如果文件不存在,FileWriter会在打开输出文件之前创建它。如果文件存在,则打开它并准备写入内容。下面的实例讲解了如何从文件中读取数据并写入另一个文件:
public class test {
public static void main(String[] args) {
int i;
FileReader fr;
FileWriter fw;
try {
fr = new FileReader("D:\\桌面\\桌面\\安卓开发工具\\学习笔记\\test01.txt");
} catch (Exception e) {
System.err.println("文件未找到");
return;
}
try {
fw = new FileWriter("D:\\桌面\\桌面\\安卓开发工具\\学习笔记\\test02.txt");
}catch (Exception e) {
System.err.println(e);
return;
}
try {
i = fr.read();//读取数据
while (i != -1) {
fw.write(i);
i = fr.read();
}
fr.close();
fw.close();
System.err.println("运行完毕");
} catch (Exception e) {
System.err.println(e);
}
}
}
3)、如何提高IO操作
缓冲字符流BufferedReader、BufferedWriter和缓冲字节流一样,引进缓冲字符流的目的也是为了提高I/O操作的效率。BufferedReader和BufferedWriter类常用的构造方法如下:
BufferedReader(Obj) ,BufferedWriter(Obj)
它们的方法与Reader类和Writer类中的方法基本相同,同时还有新增的方法。readLine()函数的功能就是读入字符,知道遇到”\n”或”\r”为止。下面的实例讲解了readLine()方法是使用方法:
public static voidmain(String[] args) {
try {
FileReader fr = newFileReader("D:\\桌面\\桌面\\安卓开发工具\\学习笔记\\test01.txt");
BufferedReader br = newBufferedReader(fr);
String a = br.readLine();
while (a != null) {
System.out.println(a);
a = br.readLine();
}
fr.close();
br.close();
} catch (Exception e) {
System.err.println(e);
}
}
4)、通过字符读取文件及写出
字符流读取文件时以单个字符为单位的。一般字符是由多个字节组成的。Java语言内部可将一个字节流转化为字符流,这种转化是有InputStreamReader和OutputStreamWriter来完成的。可以在生成InputStreamReader和OutputStreamWriter类的对象时指定编码规范,也可以使用当前平台的默认编码规范。
InputStreamReader类的构造函数如下:
InputStreamReader(InputStream in)//使用当前平台的默认编码规范
InputStreamReader(InutStream in , String charname)//指定编码规范
OutputStreamWriter类的构造函数如下:
OutputStreamWriter(OutputStream out)
OutputStreamWriter(OutputStream out , String charname)
下面通过实例讲解字节流向字符流转换的过程:
public static voidmain(String[] args) {
try {
FileInputStream fis = newFileInputStream("D:\\桌面\\桌面\\安卓开发工具\\学习笔记\\test01.txt");
//将字节流文件转换为字符流文件
InputStreamReader isr = newInputStreamReader(fis, "GBK");
//带缓冲的字符流输入文件
BufferedReader br = new BufferedReader(isr);
FileOutputStream fos = newFileOutputStream("D:\\桌面\\桌面\\安卓开发工具\\学习笔记\\test02.txt");
//将字节流文件转换为字符流文件
OutputStreamWriter osw = newOutputStreamWriter(fos , "GBK");
//带缓冲的字符流输出文件
BufferedWriter bw = newBufferedWriter(osw);
String str = br.readLine();
while (str != null) {
bw.write(str);
bw.flush();
System.out.println(str);
str = br.readLine();
}
br.close();
bw.close();
} catch (Exception e) {
System.out.println(e);
}
}
刚开始学的时候,大家通常会遇到打印出来的字符出现乱码的情况,这是由于源文件的编码问题或者字符流所指定的编码不支持引起的,在进行编码转换时,一定要看清楚源文件的编码和需要输出的编码,多试几个应该就没问题了。
4、文件类
文件咧虽然没有前面讲道德字节流和字符流重要,但它是对文件进行操作最直接和最详细的一种方法。使用文件类可以获取很多的指定文件的信息,在文件类中都给出了对应的方法。
1)、文件类简介
对一个文件继续拧操作时,需要知道这个文件的基本信息。File类提供了一些方法来处理文件和获取文件的信息。也可以对响应的目录进行操作。通过File类的方法,可以得到文件本身的属性,包括文件名、文件的路径、长度,还可以创建、删除、修改文件和文件夹。File类的构造函数如下:
>File(String path)
>File(String path ,Stringfile)
>File(File Obj ,Stringfile)
其中path是文件的路径或文件路径+文件名,file是文件名,Obj是目录的File对象。下面是一个File类中方法使用的实例:
public static void main(String[]str) throws IOException {
File a = new File("D:\\桌面\\桌面\\安卓开发工具\\学习笔记\\图片");
File b = new File("D:\\桌面\\桌面\\安卓开发工具\\学习笔记\\图片.txt");
File c = new File("D:\\桌面\\桌面\\安卓开发工具\\学习笔记", "文件.ini");
File d = new File(a , "图片片.ini");
//文件是否存在
if (a.exists())System.out.println("文件a是存在的");
else{
System.err.println("文件a不存在");
a.createNewFile();//创建a这个文件
System.err.println("创建了a这个文件");
a.mkdirs();//创建a这个文件夹
System.err.println("创建了a这个文件夹");
}
//b是否为文件
if (b.isFile())System.out.println("b是一个文件");
else{
b.mkdirs();//创建b这个文件夹
System.err.println("创建了b这个文件夹");
}
//c是否为文件夹
if (c.isDirectory())System.out.println("c是一个文件夹");
else {
c.createNewFile();
System.err.println("创建了c这个文件");
}
//d是否为文件
if (d.isFile())System.out.println("d是一个文件");
else {
d.mkdirs();
System.err.println("创建了d这个文件夹");
}
}
上面的实例建议大家好好看一下,因为上面涉及到的文件操作规律很多,写起来很麻烦,所以建议大家亲自尝调试一下,发现其中的一些规律技巧。
当创建了一个文件对象后,可以用File类提供的方法来获取文件的相关信息,同时对文件进行相应的操作。File类的方法如下:
exists():测试File对象对应的文件是否存在
isFile():测试File对象对应的是否是一个文件
isDirectory():~~~~~是否是一个文件夹
canRead():~~~~~是够可读
canWrite():~~~~~对否可写
isHidden():~~~~~是否为隐藏
createNewFile():创建一个新文件
setReadOnly():将File对象对应的文件设置为只读
list():获取File对象对应的目录下的文件名
mkdir():创建File对象对应的目录
delete():删除对应文件
equals(Object obj):比较两个文件对象
renameTo(File dest):对File对象对应的文件进行重命名
toString():将File对象转换为字符串
getName():返回File对象对应的文件名
getParent():返回File对象对应的文件的父目录
getPath():返回File对象对应的文件的路径
getAbsolutePath():返回File对象对应的文件的绝对路径
lastModified():返回文件的最后修改时间
length():返回文件的大小
2)、通过文件类对文件操作
下面列出了关于File类对文件操作的实例,如果仔细研究,就能很好地运用到程序中:
public static voidmain(String args[])
{
File f1=new File("F:\\java基础\\wndang\\程序\\5\\5-2");//打开一个文件
File f2=new File(f1,"User.java");
File f3=new File("F:\\java基础\\wndang\\程序\\5\\5-2\\User.java");
System.out.println(f2);
System.out.println();
//获取该文件的各个属性和信息
System.out.println("exists: "+f2.exists());
System.out.println("isfile: "+f2.isFile());
System.out.println("Directory: "+f2.isDirectory());
System.out.println("Read: "+f2.canRead());
System.out.println("Write: "+f2.canWrite());
System.out.println("Hidden: "+f2.isHidden());
System.out.println("ReadOnly: "+f2.setReadOnly());
System.out.println("Name: "+f2.getName());
System.out.println("Parent: "+f2.getParent());
System.out.println("AbsolutePath: "+f2.getAbsoluteFile());
System.out.println("lastModified: "+f2.lastModified());
System.out.println("length: "+f2.length());
System.out.println("list "+f2.list());
System.out.println("mkdir "+f2.mkdir());
File f4=new File("Student.java");
System.out.println("newname"+f2);
f2.renameTo(f4);
System.out.println("Name: "+f4.getName());
System.out.println(f2+"exist "+f2.exists());
System.out.println(f4+"exist "+f2.exists());
System.out.println("delete"+f4);
System.out.println("equals "+f2.equals(f4));
f4.delete();
System.out.println(f4+"exist "+f4.exists());
System.out.println("String "+f2.toString());
}