您的位置:首页 > 编程语言 > Java开发

java学习笔记_08_Java IO

2011-08-05 09:47 387 查看

java.io

File类

Java.io.File类主要是完成了文件夹管理的命名、查询文件属性和处理目录等不进行文件夹内容的读取操作。

构造方法:

File(String directoryPath)

File(String directoryPath,String filename)

File(File dirObj,String filename)

File(URI uriObj)

directoryPath是问价的路径名,filename是文件名,dirObj是一个指定目录的File对象,uriObj是描述一个文件的URI对象。

File f1=new File(“/”);

File f2=new File(“/”,”xx.text”);

File f3=new File(f1,”xx.text”)

f2和f3指向相同的文件。

下面代码测试了File的几个方法:

static void p(String s)

{

System.out.println(s);

}

public static void main(String[] args)

{

// TODO Auto-generated method stub

File f1=new File("/axis2.xml");

p("文件名"+f1.getName());

p("相对路径"+f1.getPath());

p("绝对路径"+f1.getAbsolutePath());

p("父节点"+f1.getParent());

p("是否存在"+f1.exists());

p("是否可写"+f1.canWrite());

p("是否可读"+f1.canRead());

p("isDirectory:"+f1.isDirectory());

p("是否正常文件"+f1.isFile());

p("is absolute?:"+f1.isAbsolute());

p("最后修改时间:"+f1.lastModified());

p("文件大小:"+f1.length());

}

注意:以上代码在新建文件对象的时候,File f1=new File("/axis2.xml");路径中有个“/”,这表示axis2.xml的绝对路径是在对应的磁盘根目录下,如果去掉/,则通常 是 Java 虚拟机的调用目录下。

下面列出File类常用方法,以供查看:

方法名

功能

CanWrite()

返回文件是否可写。

CanRead()

返回文件是否可读。

CompareTo(File pathname)

检查指定文件路径间的顺序

Delet()

从文件系统内删除该文件。

DeleteOnExit()

程序顺利结束时从系统中删除文件。

Equals(Object obj)

检查特定对象的路径名是否相等。

Exists()

判断文件夹是否存在。

GetAbsoluteFile()

返回文件的完整路径。

GetAbsolutePath()

返回文件的完整路径。

GetName()

返回文件名称。

GetParent()

返回文件父目录路径。

GetPath()

返回文件的潜在相对路径。

GetParentFile()

返回文件所在文件夹的路径。

HashCode()

返回文件哈希码。

IsDirectory()

判断该路径指示的是否是文件。

IsFile()

判断该路径指示的是否是文件。

LastModified()

返回文件的最后修改时间标志。

Length()

返回文件长度。

List()

返回文件和目录清单。

Mkdir()

生成指定的目录。

RenameTo(File dest)

更名文件。

SetReadOnly()

将文件设置为可读。

ToURL()

将文件的路径字符串转换成URL

File.GetCreationTime

读取创建时间

File.SetCreationTime

设置创建时间

File.GetLastAccessTime

读取最后访问时间

File.SetLastAccessTime

设置最后访问时间

File.GetLastWriteTime

读取最后修改时间

File.SetLastWriteTime

设置最后修改时间

File.GetAttributes

读取文件属性

File.SetAttributes

设置文件属性

目录的调用,看以下代码:

public static void main(String[] args)

{

// TODO Auto-generated method stub

File f1=new File("/JavaWork-e3.3-j1.5-t5.5");

if(f1.isDirectory())

{

System.out.println("目录名"+"JavaWork-e3.3-j1.5-t5.5");

String[] s=f1.list();

for(int i=0;i<s.length;i++)

{

File f=new File("/JavaWork-e3.3-j1.5-t5.5"+"/"+s[i]);

if(f.isDirectory())

{

System.out.println(s[i]+"是一个目录");

}

else

System.out.println(s[i]+"是一个文件");

}

}

else

System.out.println("JavaWork-e3.3-j1.5-t5.5不是一个目录!");

}
File.list()用之前要先判断File对象是否是目录,此方法以String数组形式返回目录下所有对象的名字.

此方法第二种形式String[] File.list(FilenameFilter FFObj)用于限制list返回的文件类型。

FilenameFilter为一个接口,里面只定义了accept()方法,它被列表中的每个文件各调用一次。boolean accept(File directory,String filename)

listFiles()方法

File[] listFiles()

File[] listFiles(FilenameFilter FFObj)

File[] listFiles(FileFilter FObj)

其次,还有创建目录的方法mkdir()和mkdirs(),两者区别就是:

mkdir()要创建的目录,那么其路径上的文件夹必须存在,

mkdirs()创建的目录则不需要。

如:在d盘上创建目录a/b,用mkdir()则a文件夹必须事先存在,用mkdirs()则不需要,如果a不存在,它会自动创建a。

在上面的说明中,文件已经创建好了,但是文件的内容还没有。通过java.io流,对文件内容进行操作。

IO流:字节流、字符流、过滤流、对象流(序列化)

1、字节流 [以字节为单位,适合操作二进制文件、音频、视频、图片]

所有的读操作都继承自一个公共超类java.io.InputStream类。

所有的写操作都继承自一个公共超类java.io.OutputStream类。

包括:

文件流:FileInputStream读入到内存、 FileOutputStream写出到文件

音频流:AudioInputStream、 AudioOutputStream

对象流:ObjectInputStream 反序列化、 ObjectOutputStream序列化

过滤流:FilterInputStream、FilterOutputStream

缓冲流(过滤流的子类):BufferedInputStream、 BufferedOutputStream

数据流(过滤流的子类):DataInputStream、DataOutputStream

……

2、字符流:[以字符为单位,对文本文件操作效率较高]

所有的读操作都继承自一个公共超类java.io.Reader类。

所有的写操作都继承自一个公共超类java.io.Writer类。

转换流:InputStreamReader读 字节->字符、OutputStreamWriter写 字符->字节

文件流(转换流的子类):FileReader、 FileWriter

缓冲流:BufferedReader、BufferedWriter

字节流和字符流对比

字节流是最基本的,所有的InputStream和OutputStream的子类都是字节流,其主要用于处理二进制数据,并按字节来处理。实际开发中很多 的数据是文本,这就提出了字符流的概念-Reader和Writer。它按虚拟机的encode来处理,也就是要进行字符流的转化。这两者之间通过InputStreamReader 和OutputStreamWriter来关联。实际上通过byte[]和String来关联在实际开发中出现的汉字问题,这都是在字符流和字节流之间转 化不统一造成的。

字节流转化为字符流,实际上就是byte[]转化为String。

字符流转化为字节流,实际上就是String转化为byte[]。

至于java.io中还出现了许多其他的流,主要是为了提高性能和使用方便,如BufferedInputStream、 PipedInputStream等。

字节流

所有的读操作都继承自一个公共超类java.io.InputStream类。

所有的写操作都继承自一个公共超类java.io.OutputStream类。

InputStream和OutputStream都是抽象类。

InputStream有6个低级输入流:

低级流

流的用途

ByteArrayInputStream

从内存数组中读取数据字节

FileInputStream

从本地文件系统中读取数据字节

PipedInputStream

从线程管道中读取数据字节

StringBufferInputStream

从字符串中读取数据字节

SequenceInputStream

从两个或多个低级流中读取数据字节,当到达流的末尾时从一个流转到另一个流

System.in

从用户控制台读取数据字节

InputStream还有一个子类:过滤器流java.io.FilterInputStream。过滤器流即能把基本流包裹起来,提供更多方便的用法。

FilterInputStream 类的构造方法为FilterInputStream(InputStream),在指定的输入流之上,创建一个输入流过滤器。

FilterInputStream的常用的子类如 下:

过滤器输入流

流的用途

BufferedInputStream

缓冲区对数据的访问,以提高效率

DataInputStream

从输入流中读取基本数据类型,如int、float、double或者甚至一行文本

LineNumberInputStream

在翻译行结束符的基础上,维护一个计数器,该计数器表明正在读取的是哪一行。

PushbackInputStream

允许把数据字节向后推到流的首部

FileInputStream举例:

public class IOTest

{

public static final String fileDir = "d:/axis2.xml"; // 原始文件位置

public static final String toDir = "d:/456.txt"; // 文件将要拷贝到地址

FileInputStream in = null;

FileOutputStream out = null;

/**

* 文件拷贝,从地址"src/123.txt"拷贝到"d:/123.txt"

*

* @throws Exception

*/

public void copyFile() throws Exception

{

in = new FileInputStream(fileDir);

out = new FileOutputStream(toDir, true);

byte[] bt = new byte[1024];

int hasRead = 0;

while ((hasRead = in.read(bt, 0, bt.length)) != -1)

{

out.write(bt, 0, hasRead);

}

out.flush();

out.close();

in.close();

}

/**

* 测试

*

* @param args

* @throws Exception

*/

public static void main(String[] args) throws Exception

{

IOTest test = new IOTest();

test.copyFile();

}

}

对于read()这个方法,每次读取一定字节后,下一次读取,将会自动从上次结束的位置开始。一般在InputStream的具体实现类中,都有一个字段标识当前的位置,即已经读到了什么地方。比如在BufferedInputStream中,有一个pos属性,用来指示这个位置。

上面的代码中,flush解释:

flush方法即使在缓冲区中没有满的情况下,也会将缓冲区内的内容强制写到外设,也就是所谓的刷新。flush方法不是对所有的 OutputStream子类起作用,只对那些使用缓冲区的OutputStream子类有效。调用close方法,系统在关闭这个流前,也会将缓冲区的内容写到外设上。

字符流

当用于处理文本数据时,选择字符流比字节流更好。

所有的读操作都继承自一个公共超类java.io.Reader类。

所有的写操作都继承自一个公共超类java.io.Writer类。

同样Reader和Writer也是抽象类。

Reader的常用的子类如下:

低级读取器

流的用途

CharArrayReader

从字符数组中读取数据

InputStreamReader

将字节流转化为字符流

FileReader(InputStreamReader的子类)

从本地文件系统中读取字符序列

StringReader

从字符串中读取字符序列

PipedReader

从线程管道中读取字符序列

同样的,字符流也有过滤器,提供简便的方法。

常用的过滤器读取器:

过滤器读取器

流的用途

BufferedReader

缓冲数据的访问,以提高效率

LineNumberReader(BufferedReader的子类)

维护一个计数器,该计数器表明正在读取的是哪一行。

FilterReader(抽象类)

提供一个类创建过滤器时可以扩展这个类

PushbackReader(FilterReader的子类)

允许把文本数据推回到读取器的流中

这些过滤器读取器都可以传入一个Reader作为构造方法的参数。

InputStreamReader

InputStreamReader是从输入流中读取数据,连接输入流于读取器。如:

new InputStreamReader(System.in)

构造方法:

InputStreamReader(InputStream) 用缺省的字符编码方式,创建一个 InputStreamReader。

InputStreamReader(InputStream, String) 用已命名的字符编码方式,创建一个 InputStreamReader。

下面是一个FileWriter的例子:

public static void main(String[] args) throws IOException

{

// TODO Auto-generated method stub

String source="阿速达卷卡式带健康哈桑将扩大化卷卡式带快哈萨克打算的";

char[] buffer=new char[source.length()];

source.getChars(0,source.length(),buffer,0);

FileWriter f0=new FileWriter("/file1.txt");

for(int i=0;i<buffer.length;i++)

{

f0.write(buffer[i]);

}

f0.close();

FileWriter f1=new FileWriter("/file2.text");

f1.write(buffer);

f1.close();

FileWriter f2=new FileWriter("/file3.txt");

f2.write(buffer,buffer.length-buffer.length/4,buffer.length/4);

f2.close();

}

注意:每次用完输入输出流之后,都要把流关闭。

附:Java io流的使用原则

一、按数据来源(去向)分类:

1 、是文件: FileInputStream, FileOutputStream, ( 字节流 )FileReader, FileWriter( 字符 )

2 、是 byte[] : ByteArrayInputStream, ByteArrayOutputStream( 字节流 )

3 、是 Char[]: CharArrayReader, CharArrayWriter( 字符流 )

4 、是 String: StringBufferInputStream, StringBufferOuputStream ( 字节流 )StringReader, StringWriter( 字符流 )

5 、网络数据流: InputStream, OutputStream,( 字节流 ) Reader, Writer( 字符流 )

二、按是否格式化输出分:

1 、要格式化输出: PrintStream, PrintWriter

三、按是否要缓冲分:

1 、要缓冲: BufferedInputStream, BufferedOutputStream,( 字节流 ) BufferedReader, BufferedWriter( 字符流 )

四、按数据格式分:

1 、二进制格式(只要不能确定是纯文本的) : InputStream, OutputStream 及其所有带 Stream 结束的子类

2 、纯文本格式(含纯英文与汉字或其他编码方式); Reader, Writer 及其所有带 Reader, Writer 的子类

五、按输入输出分:

1 、输入: Reader, InputStream 类型的子类

2 、输出: Writer, OutputStream 类型的子类

六、特殊需要:

1 、从 Stream 到 Reader,Writer 的转换类: InputStreamReader, OutputStreamWriter

2 、对象输入输出: ObjectInputStream, ObjectOutputStream

3 、进程间通信: PipeInputStream, PipeOutputStream, PipeReader, PipeWriter

4 、合并输入: SequenceInputStream

5 、更特殊的需要: PushbackInputStream, PushbackReader, LineNumberInputStream, LineNumberReader

决定使用哪个类以及它的构造进程的一般准则如下(不考虑特殊需要):

首先,考虑最原始的数据格式是什么: 原则四

第二,是输入还是输出:原则五

第三,是否需要转换流:原则六第 1 点

第四,数据来源(去向)是什么:原则一

第五,是否要缓冲:原则三 (特别注明:一定要注意的是 readLine() 是否有定义,有什么比 read, write 更特殊的输入或输出方法)

第六,是否要格式化输出:原则二

序列化

序列化的作用

对于在网络上传输数据,如果不用序列化,不采用序列化直接传输一个类的实例,如:网络上A、B两台WEB应用,如果B中有如下代码:

Document doc=new Document();

return doc;

A接收这个doc,那么A在使用这个实例的时候会出错。只有通过序列化和反序列化传输对象才能正常使用。

Java的序列化机制只序列化对象的属性值,而不会去序列化方法。

下面是序列化保存的东西

1)对象的类型

2)对象属性的类型

3)对象属性的值

序列化写法

如果要序列化一个对象,那么必须让这个对象的类实现java.io.Serializable接口,

对于一个实现序列化接口的类,要用ObjectOutputStream类和ObjectInputStream类来实现序列化对象的输出与输入。

ObjectOutputStream的方法描述如下表:

void close()

关闭调用的流。如果继续写,会抛出IOException

void flush()

最终确定输出状态,以便清空输出缓冲区

vlid write(byte buffer[])

将字节数组写入到调用的流中

void write(byte buffer[],int offset,int numBytes)

在buffer数组中写入从buffer[offset]开始的numBytes个字节

void write(int b)

将单个字节写入到调用的流中,写入的字节是b的低位字节

void writeBoolean(boolean b)

将一个boolean型值写到调用的流中。

void writeBytes(int b)

将单个字节写入到调用的流中,写入的字节是b的低位字节

void writeBytes(String str)

写入代表str的字节到调用的流中

void writeChar(int c)

写入一个char到调用的流中

void writeChars(String str)

写入str中的字符到调用的流中

void writeDouble(double d)

写入一个double到调用的流中

void writeFloat(float f)

写入一个float到调用的流中

void writeInt(int i)

写入一个int到调用的流中

void writeLong(long l)

写入一个long到调用的流中

final void writeObject(Object obj)

写入一个obj到调用的流中

void writeShort(int i)

写入一个short到调用的流中

在用ObjectOutputStream输出之后,用ObjectInputStream来接收对象。下面是ObjectInputStream的一些常用方法。

int available()

返回输入缓冲区中现在可用的字节数

void close()

关闭调用流。如果继续读,会产生IOException

int read()

返回输入流中表示下一个字节的整数。当到达文件末尾时,返回-1.

int read(byte buffer[],int offset,int numBytes)

试图读取buffer中从buffer[offset]开始的numBytes个字节,返回成功读取的字节数。遇到文件末尾时,将返回-1

boolean readBoolean()

从调用流中读取并返回一个boolean类型的变量

byte readByte()

从调用流中读取并返回一个byte类型的变量

char readChar()

从调用流中读取并返回一个char类型的变量

double readDouble()

从调用流中读取并返回一个double类型的变量

float readFloat()

从调用流中读取并返回一个float类型的变量

void readFully(byte buffer[])

读取buffer.length个字节到buffer中,只有当所有自己被读取后才返回

void readFully(byte buffer[],int offset,int numBytes)

读取numBytes个自己到开始于buffer[offset]的buffer中,只有当numBytes个字节被读取时才返回

int readInt()

从调用流中读取并且返回一个Int类型的变量

long readLong

从调用流中读取并且返回一个long类型的变量

final Object readObject()

从调用流中读取并且返回一个对象

short readShort()

从调用流中读取并且返回一个short类型的变量

int readUnsignedByte()

从调用流中读取并且返回一个无符号byte类型的变量

int readUnsignedShort()

从调用流中读取并且返回一个无符号short类型的变量

下面的例子用了ObjectOutputStream和ObjectInputStream

public class SerializableTest implements Serializable

{

/**

* TODO

*

* @param args

* @return void

* @throws IOException

* @throws ClassNotFoundException

* @since v 1.0

*/

public static void main(String[] args) throws IOException, ClassNotFoundException

{

// TODO Auto-generated method stub

File a=new File("/a.txt");

FileOutputStream fos=new FileOutputStream(a);

ObjectOutputStream oos=new ObjectOutputStream(fos);

SerializableTest st=new SerializableTest();

oos.writeObject(st);

FileInputStream fis=new FileInputStream(a);

ObjectInputStream ois=new ObjectInputStream(fis);

SerializableTest b=(SerializableTest)ois.readObject();

b.s();

}

private void s()

{

System.out.println("序列化后读出的数据");

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: