Java I/O

一、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-- 字符输入流,抽象类

  1.  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类库具有两个对称性:

  • 输入-输出对称
  • 字节流和字符流对称

 

原文地址:https://www.cnblogs.com/BalmyLee/p/10716068.html