您的位置:首页 > 职场人生

黑马程序员--第二阶段Java高级IO--第18天

2012-04-25 11:11 295 查看
[align=center]-------------------- android培训、java培训、期待与您交流!--------------------[/align]

IO/输入输出

大多数应用程序都需要与外部设备进行数据交换,最常见的外部设备包含磁盘文件系统和网络,IO就是指应用程序对这些设备的数据输入与输出的操作,在程序中,键盘被当作一种特殊的输入文件,显示器被当作输出文件使用。Java语言定义了许多类专门负责各种方式的输入输出,这些类都被放在java.io包中。

File类

File类是IO包中惟一代表磁盘文件本身信息的类,注意不是代表文件中的内容,而是代表文件的信息,如文件名、修改时间、可读等信息内容。File类定义了一些与平台无关的方法来操纵文件,通过调用File类提花的各种方法,我们能够创建、删除文件,重命名文件,判断文件的读写权限及文件是否存在,设置和查询文件的最近修改时间。

在Java中,目录也被当作File使用,只是多了一些目录特有的功能——可以用list方法列出目录中所有子目录和文件名。在Unix下的路径分隔符为(/),在Dos下的路径分隔符为(\),Java可以正确处理Unix和Dos的路径分隔符,即使我们在Windows环境下使用(/)作为路径分隔符,Java仍然能够正确处理。

下面的例子演示了File类用法,判断某个文件是否存在,存在则删除,不存在则创建:

import java.io.File;

import java.text.SimpleDateFormat;

import java.util.Date;

class TestFile {

public static void main(String[] args) {

File f = new File("D:\\text1\\text2\\text.txt");//这里的目录结构必须已经存在

//此处可尝试:text、text1\\text2、text.txt

//如果用new File("aa","1.txt"),则aa为1.txt文件的parent目录,但是aa目录必须已经存在

if(f.exists()) { //判断文件或目录是否存在

f.delete(); //删除文件或目录

} else {

try{

f.createNewFile(); //创建文件

// f.mkdirs(); //创建目录

} catch(Exception e) {e.printStackTrace();}

}

System.out.println(f.exists()? "文件或目录已存在" : "文件或目录不存在");

System.out.println("指定的路径名为:" + f);

System.out.println("指定的文件名或目录名为:" + f.getName());

System.out.println("指定的文件路径为:" + f.getPath());

System.out.println("指定的文件绝对路径为:" + f.getAbsolutePath());

System.out.println("指定的父目录为:" + f.getParent());

System.out.println(f.isAbsolute()? "是绝对路径" : "不是绝对路径");

System.out.println(f.isDirectory()? "这是一个目录" : "这不是一个目录");

System.out.println(f.isFile()? "这是一个文件" : "这不是一个文件");

System.out.println(f.isHidden()? "这是一个隐藏文件" : "这不是一个隐藏文件");

System.out.println(f.canExecute()? "这是可执行文件" : "这不是一个可执行文件");

System.out.println(f.canRead()? "这是可读文件" : "这不是一个可读文件");

System.out.println(f.canWrite()? "这是可写文件" : "这不是一个可写文件");

if(f.exists()){

SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日HH时mm分ss秒");

Date d = new Date(f.lastModified());//lastModified为返回文件的最后修改时间,值为long型

String lastModified =sdf.format(d);

System.out.println("文件最后一次修改时间为:" + lastModified);

}

}

}

注意:delete方法删除由File对象的路径所表示的磁盘文件或目录。如果删除的对象是目录,该目录中的内容必须为空。

上面代码只是对文件本身的属性进行操作,而不能访问文件的内容,即不能够从文件中读取数据或往文件里写数据。

RandomAccessFile类

RandomAccessFile类可以说是Java语言中功能最为丰富的文件访问类,它提供了众多的文件访问方法。RandomAccessFile类支持“随机访问”方式,可以跳转到文件的任意位置处读写数据。在你访问一个文件的时候,不想把文件从头读到尾,并希望像访问一个数据库一样地访问一个文本文件,使用RandomAccessFile类就是你的最佳选择。

RandomAccessFile对象类有个位置指示器,指向当前读写处的位置,文件的开始位置为0,当读写n个字节后,文件指示器将指向这n个字节后的下一个字节处。刚打开文件时,文件指示器指向文件的开头处,我们可以移动文件指示器到新的位置,随后的读写操作将从新的位置开始。

RandomAccessFile类提供了众多的文件访问方法

RandomAccessFile类支持“随机访问”方式

RandomAccessFile类在随机读写等长记录格式的文件时有很大的优势

RandomAccessFile类仅限于操作文件,不能访问其他IO设备,如网络、内存映象等。

两种构造方法:

new RandomAccessFile(f,”rw”);//读写方式

new RandomAccessFile(f,”r”);//只读方式

注:当我们的程序以读写的方式打开一个文件时,如果这个文件不存在,程序会为你创建

编程实例:往文件中写入三名员工的信息,每个员工含有姓名和年龄两个字段,然后按照第二名、第一名、第三名的先后顺序读取出员工信息。

我们需要设计一个类来封装员工信息。一个员工信息就是文件中的一条记录,我们必须保证每条记录在文件中的大小相同,也就是每个员工的姓名字段在文件中的长度是一样的,我们才能够确定每条记录在文件中的具体位置。假设name中有8个字符,少于8个则补空格(”\u0000”),多于8个则去掉后面多余的部分。由于年龄是整数型,不管这个数有多大,只要它不超过整型数的范围,在内存中都是占4个字节大小。

字符串对象有一个length方法用来返回字符串对象的字符个数。如:

“abc”.length( );//返回3

“戴振良”.length( );//返回3

注意1:英文字符虽然占两个字节,但是他们的unicode码只占一个字节,而中文字符却占两个字符。byte只占一个字节,所以把一个英文字符转换为byte型时数据不会丢失,如:(byte)’a’,
而把一个中文字符转换为byte就会丢失数据,如:int b=‘戴’; //b=25140 int b=(byte)‘戴’;
//b=52

注意2: String a=null; a=a+"你好";
此时a="null你好";所以可以把a初始化为空字符串” ”

Employee.java

public class Employee

{

public String name = null;

public int age = 0;

public static final int LEN = 8;

public Employee(String name, int age)

{

if(name.length()>LEN)//字符串对象的length方法用于返回字符串对象的长度(字符个数)

{

name=name.substring(0,LEN);

}

else

{

while(name.length()<LEN)

{

name+="\u0000";

}

}

this.name=name;

this.age=age;

}

}

RandomFileTest.java

import java.io.*;

public class RandomFileTest

{

public static void main(String[] args) throws Exception //在这里加了throws Exception后就不需要捕获异常了

{

Employee e1=new Employee("张三",23);

Employee e2=new Employee("lisi",256);

Employee e3=new Employee("wangwu",25);

RandomAccessFile ra=new RandomAccessFile("employee.txt","rw");

//getBytes()方法用于把该字符串对象的所有字符转换为Byte数组,因为中文字符太多,要用两个字节来表示,而一个字节就能表示完所有的英文字符,当读取英文字符是,则读一个字符会转换成一个字节,而读一个中文字符的时候会转换成两个字节,

//write(int b)向此文件写入指定的字节。

//write(byte[] b)将b.length
个字节从指定 byte 数组写入到此文件,并从当前文件指针开始。

//writeInt方法:按四个字节将 int
写入该文件,先写高字节。

//ra.write(e1.name.getBytes());

//writeChar(int v)
按双字节值将 char 写入该文件,先写高字节

//writeChars(String s)
按字符序列将一个字符串写入该文件。

ra.writeChars(e1.name); //写进来的字符串以Unicode码表示,每个字符占两个字节

ra.writeInt(e1.age);

//ra.write(e2.name.getBytes());

ra.writeChars(e2.name);

ra.writeInt(e2.age);

//ra.write(e3.name.getBytes());

ra.writeChars(e3.name);

ra.writeInt(e3.age);

ra.close();//关闭文件

//int len=0;

//byte[] buf=new byte[Employee.LEN];

String strName="";

RandomAccessFile raf=new RandomAccessFile("employee.txt","r");

//skipBytes(int n) //尝试跳过输入的 n
个字节以丢弃跳过的字节。

raf.skipBytes(Employee.LEN*2+4);//跳过12个字节,从第13个字节开始读写操作

//len=raf.read(buf);//将最多 buf.length
个数据字节从此文件读入 buf 数组。

//buf参数是将数据读入的缓冲区,该方法返回的是读入缓冲区的总字节数(int型),如果由于已到达此文件的末尾而不再有数据,则返回 -1。

//strName=new String(buf,0,len);

for(int i=0;i<Employee.LEN;i++)

{ //readChar()从此文件读取一个字符。

strName+=raf.readChar();

}

System.out.println(strName.trim()+":"+raf.readInt());

strName="";

//trim方法:删除字符串对象中字符串前面、后面的那些不可显示的字符

//read()无参数方法:从此文件中读取一个数据字节。以整数形式返回此字节,范围在 0
到 255 (0x00-0x0ff)。如果尚无输入可用,将阻塞此方法。

//seek(long pos) //设置到此文件开头测量到的文件指针偏移量,在该位置发生下一个读取或写入操作。

raf.seek(0);//定位到文件中的第0个字节处

//len=raf.read(buf);

//strName=new String(buf,0,len);

for(int i=0;i<Employee.LEN;i++)

{

strName+=raf.readChar();

}

System.out.println(strName.trim()+":"+raf.readInt());//读取完这条语句,指示器已经指示到了第二条记录的开始处了

strName="";

raf.skipBytes(Employee.LEN*2+4);

//len=raf.read(buf);

//strName=new String(buf,0,len);

for(int i=0;i<Employee.LEN;i++)

{

strName+=raf.readChar();

}

System.out.println(strName.trim()+":"+raf.readInt());

raf.close();

}

}

[align=center]-------------------- android培训、java培训、期待与您交流!--------------------[/align]
[align=center] 详情请查看:http://edu.csdn.net/heima/[/align]
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: