一、File对象的操作
File类提供了管理文件或目录的方法。File实例表示真实文件系统中的一个文件或者目录
构造函数 File(String pathname); File(String dir, String subpath);
常用方法 canRead()、canWrite()、exists() 和 length()等等
文件的信息
- String getName( ); //获得文件(目录)名
- String getAbsolutePath() //获得绝对路径
- String getParent( ); //获得上级目录名
文件属性
- boolean exists( ); //是否存在
- boolean canWrite( );//是否可写
- boolean canRead( );//是否可读
- boolean isFile( ); //是否是一个文件
- boolean isDirectory( );//是否是一个目录
文件信息 目录操作
- long lastModified( );//文件最后修改日期
- long length( ); //文件长度(字节数长度)
- boolean delete( );//删除当前文件对象表示的文件
- boolean mkdir( ); //创建一个目录
- boolean createNewFile(); //创建文件
- String[] list( ); //求出目录里所有的文件或目录名
- File[] listFiles();//求目录里所有的文件对象
1、一个File类的对象,表示磁盘上的文件或目录。
2、File提供了与平台无关的方法来对磁盘上的文件或目录进行操作。
3、File类直接处理文件和文件系统。
4、File类没有指定信息怎样从文件读取或向文件存储。
1 package io;
2
3 import java.io.File;
4 import java.io.IOException;
5
6 public class FileTest
7 {
8 public static void main(String[] args) throws IOException
9 {
10 File file = new File("f:/migu");
11 file.mkdir();
12 //判断该抽象名表示的目录是否存在
13 if(file.exists() && file.isDirectory())
14 {
15 System.out.println("migu 目录存在");
16 File file1 = new File("f:/migu/UES.txt");
17 File file2 = new File("f:\migu\CMU.txt");
18 //创建文件
19 file1.createNewFile();
20 file2.createNewFile();
21 File file3 = new File("f:/migu/插件/支付中心");
22 //创建此抽象名表示的目录,以及所有必需但是不存在的父目录
23 file3.mkdirs();
24 File[] files = file.listFiles();
25 //该方法返回该路径下这一层的所有文件和目录
26 for(File f : files)
27 {
28 System.out.println("migu目录下的文件名:" + f.getName());
29 System.out.println("migu目录文件的绝对路径:" + f.getAbsolutePath());
30 }
31 } else {
32 System.out.println("migu 目录不存在");
33 }
34
35 }
36 }
执行结果:
migu 目录存在
migu目录下的文件名:CMU.txt
migu目录文件的绝对路径:f:miguCMU.txt
migu目录下的文件名:UES.txt
migu目录文件的绝对路径:f:miguUES.txt
migu目录下的文件名:插件
migu目录文件的绝对路径:f:migu插件
这个DEMO展示的跟File类相关的方法都是简单易懂的,其中有两个地方需要强调下:
1、mkdirs是创建抽象名表示的文件或者目录,并且还会创建该目录或者文件的所有不存在的父目录。
2、在16、17行,我这里用了两种不同的路径分割符来表示抽象路径,从运行结果来看都是可行的。那么两者有什么区别呢?
不同操作系统下文件分隔符:windows中是“”,linux中是“/”,在用JAVA代码去读取windows系统中磁盘上的文件时候,若要用“”,必须写成“\”,因为一个""在java中表示是转义符。所以用“\”代表“”。在这里我的建议是尽量都写成“/”,因为在所有的操作系统中“/”永远都是没有问题的。
二、java.io包
输入/输出处理是程序设计中非常重要的一部分,比如从键盘读取数据、从文件中读取数据或向文件中写数据等等。
java把一组有序的数据序列称为流(Stream)。根据操作的类型,可以把流分为输入流和输出流。
java I/O系统负责处理程序的输入和输出,I/O类库位于java.io包中,它对各种输入流和输出流进行了抽象。
按照最小的数据单元,可以把流分为:
- 字节流 抽象父类是 InputStream 和 OutputStream
- 字符流 抽象父类是 Reader 和 Writer
从1.4版本开始JAVA引入了NIO,用来提升I/O性能。I/O操作类在包java.io下,大概有将近80个类,这些类可以分为如下四组:
- 基于字节操作的I/O接口:InputStream和OutputStream
- 基于字符操作的I/O接口:Reader和Writer
- 基于磁盘操作的I/O接口:File
- 基于网络操作的I/O接口:Socket
从字面意思理解,前两组主要是传输数据的格式,后两组是传输数据的方式。虽然Socket类并不在java.io包下,但是我们仍然将其归类在一起来讨论。因为我个人认为I/O的核心问题要么是数据格式影响I/O操作,要么是传输方式影响I/O操作。最终的问题也就是将什么样的数据写到什么地方的问题。
1、从功能上:输入流、输出流
2、从结构上:字节流、字符流
3、从来源上:节点流、过滤流
其中InputStream/OutputStream是为字节流而设计的,Reader/Writer是为字符流而设计的。处理字节或者二进制对象使用字节流,处理字符或者字符串使用字符流。
在最底层,所有的输入/输出都是字节形式的,基于字符的流只在处理字符的时候提供方便有效的方法。
节点流是从特定的地方读写的流,例如磁盘或者内存空间,也就是这种流是直接对接目标的。
过滤流是使用节点流作为输入输出的,就是在节点流的基础上进行包装,新增一些特定的功能。
三、基于字节的流
-
InputStream
InputStream--字节输入流的顶级父类,抽象类
InputStream类中定义的方法
- int read(): 从输入流中读取一个字节,把它转换为0-255之间的整数,并返回这一整数,如果遇到输入流的结果,返回-1
- int read(byte[] b): 从输入流中读取若干个字节,把它们保存到参数b指定的字节数组中,返回的整数表示读取的字节数,如果遇到输入流的结尾,返回-1
- int read(byte[] b, int off, int len) 从输入流中读取若干个字节,把它们保存到参数b指定的字节数组中。参数off指定在字节数组中开始保存数据的起始下标,参数len指定读取的字节数目。返回的整数表示实际读取的字节数。如果遇到输入流的结尾,返回-1
- void close() :关闭输入流
- int available() :返回可以从输入流中读取的字节数目
- skip(long n):从输入流中跳过参数n指定数目的字节
- boolean markSupported(), void mark(int readLimit), void reset():用于重复读入数据
字节数组输入流:ByteArrayInputStream
1 byte[] b = {1,2,55,-1,-99,-87};
2 ByteArrayInputStream in = new ByteArrayInputStream(b);
3 int i = in.read();
4 while(i != -1){
5 System.out.println(i);
6 i = in.read();
7 }
8 try {
9 in.close();
10 } catch (IOException e) {
11 e.printStackTrace();
12 }
文件输入流:FileInputStream
1 FileInputStream in = new FileInputStream("d:/123.txt");
2 int data = in.read();
3 while(data != -1){
4 System.out.println(data);
5 data = in.read();
6 }
7 in.close();
1.DataInputStream类
- FilterInputStream的子类,FilterInputStream--过滤输入流,是一种用于扩展输入流的装饰器,它的子类分别用来扩展输入流的某一种功能
- DataInputStream类与DataOutputStream类搭配使用,可以按照与平台无关的方式从流中读取和写入基本数据类型(int、char、boolean等)的数据
- 构造方法:DataInputStream(InputStream in) :使用指定的底层 InputStream 创建一个 DataInputStream
演示示例
1 public static void main(String[] args) throws IOException {
2 FileOutputStream fout = new FileOutputStream("d:/123.txt");
3 DataOutputStream dout = new DataOutputStream(fout);
4 dout.writeBoolean(true);
5 dout.writeChar('A');
6 dout.writeInt(111);
7 dout.writeBytes("hello World");
8 dout.close();
9
10 DataInputStream din = new DataInputStream(new FileInputStream("d:/123.txt"));
11 System.out.println(din.readBoolean());
12 System.out.println(din.readChar());
13 System.out.println(din.readInt());
14 byte[] data = new byte[din.available()];
15 System.out.println(din.read(data));
16 System.out.println(new String(data));
17 din.close();
18 }
2.BufferedInputStream
BufferedInputStream类覆盖了被装饰的输入流的读数据行为,利用缓冲区来提高读数据。BufferedOutputStream则是带缓冲区的输出流
构造方法:
- BufferedInputStream(InputStream in) :通过原始输入流构造一个带缓冲区的输入流
- BufferedInputStream(InputStream in, int size) :通过一个原始输入流构造一个带缓冲区的输入流,参数size指定缓冲区大小,以字节为单位
示例
1 FileInputStream in = new FileInputStream("d:/123.txt");
2 BufferedInputStream bin = new BufferedInputStream(in,1024);
3 byte[] data = new byte[100];
4 int size = bin.read(data);
5 while(size != -1){
6 System.out.println(new String(data));
7 size = bin.read(data);
8 }
9 bin.close();
10 in.close();
-
OutputStream
OutputStream--字节输出流的顶级父类,抽象类
OutputStream类中定义的方法:
- void write(int b): 向输出流写出一个字节
- void write(byte[] b): 把参数b指定的字节数组中的所有字节写到输出流
- void write(byte[] b,int off, int len):把参数b指定的字节数组中的若干字节写到输出流,参数off为起始下标,参数len为长度
- void close():关闭输出流
- void flush():OutputStream类本身的flush方法不执行任何操作,它的一些带缓冲区的子类覆盖了flush方法,该方法强制把缓冲区内的数据写到输出流中
文件输出流:FileOutputStream
1 byte[] a = {89,97,86,111};
2 FileOutputStream out = new FileOutputStream("d:/12.txt");
3 out.write(a);
4 out.close();
Copy文件操作:
1 FileInputStream in = new FileInputStream("d:/aaa.rmvb");
2 FileOutputStream out = new FileOutputStream("d:/bbb.txt");
3 byte[] datas = new byte[1024];
4 int i = in.read(datas);
5 while(i != -1){
6 out.write(datas);
7 i = in.read(datas);
8 }
9 in.close();
10 out.close();
1、BufferedOutputStream
示例:
1 FileOutputStream fout = new FileOutputStream("d:/222.txt");
2 BufferedOutputStream bout = new BufferedOutputStream(fout,100);//缓冲区为2,假设改为100就会报异常
3 DataOutputStream dout = new DataOutputStream(bout);
4 dout.writeUTF("你好啊");
5 FileInputStream fin = new FileInputStream("d:/222.txt");
6 BufferedInputStream bin = new BufferedInputStream(fin);
7 DataInputStream din = new DataInputStream(bin);
8 din.readUTF(din);
2、PrintStream
示例:
1 PrintStream ps = new PrintStream("d:/ps.txt");
2 ps.print(true);
3 ps.println("aaaaa");
4 ps.print('A');
5 ps.print(123131);
6 ps.close();
四、基于字符的流
-
Reader
Reader -- 字符输入流,抽象类
1、FileReader
1 FileReader fr = new FileReader("d:/123.txt");
2 char[] chars = new char[1024];
3 int size = fr.read(chars);
4 while(size != -1){
5 System.out.println(new String(chars));
6 size = fr.read(chars);,
7 }
8 fr.close();
- InputStreamReader
InputStreamReader可以把InputStream类型转换为Reader类型
构造方法:
- InputStreamReader(InputStream in)创建一个使用默认字符集的 InputStreamReader。
- InputStreamReader(InputStream in, String charSet)创建使用指定字符集的 InputStreamReader。
1 BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
2 String str = br.readLine();
3 System.out.println(str);
4 br.close();
- BufferedReader
带有缓冲区的字符输入流
System.in:为InputStream类型,代表标准输入流,默认的数据源为键盘
System.out:为PrintStream类型,代表标准输出流,默认的数据汇是控制台
System.err:为PrintStream类型,代表标准错误输出也流,默认的数据汇是控制台
-
Writer
Writer-- 字符输入流,抽象类
- FileWriter
1 FileWriter fw = new FileWriter("fw.txt",true);
2 fw.write("你好,今天是星期四
");
3 fw.close();
五、对象的序列化
对象的序列化是指把对象写到一个输出流中,对象的反序列化是指从一个输入流中读取一个对象 java语言要求只有实现了java.io.Serializable接口的类的对象才能被序列化和反序列化。
实现序列化用ObjectOutputStream类
反序列化用ObjectInputStream类
-
ObjectOutputStream
ObjectOutputStream oout = new ObjectOutputStream(new FileOutputStream("d:/emp.obj"));
Employee emp = new Employee("aa", 23);
oout.writeObject(emp);
oout.close();
-
ObjectInputStream
1 ObjectInputStream oin = new ObjectInputStream(new FileInputStream("d:/emp.obj"));
2 Employee e = (Employee) oin.readObject();
3 System.out.println(e.getName());
4 System.out.println(e.getAge());
5 // 如果某些属性不想被序列化,则这些属性使用transient修饰符
六、总结
java I/O类库对各种常见的数据源、数据汇及处理过程进行了抽象。
java I/O类库具有两个对称性:
- 输入-输出对称
- 字节流和字符流对称