首页 > 代码库 > java基础之IO操作

java基础之IO操作

IO操作

  •        ·文件类的使用(File)
  •        ·IO中流的基本使用(字符流、字节流、内存流、打印流)
  •        ·System类对IO的支持
  •        ·对象序列化的问题

在整个的IO操作中,流的操作分为两种:

         ·字节流

                   字节输出流:OutputStream

                   字节输入流:InputStream

         ·字符流

                   字符输出流:Writer

                   字符输入流:Reader

IO操作的基本步骤:

         在Java的使用io的话,必须要按照以下的几个步骤进行(对文件操作来说):

  •          ·使用File找到一个文件
  •          ·使用字节流或者字符流的子类为OutputStream,InputStream,Writer,Reader实例化
  •          ·进行读写操作
  •          ·关闭流

File文件操作类

File是IO操作中,唯一可以代表磁盘本身类,File定义了一些与平台无关的操作方法来操作文件,比如说可以创建和删除文件等等。常用操作方法如下:

         ·public File(String pathname):构造方法,构造一个有路径的文件(文件夹)目录

         ·public boolean createNewFile()   throws IOException:创建文件

         ·public boolean delete():删除文件

         ·public boolean exists():判断文件是否存在

         ·public boolean isDirectory():判断文件是否是文件夹

         ·public long length():返回文件的字节长度

         ·public String[] list():返回文件夹中所有文件

         ·public boolean mkdir():创建文件夹

         ·public boolean mkdirs():创建全路径文件夹(推荐使用)

范例:在D盘中创建 wanczy.txt

在正常开发中,我们一般判断文件是否存在,存在则删除再创建,不存在则创建。

public static void main(String[] args) {
        File file = new File("D:" + File.separator + "wanczy.txt");
     if(file.exists()){
       file.delete();//删除文件
      }
try { file.createNewFile();//创建文件 } catch (IOException e) { e.printStackTrace(); }

范例:取得“D:\软件”目录中所有的文件名称

package com.wanczy.ioDemo;

import java.io.File;

public class IODemo03 {
    public static void main(String[] args) {
        loop("D:" + File.separator + "软件");
    }
    
    public static void loop(String path){
        File file = new File (path);
        String s[] = null;
        if(file.isDirectory()){//是文件夹
            s = file.list();//取得所有的文件名称
            for (int i = 0; i < s.length; i++) {
                loop(path+File.separator+s[i]);//递归,方法自己调用自己
            }
        }else{
            System.out.println(path);
        }
        
    }
}

 

3.字节流输出流outputStream

在IO操作包中,OutputStream是字节输出流的最大的父类

public abstract class OutputStream

extends Object

implements Closeable, Flushable

通过类的定义发现,此类是一个抽象类,所以使用的时候必须要依靠子类,如果我们现在系那个要完成的是对文件进行操作,那么需要使用FileOutputStream为OutputStream实例化。

FileOutputStream常用构造方法:

         ·public FileOutputStream(File file) throws FileNotFoundException:创建一个文件字节输出流,连接到一个具体的文件,文件的内容是以覆盖的形式进行操作

         ·public FileOutputStream(File file, boolean append)  throws FileNotFoundException:创建一个字节文件输出流,链接到一个文件,如果第二个参数的值为true话,表示的内容以追加的形式进行操作

 

OutputStream类常用方法:

  •          ·public void write(byte[] b) throws IOException:将整个字节数组写入到流中
  •          ·public void write(int b)  throws IOException:将一个字节写入到流中
  •          ·public void write(byte[] b, int off,  int len)  throws IOException:将字节数组的一部分写入到流中

范例:将“中华人民共和国”写入到 wanczy.txt文件中。

代码

我们现在的操作,明明是向文件中输入了内容,为什么还是叫做字节输出流呢?对于输入输出,参照物是程序,将程序中的内容写入到流中,那么就是 出,如果从流中读取内容到程序,那么叫做输入。o

以上的程序我们是将整个字节数组写入到流中,当然我们也可以一个字节一个字节的写入

package com.wanczy.ioDemo;
 
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
 
public class IODemo05 {
         public static void main(String[] args) throws Exception{
                   File file = new File("D:" + File.separator + "wanczy.txt");
                   OutputStream out = new FileOutputStream(file);
                   String s = "世界人民大团结万岁";
                   byte b[] = s.getBytes();//将字符串转换成字节数组
                   for (int i = 0; i < b.length; i++) {
                            out.write(b[i]);//写入一个字节
                   }
                   out.close();//关闭流
         }
}

 

目前文件中的内容是被覆盖,如果想要表示追加的话,我们在构造FileOutputStream的时候加入true作为参数。

3.字节输入流

使用InputStream可以读取流中的内容,此类定义如下:

public abstract class InputStream
extends Object
implements Closeable

   

发现此类依然是一个抽象类,如果要使用的话,必须依靠子类,现在我们需要从文件中读取内容,那么肯定需要好似用FileInputStream,FileInputStream的构造方法:

         ·public FileInputStream(File file) throws FileNotFoundException:构造FileInputStream对象,连接到一个文件

如果要读取内容的话,我们必须要对InputStream读取的方法有所了解:

         ·public abstract int read()  throws IOException:读取一个字节

         ·public int read(byte[] b)  throws IOException:将内容读取到一个字节数组中

范例:从D:wanczy.txt 读取文件

public static void main(String[] args) throws Exception{
        File file = new File("D:" + File.separator + "wanczy.txt");
        InputStream in = new FileInputStream(file);
        byte b[] = new byte[1024];
        int length = in.read(b);//读取内容到字节数组
        String s = new String(b,0,length);//将字节数组转换为字符串
        System.out.println(s);
        in.close();
    }

以上的程序是比较常见的形式,但是依然是有缺点,会受到数组开辟空间的限制,如果想动态的开辟数组的空间,则可以根据文件的大小来决定。

public static void main(String[] args) throws Exception{
        File file = new File("D:" + File.separator + "wanczy.txt");
        InputStream in = new FileInputStream(file);
        int length = (int)file.length();//取得文件的字节长度
        byte b[] = new byte[length];
        in.read(b);//读取内容到字节数组
        String s = new String(b);//将字节数组转换为字符串
        System.out.println(s);
        in.close();
    }
}

4.字符输出流

Writer类是IO操作包中字符输出的最高的父类,主要功能是完成字符流的输出,定义格式如下:

public abstract class Writer
extends Object
implements Appendable, Closeable, Flushable

 

与字节操作的OutputStream和InputStream一样,都是抽象类,如果要进行文件操作的话,则必须使用子类FileWriter,来看到此类的构造方法:

         ·public FileWriter(File file)   throws IOException:构造文件字符输出流对象,链接到一个文件,表示内容覆盖

         ·public FileWriter(File file,boolean append)   throws IOException:构造文件字符输出流,连接到一个文件,如果第二个参数的值为true的话,那么表示追加

我们还需要知道Writer常用的写入的方法:

         ·public void write(char[] cbuf) throws IOException:将整个字符数组写入流中

         ·public void write(String str)  throws IOException:将字符串写入到流

         ·public void write(int c) throws IOException:将一个字符写入到流中

范例:将字符串写入到流中

public class IODemo09 {
    public static void main(String[] args) throws Exception{
        File file = new File("D:" + File.separator + "wanczy.txt");
        Writer out = new FileWriter(file,true);
        String s = "没有";
        out.write(s);//将字符串直接写入到流中
        out.close();
    }

 5.字符输入流

字符输入流Reader是字符输入操作的最高父类,类的定义如下:

public abstract class Readerextends Objectimplements Readable, Closeable

发现此类也是一个抽象类,现在要从文件流中读取内容,那么肯定是需要子类FileReader,观察FileReader的构造方法:

         ·public FileReader(File file) throws FileNotFoundException:创建文件字符输入流,并且链接到文件

肯定Reader里面有相应的读取的方法:

  •          ·public int read() throws IOException:读取单个字符
  •          ·public int read(char[] cbuf) throws IOException:读取到一个字符数组

范例:

    File file= new File("D:"+File.separator+"软件"+File.separator+"11.txt");
        Reader re= new FileReader(file);
        char[] c=new char[1024];
        /*int length= re.read(c);//将内容读取到字符数组中
        String s = new String(c,0,length);*/
        for (int i = 0; i < c.length; i++) {
            c[i] =(char) re.read();//读取一个字符
        }
        String s=new String(c);
        System.out.println(s);
        re.close();

6.字节流和字符流的区别

以上的输出和输入的操作,都是分为两组,一组是字节操作,一组是字符操作,我们知道字节输入和输出流是操作字节的,字符输入输出是操作字符的,那么在开发中使用哪一组更好呢?为了简单说明问题,我们可以写两个程序,一个是使用字节输出流,一个使用字符输出流。

         ·使用字节输出流(不进行流的关闭)

使用字节输出流(不进行流的关闭)
package com.wanczy.ioDemo;

import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;

public class IODemo04 {
    public static void main(String[] args) throws Exception{
        File file = new File("D:" + File.separator + "wanczy.txt");
        OutputStream out = new FileOutputStream(file);
        String s = "中华人民共和国万岁";
        byte b[] = s.getBytes();//将字符串转换成字节数组
        out.write(b);//将字节数组写入到流中
//        out.close();//关闭流
    }
}
·字符输出流
package com.wanczy.ioDemo;

import java.io.File;
import java.io.FileWriter;
import java.io.Writer;

public class IODemo10 {
    public static void main(String[] args) throws Exception{
        File file = new File("D:" + File.separator + "wanczy.txt");
        Writer out = new FileWriter(file);
        String s = "社会主义好";
        char c[] = s.toCharArray();//将字符串转换成字符数组
        out.write(c);//将字符数组写入到流中
//        out.close();

      out.flush();//刷新
} }

如果使用字节输出流和字符输出流都不进行关闭流的操作,那么字符输出流不能将内容写入到文件,现在我们可以试一下Writer类提供的另外的方法:

         ·public abstract void flush() throws IOException刷新

刷新之后,使用字符输出流也是同样可以输出内容的,但是从实际上来讲,最早的程序中,并没有刷新,而是关闭,所以表示在关闭的时候会进行强制的刷新,刷新就是缓冲区(内存),现在我们就可以得出结论:

字节流在操作文件的时候,是直接操作文件的,不使用缓冲区

         ·字节——文件

字符流在操作的时候,是通过缓冲区间接操作文件的

         ·字符——缓冲区——文件

所有,两者相比较,使用字节流较多,而且文件中的内容也是以字节的形式存在,但是在处理中文的时候,字符流使用较多。

7 内存操作流

 

以上的程序,我们都是对文件进行操作的,如果有临时的信息需要通过IO进行操作的,那么使用文件肯定会比较麻烦,所以IO中提供了内存操作流,内存作为输出和输入的目标

 

         ·内存输出流:ByteArrayOutputStream,是OutputStream的子类

 

         ·内存输入流:ByteArrayInputStream,是InputStream的子类

 

ByteArrayOutputStream构造方法:public ByteArrayOutputStream()

 

ByteArrayInputStream构造方法:public ByteArrayInputStream(byte[] buf),表示将信息放入到字节数组

 

对于读写的操作,也都是继承自父类的操作。

 

范例:将内容写入到内存,再读取

//写入到内存,再读取到程序里
        String s = "abd";
        OutputStream out = new ByteArrayOutputStream();
        out.write(s.getBytes());//将内容写入到内存中
        byte[] b=s.getBytes();
        InputStream in =new ByteArrayInputStream(b);
        int len=in.read(b);
        String s1=new String(b,0,len);
        System.out.println(s1);

.8 打印流

我们学习的OutputStream可以完成数据的输出,此类有一个子类:

 

public class PrintStream extends FilterOutputStreamimplements Appendable, Closeable

现在我们来观察一下此类的构造方法:

public PrintStream(OutputStream out),发现构造方法是父类的对象,这种开发模式我们叫做装饰模式,可以根据实例化PrintStream对象的不同,完成向不同的目标输出。

观察PrintStream常用的方法:

         ·public void print(常见类型对象或者基本数据类型)

范例:向文件中输出public void print(Object obj)

public static void main(String[] args) throws Exception{
        String s = "南昌人民好";
        PrintStream ps = new PrintStream( new FileOutputStream(new File("D:" + File.separator + "jjm.txt"),true));
        ps.println(s);
        ps.println("全中国人民都好");
        ps.println("其实世界人民都很好");
        ps.close();

现在可以得出一个结论,使用打印流是最方便的输出,以后在开发中,可以尽量的使用打印流进行操作。

9 System类对IO的支持

 

System类中有三个常量:

 

         ·out:标准的输出,输出的位置就是控制台

 

         ·in:表示标准的输入,输入的位置是键盘

 

         ·err:错误输出,输出的位置就是控制台

 

对于out 和err 来说,都是PrintStream这个打印流的对象,所以我们System.out可以向控制台输出内容。

 

java基础之IO操作