今天开始学习张孝祥老师的视频教程-IO输入与输出,手上备有一本《JAVA语言程序设计(基础篇)》做为补充资料。
IO
File类
File类是IO包中唯一代表磁盘文件本身信息的类,而不是文件中的内容。
File类定义了一些与平台无关的方法来操纵文件,例如,创建、删除文件和重命名文件。
Java中的目录被当作一种特殊的文件使用,list方法可以返回目录中的所有子目录和文件名。
在Unix下的路径分隔符为(/),在Dos下的路径分隔符为(/),Java可以正确处理Unix和Dos的路径分隔符。
在第一个程序中,主要学习的方法有File类下的exists()、delete()、getName、getPath()、getAbsolutePath()、getParent()、canRead()、isDirectory()、lastModified()等方法,并使用了Util包下的Date类来显示文件的修改日期。用到了三目运算符,如:
f.canRead()?"readable":"unreadable"
如果条件canRead成立,则返回readable,否则返回unreadable。
f.createNewFile();语句在编译时会报错,故要加try… catch… 语句捕获异常。
书中提示:
在程序中,不要直接使用绝对目录名和文件名。为了能让程序在不同的平台上正常运行,使用下列字符串代替“c://book//test.dat”:
new File(".".getCanonicalPath()+"book"+File.separator+"test.dat");
RandomAccessFile类
RandomAccessFile类提供了众多的文件访问方法
RandomAccessFile类支持“随机访问”方式
RandomAccessFile类在随机(相对顺序而言)读写等长记录格式的文件(文件信息的记录按固定的格式)时有很大的优势
RandomAccessFile类仅限于操作文件,不能访问其他的IO设备,如网络,内存映象等
两种构造方法:
new RandomAccessFile(f,”rw”);//读写方式
new RandomAccessFile(f,”r”);//只读方式
学习此类下write()、writeInt()、writeChars()方法的区别,write()方法只能写入最大为256的数,大于256的数只写入溢出的部分。中文字符占两个字符位:
ra.write(e1.name.getBytes());
ra.writeChars(e1.name);
故在程序中若有中文字符,用writeChars()方法可以解决显示出错的问题。
new RandomAccessFile(f,”rw”)方法可以创建指定文件名的文件并设置创建文件的读写属性,在对RandomAccessFile类的操作结束后,应用close()方法关闭类操作,skipBytes()方法用于跳到文件指定位置,seek()方法用于RandomAccessFile类对文件的绝对定位,trim()方法用于取整,去掉字符串中不可见的字符。另外,还有readChar()、readInt()方法。
节点流
理解流的概念
InputStream与OutputStream类
FileInputStream与FileOutputStream类
Reader与Write类
PipedInputStream与PipedOutputStream类
ByteArrayInputStream与ByteArrayOutputStream类
重视程序代码的重用性
流的概念
流是字节序列的抽象概念
文件是数据的静态存储形式,而流是指数据传输时的形态
流类分为两大类:节点流类和过滤流类(也叫处理流类)
InputStream类
程序可以从中连续读取字节的对象叫输入流,在Java中,用InputStream类来描述所有输入流的抽象概念
方法:
int read()
int read(byte[] b)
int read(byte[] b,int off ,int len)
long skip(long n)
int available()
void mark(int readlimit)
void reset()
boolean markSupported()
void close()
其中,mark()、reset()方法不适用于节点流
问题:有了垃圾回收器,为什么还要调用close方法?
Java垃圾回收器只能管理Java程序中的类实例对象,不能管理系统产生的资源,程序需调用close()方法,通知系统释放对象所表示的流资源。
OutputStream类
程序可以向其中连续写入字节的对象叫输出流,在Java中,用OutputStream类来描述所有输出的抽象概念。
方法:
void write(int b) 将字节低位写入,高位舍弃
void write(byte[] b)
void write(byte[] b,int off,int len)
void flush()用于将内存缓存内容清空,输出到IO设备中
void close()
内存缓冲区的好处:能提高系统的效率。但降低程序本身的效率,因为程序不是直接写入IO设备中对IO设备进行控制。
张老师关于IO缓冲区的亲身经历:
程序记录文件不能反应所有的程序问题,记录文件不能记录缓冲区的内容,要用flush()方法或write()方法将内存缓冲区中的内容直接写入硬盘中,才能得到完全的记录文件,从而找到程序的问题所在。
书中提示:I/O类中几乎所有的方法都抛出异常java.io.IOException,所以必须在方法中声明抛出异常,或者将代码放到try-catch块中。
附1:
import java.io.*;
import java.util.Date;
public class FileTest
{
public static void main(String args[])
{
File f = new File("1.txt");
if(f.exists())
{
f.delete();
System.out.print("hi");
}
else
{
// try
// {
f.createNewFile();
// }
/* catch(Exception e)
{
e.printStackTrace();
}*/
}
System.out.println("File name:"+f.getName());
System.out.println("File path:"+f.getPath());
System.out.println("File abs path:"+f.getAbsolutePath());
System.out.println("File Parent:"+f.getParent());
System.out.println(f.exists()?"exist":"not exit");
System.out.println(f.canRead()?"readable":"unreadable");
System.out.println(f.isDirectory()?"directory":"not directory");
System.out.println("File lastModified:"+new Date(f.lastModified()));
}
}
附2:
import java.io.*;
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)
{
this.name = name.substring(0,LEN);
}
else
{
while(name.length()<LEN)
{
name +="/u0000";
}
}
this.name = name;
this.age = age;
}
}
public class RandomFileTest
{
public static void main(String args[])throws Exception
{
Employee e1 = new Employee("zhangsan",28);
Employee e2 = new Employee("李四",23);
Employee e3 = new Employee("wangwu",25);
RandomAccessFile ra = new RandomAccessFile("employee.txt","rw");
//ra.write(e1.name.getBytes());
ra.writeChars(e1.name);
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");
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.seek(0);
//len = raf.read(buf);
//strName = new String(buf,0,len);
strName = "";
for(int i=0;i<Employee.LEN;i++)
{
strName += raf.readChar();
}
System.out.println(strName.trim()+":"+raf.readInt());
raf.skipBytes(Employee.LEN*2+4);
//len = raf.read(buf);
//strName = new String(buf,0,len);
strName = "";
for(int i=0;i<Employee.LEN;i++)
{
strName += raf.readChar();
}
System.out.println(strName.trim()+":"+raf.readInt());
raf.close();
}
}