File类是java.io包中唯一代表磁盘文件本身的对象。File类定义了一些与平台无关的方法来操作文件,可以通过调用File类中的方法,实现创建,删除,重命名文件等操作。File类的对象主要用来获取文件本身的一些信息,如文件所在的目录,文件的长度,文件读写权限等。数据流可以将数据写入到文件中,文件也是数据流最常用的数据媒体。
文件的创建与删除
可以使用File类创建一个文件对象。通常使用以下3种构造方法来创建文件对象。
(1)File(String pathname)
该构造方法通过将给定路径名字符串转换为抽象路径名来创建一个新的File实例。
语法如下:
New File(String pathname)
其中,pathname指路径名称(包含文件名)。例如:
File file=new File(“d:/1.txt”);
(2)File(String parent,String child)
该构造方法根据定义的父路径和子路径字符串(包含文件名)创建一个新的File对象。
语法如下:
new File(String parent,String child)
parent:父路径字符串。例如,D:/或D:/doc。
child:子路径字符串。例如,letter.txt。
(3)File(File f,String child)
该构造方法根据parent抽象路径名和child路径名字符串创建一个新File实例。
语法如下:
new File(File f,String child)
f:父路径对象,例如,D:/doc/。
child:子路径字符串,例如,letter.txt
如果当前目录中不存在名称为word的文件,File类对象可通过调用createNewFile()方法创建一个名称为word.txt的文件,可以通过文件对象的delete()方法将其删除,如下例:
package kop;
import java.io.*;
public class op {
public static void main(String[] args){
File file=new File("D:/word.txt");
if(file.exists()){
file.delete();
System.out.println("文件已删除");
}else{
try{
file.createNewFile();
System.out.println("文件已创建");
}catch(Exception e){
e.printStackTrace();
}
}
}
}
获取文件信息
File类的常用方法
方法 | 返回值 | 说明 |
getName() | String | 获取文件 |
canRead() | Boolean | 判断文件是否是可读的 |
canWrite() | Boolean | 判断文件是否可以被写入 |
exits() | Boolean | 判断文件是否存在 |
length() | Long | 获取文件的长度(以字节为单位) |
getAbsolutePath() | String | 获取文件的绝对路径 |
getParent() | String | 获取文件的父路径 |
isFile() | Boolean | 判断文件是否存在 |
isDirectory() | Boolean | 判断文件是否是一个目录 |
isHidden() | Boolean | 判断文件是否是隐藏文件 |
lastModified() | Long | 获取文件最后修改时间 |
下面通过实例来介绍如何使用上述的某些方法来获取文件信息。
package kop;
import java.io.*;
public class op {
public static void main(String[] args){
File file=new File("D:/word.txt");
if(file.exists()){
String name=file.getName();
long length=file.length();
boolean hidden=file.isHidden();
Long time=file.lastModified();
System.out.println("文件名称:"+name);
System.out.println("文件长度是:"+length);
System.out.println("该文件是隐藏文件吗?:"+hidden);
System.out.println("最后修改时间:"+time);
System.out.println(file.getParent());
}
else{
System.out.println("该文件不存在");
}
}
}
文件输入/输出流
程序运行期间,大部分数据都在内存中进行操作,当程序结束或关闭时,这些数据将消失。如果需要将数据永久保存,可使用文件输入/输出流与指定的文件建立连接,将需要的数据永久保存到文件中。
FileInputStream与FileOutputStream类
FileInputStream类与FileOutputStream类都用来操作磁盘文件。如果用户的文件读取需求比较简单,则可以使用FileInputStream类,该类继承自InputStream类。FileOutputStream类与FileInputStream类对应,提供了基本的文件写入能力。FileOutputStream类与OutputStream类的子类。
FileInputStream类常用的构造方法如下:
FileInputStream(String name)。
FileInputStream(File file)。
第一构造方法使用给定的文件名name创建一个FileInputStream对象,第二个构造方法使用File对象创建FileInputStream对象。第一个构造方法比较简单,但第二个构造方法允许在把文件连接输入流之前对文件作进一步分析。
FileOutputStream类有与FileInputStream类相同的参数构造方法,创建一个FileOutputStream对象时,可以指定不存在的文件名,但此文件不能是一个已被其他程序打开的文件。下面的实例就是使用FileInputStream与FileOutputStream类实现文件的读取与写入功能的。
例子:
package kop;
import java.io.*;
public class op {
public static void main(String[] args){
File file=new File("D:/word.txt");
try{
FileOutputStream out=new FileOutputStream(file);
byte buy[]="今天是星期三,天气晴。".getBytes();
out.write(buy);
out.close();
}catch(Exception e){
e.printStackTrace();
}
try{
FileInputStream in=new FileInputStream(file);
byte byt[]=new byte[1024];
int len=in.read(byt);
System.out.println("文件中的信息是:"+new String(byt,0,len));
in.close();
}catch(Exception e){
e.printStackTrace();
}
}
}
说明:虽然Java在程序结束时自动关闭所有打开的流,但是当使用完流后,显式地关闭所有打开的流仍是一个好习惯。一个被打开的流有可能会用尽系统资源,这取决于平台和实现。如果没有将打开的流关闭,当连云港一个程序试图打开另一个流时,可能会得不到需要的资源。
FileReader和FileWriter类
使用FileOutputStream类向文件中写入数据与FileInputStream类从文件中将内容读出来,都存在一点不足,即这两个类都只提供了对字节或字节数组的读取方法。由于汉子在文件中占用两个字节,如果使用字节流,读取不好可能会出现乱码现象,此时采用字符流Reader或Writer类即可避免这种现象。
FileReader和FileWriter字符流对应FileInputStream和FileOutputStream类。FileReader流顺序地读取文件,只要不关闭流,每次调用read()方法就顺序地读取源中其余的内容,直到源的末尾或流被关闭。
下面介绍利用FileReader与FileWriter类的用法
package kop;
import java.io.*;
public class op {
public static void main(String[] args){
File file=new File("D:/word.txt");
try{
FileWriter out=new FileWriter(file);
String s="今天星期三,天气晴.";
out.write(s);
out.close();
}catch(Exception e){
e.printStackTrace();
}
try{
FileReader in=new FileReader(file);
char a[]=new char[1024];
int len=in.read(a);
System.out.println("文件中的信息是:"+new String(a,0,len));
in.close();
}catch(Exception e){
e.printStackTrace();
}
}
}
带缓存的输入/输出流
缓存是I/O的一种性能优化。缓存流为I/O流增加了内存缓存区。有了缓存区,使得在流上执行skip(),mark()和reset()方法都成为可能。
BufferedInputStream和BufferedOutputStream类
BufferedInputStream类可以对所有InputStream类进行带缓存区的包装以达到性能的优化。BufferedInputStream类有两个构造方法:
BufferedInputStream(InputStream in)。
BufferedInputStream(InputStream in,int size)。
第一种形式的构造方法创建了一个带有32个字节的缓存流;第二种形式的构造方法按指定的大小来创建缓存区。一个最优的缓存区的大小,取决于它所在的操作系统,可用的内存空间以及机器配置。从构造方法可以看出,BufferedInputStream对象对于InputStream类对象之前。
文件-----------》InputStream--------------》BufferedInputStream---------------------》目的地
使用BufferedOutputStream输出信息和用OutputStream输出信息完全一样,只不过BufferedOutputStream有一个flush()方法用来将缓存区的数据强制输出完。BufferedOutputStream类也有两个构造方法
BufferedOutputStream(OutputStream in)。
BufferedOutputStream(OutputString in,int size)。
第一种构造方法创建一个有32个字节的缓存区,第二种方法以指定的大小来创建缓存区
注意:flush()方法就是用于即使在缓存区没有满的情况下,也将缓存区的内容强制写入到外设,习惯上称这个过程为刷新。flush()方法只对使用缓存区的OutputStream类的子类有效,当调用close()方法时,系统在关闭流之前,也会将缓存区中信息刷新到磁盘文件中。
BufferedReader与BufferedWriter类
BufferedReader类与BufferedWriter类分别继承Reader类与Writer类。这两个类同样具有内部缓存机制,并可以以行为单位进行输入/输出。
BufferedReader类常用的方法如下:
read()方法:读取单个字符。
readLine()方法:读取一个文本行,并将其返回为字符串。若无数据可读,则返回null。
BufferedWriter类中的方法都返回void。常用的方法如下。
write(String s,int off,int len)方法:写入字符串的某一部分。
flush()方法:刷新该流的缓存。
newLine()方法:写入一个行分隔符。
在使用BufferedWriter类的Write()方法时,数据并没有立刻被写入至输出流,而是首先进入缓存区中。如果想立刻将缓存区中的数据写入输出流,一定要调用flush()方法。
通过例子:
package kop;
import java.io.*;
public class op {
public static void main(String[] args){
File file=new File("D:/word.txt");
String content[]={"好久不见","最近好吗","常联系"};
try{
FileWriter out=new FileWriter(file);
BufferedWriter bufw=new BufferedWriter(out);
for(int k=0;k<content.length;k++)
{
bufw.write(content[k]);
bufw.newLine();
}
bufw.close();
out.close();
}catch(Exception e){
e.printStackTrace();
}
try{
FileReader in=new FileReader(file);
BufferedReader bufr=new BufferedReader(in);
String s=null;
int i=0;
while((s=bufr.readLine())!=null){
i++;
System.out.println("第"+i+"行:"+s);
}
bufr.close();
in.close();
}catch(Exception e){
e.printStackTrace();
}
}
}
数据输入/输出流
数据输入/输出流(DataInputStream类与DataOutputStream类)允许应用程序以与机器无关的方式从底层输入流中读取基本Java数据类型。也就是说,当读取一个数据时,不必再关心这个数值应当是哪种字节。
DataInputStream类与DataOutputStream类的构造方法如下。
DataInputStream(InputStream in):使用指定的基础InputStream创建一个DataInputStream。
DataOutputStream(OutputStream out):创建一个新的数据输出流,将数据写入指定基础输出流。
DataOutputStream类提供了如下3种写入字符串的方法。
writeBytes(String s)。
writeChars(String s)。
writeUTF(String s)。
由于Java中的字符是Unicode编码,是双字节的,writeBytes只是将字符串中的每一个字符的低字节内容写入目标设备中;而writeChars将字符串中的每一个字符的两个字节的内容都写到目标设备中;writeUTF将字符串按照UTF编码后的字节长度写入目标设备,然后才是每一个字节的UTF编码。
DataInputStream类只提供了一个readUTF()方法返回字符串。这是因为要在一个连续的字节流读取一个字符串,如果没有特殊的标记作为一个字符串的结尾,并且不知道这个字符串的长度,就无法知道读取到什么位置才是这个字符串的结束。DataOutputStream类中只有writeUTF()方法向目标设备中写入字符串的长度,所以也能准确地读回写入字符串。
package kop;
import java.io.*;
public class op {
public static void main(String[] args){
File file=new File("D:/word.txt");
String content[]={"好久不见","最近好吗","常联系"};
try{
FileOutputStream fs=new FileOutputStream(file);
DataOutputStream ds=new DataOutputStream(fs);
ds.writeUTF("使用writeUFT()方法写入数据;");
ds.writeChars("使用writeChars()方法写入数据;");
ds.writeBytes("使用writeBytes()方法写入数据,");
ds.close();
FileInputStream fis=new FileInputStream(file);
DataInputStream dis=new DataInputStream(fis);
System.out.print(dis.readUTF());
}catch(Exception e){
e.printStackTrace();
}
}
}
运行结果如下:
使用记事本程序将word.txt打开,如图所示,尽管在记事本程序中看不出writeUTF()写入的字符串是“使用writeUFT()方法写入数据”,但程序通过readUTF()读回后显示在屏幕上的仍是“使用writeUFT()方法写入数据”。但如果使用writeChars()和writeBytes()方法写入字符串后,再读取回来就不容易了,读者不妨编写程序尝试一下。