欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

文件与流简介(1)

程序员文章站 2024-03-12 12:09:02
...

文件的介绍

1)在Java中使用java.io.File类表示一个文件(目录) 路径(注:该类并不代表文件内容)。

2)File类关心的是磁盘上存储的文件位置和名称等,而流是指程序运行中的数据通信信道,当然流类所关心的是文件的内容。

3)如果要考虑跨平台,则可以这样书写写:”...”+File.separator+”temp”+ File.separator+”文件名”。

 

File类的构造函数:

File(String pathname):建立一个以pathname为路径的File对象,pathname可以是相对路径,也可以是绝对路径。

File(Stringparent,String child):建立一个以parent加上child为路径的File对象。

File(Fileparent,String child):建立一个以parent加上child为路径的File对象。

 

类File的对象的常用方法:

1)exists() //文件或者目录是否存在

2)isFile() //是否是文件

3)isDirectory() //是否是目录

4)getName() //取文件或者目录的名字

5)getPath() //取文件或者目录的路径

6)getAbsolutePath() //取文件绝对路径

7)lastModified() //最后修改日期

8)length() //文件或者目录的字节大小

9)createNewFile() //创建新文件

10)mkdirs() //创建文件夹

10)list()//获得当前File对象所表示目录下的文件和目录名称,返回String[]类型的数据。

11)listFiles()//获得当前File对象所表示目录下的文件和目录,返回File[]类型的数据。

 

例子(获取当前目录下所有文件和文件的大小):

 

import java.io.*;
public classFileSize
{
    public static void main(String[] args) {
        File files=new File(".");
        String[] list=files.list();
        for(int i=0;i<list.length;i++){
       
            File file=new File(list[i]);
            System.out.println(list[i]+file.length());
       
        }
    }
}

 

开发一个方法删除指定的文件或目录(包括子目录、子文件)

 

public classFileDeleter {
 public void delete(File file){  
  if(!file.exists())return; //如果file不存在 
  if(file.isFile()){//若file表示文件,则删除。
   file.delete();
   return;
  } 
  if(file.isDirectory()){//若file表示目录  
    //获得直接在该目录下所有文件或目录对应的File对象  
    File[] subFiles=file.listFiles();
    //如果该目录下确实有文件或者目录
    if(subFiles!=null&&subFiles.length>0){  
    //依次删除该目录下的文件或目录
    for(int i=0;i<subFiles.length;i++){
        delete(subFiles[i]);//递归调用
    }   
   }  
   file.delete(); //删除该目录
  } 
 }
}

 

流的概念

File类关心的是磁盘上存储的文件位置和名称等,而流是指程序运行中的数据通信信道,当然流类所关心的是文件的内容。

流的分类

输入流和输出流:

1)输入流是从外设传输数据进入内存的流。

2)输出流是从内存传输数据至外设的流。

字节流和字符流:

1)字节流是指以字节为数据最小传输单位的流。

2)字符流是指以字符(双字节)为数据最小传输单位的流。

流的四个根类

1)InputStream-字节输入流

2)OutputStream-字节输出流

3)Reader-字符输入流

4)Writer-字符输出流

字节流

文件与流简介(1)

1>InputStream类是所有字节输入流类的基类,是个抽象类。

2>常用的方法:

int read():如果下一个字节可读,以整数的形式返回读取的字节值,如果到了流末尾,则返回-1。

int read(byte[] b):从流中最多读取b.length个数据字节放入数组b中,以整数形式返回实际读取的字节数,如果到了流末尾,则返回-1。

int read(byte[] b,int off,int len):从流中最多读取len个数据字节放入数组b中,并从b[off]开始放入数组,以整数形式返回实际读取的字节数,如果到了流末尾,则返回-1。

void close():关闭输入源。

int available():返回当前可读的字节数。

例子(读取文件信息):

 

public staticvoid main(String[] args) {
File file=newFile("test.txt");
byte[] bt=newbyte[(byte)file.length()];
try {
FileInputStreamfis=new FileInputStream(file);
fis.read(bt);
for (int i = 0; i< bt.length; i++) {
System.out.print((char)bt[i]+"\t");
}
} catch(FileNotFoundException e) {
e.printStackTrace();
} catch(IOException e) {
e.printStackTrace();
}
}

 

1>OutputStream类是所有字节输出流类的基类,也是个抽象类。

2>在Java中大多数流类都是成对出现的,了解这一规律有利于大家对流类的掌握。

3>OutputStream类的常用方法:

void write(int b):写入单个字节到输出流。

void write(byte[] b):将字节数组b中的数据写入此输出流。

void write(byte[] b,int off,int len):将数组b内从b[off]开始的len个字节写入此输出流。

void flush():清空输出流缓冲区。

void close():关闭输出流。

例子(向文件输出内容):

 

public staticvoid main(String[] args) {
try {
FileOutputStreamfos=new FileOutputStream(new File("test.txt"));
for (int i = 97;i < 123; i++) {
fos.write((char)i);
}
fos.flush();
System.out.println("写入成功!");
} catch(FileNotFoundException e) {
e.printStackTrace();
} catch(IOException e) {
e.printStackTrace();
}
}

 

数据流

1>数据流以与机器无关方式从底层读取或者写入基本Java数据类型的流。

2>数据流是处理流,需要连接嵌套其它流。

3>数据流属于字节流

DataInputStream-数据输入流,是InputStream的子类。

DataOutputStream-数据输出流,是OutputStream的子类。

示例一(将十个浮点数写入文件)

 

public staticvoid main(String[] args){
DataOutputStreamdos=null;
try {
File file=newFile(
    "f:"+File.separator+"ja_2"+File.separator+"nums");
dos=newDataOutputStream(new FileOutputStream(file));
for(inti=0;i<10;i++){
    dos.writeDouble(Math.random()*10);
}
dos.flush();
System.out.println("写入成功!");
} catch(Exception e) {
    e.printStackTrace();
} finally{
    try {dos.close();} catch (Exception e) {}
}
}

 

示例二:从文件中读出浮点数

 

public staticvoid main(String[] args){
DataInputStreamdis=null;
try {
File file=newFile(
"f:"+File.separator+"ja_2"+File.separator+"nums");
dis=newDataInputStream(new FileInputStream(file));
while(true){
    System.out.println(dis.readDouble());
}
} catch(EOFException e) {
    //readDouble()当达到流结尾抛出此异常
    System.out.println("文件读取完毕!");
} catch(Exception e) {
    e.printStackTrace();
} finally{
    try {dis.close();} catch (Exception e1) {}
}
}

 

节点流和处理流

1>按照流是否直接与特定的节点(如磁盘、内存、设备等数据源)相连,可将流分为节点流和处理流。

2>节点流与具体节点相连接,直接读写节点数据,如:

FileInputStream

FileOutputStream

FileReader

FileWriter等等。

3>处理流与已存在的流相连接,通过调用所连接流的功能实现数据读写,其构造方法总要带一个其他流对象做参数。如下列出了部分处理流:

InputStreamReader

InputStreamWriter

BufferedReader

PrintWriter

DataInputStream 数据输入流

DataOutputStream 数据输出流

ObjectInputStream 对象输入流

ObjectOutputStream 对象输出流

4>流对象被其他处理流的多次连接,称为流的嵌套。

直接与数据源相连接的流是节点流

处理流连接节点流,提供附加性能

处理流可以被其它处理流继续连接,以获取需要的其它性能。

处理流不可以与节点(数据源)直接连接

 

字符流

文件与流简介(1)

Reader

 

1)Reader类是所有字符输入流类的基类,是个抽象类。

2)Reader的常用方法:

void close() :关闭输入源。

int read() :从输入流读取单个字符的整数表示,如果不存在则返回-1。

int read(char[] cbuf) :从输入流中将字符读入数组,返回实际读取的字符数,如果遇到文件结尾返回-1。

int read(char[] cbuf,int off,int len):将字符读入数组的某一部分。

boolean ready() :判断此流是否已准备好被读取。

long skip(long n) :跳过n个字符,返回跳过的字符数。

Writer

1)Writer类是所有字符输出流类的基类,也是个抽象类。

2)Writer的常用方法:

void write(int ch) :写入单个字符到调用的输出流。

void write(String str): 写入str到输出流。

void write(String str, int off,int len)写入字符串的某一部分。

void write(char[] cbuf):写入字符数组。

void write(char[] cbuf,int off,int len):写入字符数组的某一部分。

Writer append(char c) :将指定字符追加到此 writer。

void flush() :清空输出缓冲区。

void close() :关闭输出流。

FileReader

1)此类是Reader子类,是读取字符文件的便捷类,可以使用它直接读取文件的内容。

2)FileReader类常用构造方法

FileReader(Filefile)

FileReader(Stringfilename)

FileWriter

1)此类是Writer的子类,是向文件写入字符的便捷类,使用它可以方便地创建一个写文件的对象。

2)FileWriter类常用构造方法

FileWriter(Filefile)

FileWriter(Stringfilename)

FileWriter(Filefile,boolean append)

FileWriter(Stringfilename,boolean append)

BufferedReader

1)BufferedReader由Reader类扩展而来,提供通用的缓冲方式文本读取,而且提供了很实用的readLine()方法。

2)BufferedReader有两个构造函数:

BufferedReader(Reader in):创建使用缺省尺寸输入缓冲区的缓冲字符输入流。

BufferedReader(Reader in,int bufsize):创建一个使用指定大小输入缓冲区的缓冲字符输入流。

3)BufferedReader的常用方法

String readLine() :读取一个文本行。

PrintWriter

1)PrintWriter继承了Writer类,但除此之外此类还实现了PrintStream中的所有print()方法, PrintWriter可以直接输出字符串。

2)PrintWriter常用的构造方法:

PrintWriter(Writer out)

PrintWriter(OutputStream out)

void print(Object obj) :打印对象。

void println(Object obj) :打印对象后换行。

InputStreamReader

1)InputStreamReader继承了Reader,它实现了Reader的抽象方法。

2)InputStreamReader是字节流通向字符流的桥梁,它使用指定的字符集(charset)读取字节并将其解码为unicode字符。

3) 注:FileReader即为InputStreamReader直接子类,使用默认字符集。

4) InputStreamReader的常用构造方法:

InputStreamReader(InputStream in):创建一个使用默认字符集的InputStreamReader。

InputStreamReader(InputStream in,String charsetName) :创建使用指定字符集的InputStreamReader。

5)InputStreamReader的常用方法:

String getEncoding():返回此流使用的字符编码的名称

6)一个有关InputStreamReader类的例子:

public staticvoid main(String[] args) {

File file=newFile("test.txt");

InputStreamis=null;

try {

is = newFileInputStream(file);

} catch(FileNotFoundException e) {

e.printStackTrace();

}

InputStreamReaderreader=new InputStreamReader(is);

try {

int i=0;

while((i=reader.read())>0){

 System.out.print((char)i+"\t");

}

} catch(IOException e) {

e.printStackTrace();

}

}

OutputStreamWriter

1)OutputStreamWriter继承了Writer,它实现了Writer的抽象方法。

2)OutputStreamWriter是字符流通向字节流的桥梁,这刚好与InputStreamReader相反。它使用指定的字符集(charset)将要写入流中的unicode字符编码成字节

3)注:FileWriter即为OutputStreamWriter直接子类,使用默认字符集。

4)OutputStreamWriter的常用构造方法:

public OutputStreamWriter(OutputStream out):创建使用默认字符编码的OutputStreamWriter。

public OutputStreamWriter(OutputStream out,String charsetName):创建使用指定字符集的 OutputStreamWriter。

String getEncoding() :返回此流使用的字符编码的名称。

5)一个有关OutputStreamWriter类的例子:

publicstatic void main(String[] args) {

Stringstr=“行知汇元。";

try {

OutputStreamWriterosw =new OutputStreamWriter(new FileOutputStream(newFile("test.txt")));

osw.write(str,0, str.length());

osw.flush();

osw.close();

System.out.println("文件写入成功。");

} catch(FileNotFoundException e) {

e.printStackTrace();

} catch(IOException e) {

e.printStackTrace();

}

}

对象流

1)对象流:

     就是将对象的内容进行流化,也即是将对象的内容转化成二进制流,对象流是处理流。

2)特点:

     1、流化后的对象可以进行读写操作。

     2、流化后的对象可以进行网络之间的传输。

3)对象流的构造:

     对象输入流(ObjectInputStream):ObjectInputStream in=new ObjectInputStream(输入流对象);

     相应的方法:in.readObject();

     对象输出流(ObjectOutputStream):ObjectOutputStream out=new ObjectOutputStream(输出流对象);

     相应的方法:out.writeObject(Object obj);

序列化

1)序列化:

     所谓序列化就是将对象输出到流中,或者从流中读取对象。

2) 序列化的作用:

     1、利用对象的序列化,可以实现轻量级持久性,这意味着一个对象的生存周期并不取决于程序是否正在执行,它可以生存于程序的调用之间。

     2、通过将一个序列化的对象写入磁盘,然后在重新调用时恢复该对象,以实现持久性的效果。 

3)序列化分为:序列化和反序列化。

     序列化:就是将对象的内容分解成字节流,以便存储在文件中或在网络上传输。

     反序列化:就是打开并读取字节流,且从该流中恢复该对象。

4)注意:

     只有序列化的对象才可以存储在存储设备上。

序列化的实现

     将需要被序列化的类实现Serializable接口,然后使用一个输出流(如:FileOutputStream等)来构造一个对象输出流ObjectOutputStream对象,使用该对象的writeObject(Object obj)方法,就可以将指定的对象obj写入到文件或传输于网络。

 

序列化对象的代码:

文件与流简介(1)

反序列化的实现

     将需要被序列化的类实现Serializable接口,然后使用一个输入流(如:FileInputStream等)来构造一个对象输入流ObjectIntputStream对象,使用该对象的readObject()方法,获得对象输入流中的对象。

 

反序列化对象的代码:

文件与流简介(1)

注意:

1、只有实现java.io.Serializable接口的类才可以启用序列化功能。未实现此接口的类将无法启用任何状态的序列化和反序列化。

2、 如果某个类能够被序列化,其子类也可以被序列化。

3、对象的(反)序列化仅针对非瞬时状态实例成员变量:使用static或者transient修饰的成员数据不能被(反)序列化。

注:static代表类的状态,而非实例状体;transient代表对象的临时数据,即处于瞬时状态。

完整例子:

1、 自定义一个类SerializableObject实现接口 Serializable:

文件与流简介(1)

2、序列化类SerializableObject的对象:

文件与流简介(1)

3、反序列化类SerializableObject的对象:

文件与流简介(1)

4、测试类Test:

文件与流简介(1)