【Java 输入、输出流】

Java 输入、输出流(I/O流)

  • 1 File类
    • 1.1 文件的属性
    • 1.2 目录
    • 1.3 文件的创建与删除
    • 1.4 运行可执行文件
  • 2 文件字节输入、输出流
    • 2.1 文件字节输入流
    • 2.2 文件字节输出流
  • 3 文件字符输入、输出流
  • 4 缓冲流

概述:输入、输出流提供一条通道程序,可以使用这条通道读取源中的数据或把数据传送到目的地。把输入流的指向称作源,程序从指向源的输入流中读取源中的数据;而输出流的指向是数据要去的一个目的地,程序通过向输出流中写入数据把数据传送到目的地。

【Java 输入、输出流】_第1张图片

1 File类

File对象主要用来获取文件本身的一些信息,不涉及对文件的读写操作

创建一个File对象的构造方法有3个,如下:

(1) File(String filename);//filename为文件名
(2) File(String directoryPath,String filename);//directoryPath是文件的路径
(2) File(File dir,String filename);//dir为一个目录

使用File(String filename);创建文件时,该文件位置默认为当前程序所在位置

1.1 文件的属性

File类的下列方法获取文件本身的一些信息。

public String getName()//获取文件的名字。
public boolean canRead()//判断文件是否是可读的。
public boolean canWrite()//判断文件是否可被写入。
public boolean exits()//判断文件是否存在。
public long length()//获取文件的长度(单位是字节)。
public String getAbsolutePath()//获取文件的绝对路径。
public String getParent()//获取文件的父目录。
public boolean isFile()//判断文件是否是一个普通文件,而不是目录。
public boolean isDirectroy()//判断文件是否是一个目录。
public boolean isHidden()//判断文件是否是隐藏文件。
public long lastModified()//获取文件最后修改的时间。

例子1.1(例子中使用上述的一些方法,获取某些文件的信息)

package Example1;

import java.io.File;

public class Example1_1 {
     
    public static void main(String[] args) {
     
        File file = new File("D:\\lifeilin", "lifeilin.txt");//创建文件对象
        try {
     
            file.createNewFile();//创建一个新文件
        } catch (Exception e) {
     
            e.printStackTrace();
        }
        System.out.println("文件是否存在:" + file.exists());
        System.out.println(file.getName() + "是可读的吗:" + file.canRead());
        System.out.println(file.getName() + "的长度:" + file.length());
        System.out.println(file.getName() + "的绝对路径:" + file.getAbsolutePath());
    }
}

【Java 输入、输出流】_第2张图片

1.2 目录

(1)创建目录
public boolean mkdir()

(2)列出目录中的文件

public String[] list();用字符串形式返回目录下的全部文件。
public File [] listFiles();用File对象形式返回目录下的全部文件。
public String[] list(FilenameFilter obj)用字符串形式返回目录下的指定类型的所有文件。
public File [] listFiles(FilenameFilter obj)用File对象形式返回目录下的指定类型所有文件。

上述两方法的参数FilenameFilter是一个接口,该接口有一个方法:
public boolean accept(File dir,String name);

例子2(Example1_2.java ,FileAccept.java ),例子2列出当前目录(应用程序所在的目录)下全部java文件的名字)

FileAccept.java

package Example1_2;

import java.io.*;

public class FileAccept implements FilenameFilter {
     //FileAccept类实现FilenameFilter接口
    private String extendName;
    public void setExtendName(String s) {
     
        extendName="."+s;
    }
    public boolean accept(File dir,String name) {
      //重写接口中的方法
        return name.endsWith(extendName);
    }
}

Example1_2.java

package Example1_2;

import java.io.*;

public class Example1_2 {
     
    public static void main(String[] args) {
     
        File dirFile = new File(".");
        FileAccept fileAccept = new FileAccept();
        fileAccept.setExtendName("java");
        String fileName[] = dirFile.list(fileAccept);
        for (String name : fileName) {
     
            System.out.println(name);
        }
    }
}

1.3 文件的创建与删除

当使用File类创建一个文件对象后,例如
File file=new File(“D:”,“letter.txt”);

如果D:\目录中没有名字为letter.txt文件,文件对象file调用方法
public boolean createNewFile();
文件对象调用方法public boolean delete()可以删除当前文件,
例如:
file.delete();

1.4 运行可执行文件

➢用Runtime类声明一个对象( Runtime类在java.lang包)
Runtime ec;
➢然后使用该类的getRuntime()静态方法创建这个对象:
ec=Runtime.getRuntime();
ec可以调用 exec(String command) 方法打开本地机的可执行
文件或执行一个操作。

下面例子演示打开本地的记事本:

import java.io.*;

public class Example1_4 {
     
    public static void main(String[] args) {
     
        try {
     
            Runtime ce = Runtime.getRuntime();//创建对象
            File file = new File("c:/windows", "Notepad.exe");
            ce.exec(file.getAbsolutePath());//打开本地记事本
        } catch (Exception e) {
     
            System.out.println(e);
        }
    }
}

2 文件字节输入、输出流

➢java.io包提供了大量的流类.
➢Java把InputStream 抽象类的子类创建的流对象称作字节输入流;OutputStream抽象类的子类创建的流对象称作字节输出流。
➢针对不同的源或目的地。java.io包为程序提供了相应的输入流或输出流。这些输入、输出流绝大部分都是InputStream、OutputStream、Reader或Writer的子类。

2.1 文件字节输入流

使用输入流通常包括4个基本步骤:
(1)设定输入流的源
(2)创建指向源的输入流
(3)让输入流读取源中的数据
(4)关闭输入流。

(1)构造方法:设定输入流源
使用FileInputStream类的下列构造方法创建指向文件的输入流。

FileInputStream(String name);//使用给定的文件名name创建FileInputStream流
FileInputStream(File file);//使用File对象创建FileInputStream流
//参数name和file指定的文件称为输入流的源

FileInpuStream输入流打开一个到达文件的通道(源就是这个文件,输入流指向这个文件)。当创建输入流时,可能会出现错误(也被称为异常)。例如,输入流指向的文件可能不存在。当出现I/O错误,Java 生成一个出错信号,它使用IOException (IO异常)对象来表示这个出错信号。程序必须在try-catch语句中的try块部分创建输入流,在catch (捕获)块部分检测并处理这个异常。例如,为了读取一个名为hello.txt 的文件,建立一个文件输入流in。

        try {
     
            FileInputStream in = new FileInputStream("hello.txt");//创建指向文件hello.txt的输入流
        } catch (IOException e) {
     
            System.out.println("File read error:" + e);
        }

或者:

		File f = new File("hello.txt");//指定输入流的源
        try {
     
            FileInputStream in = new FileInputStream(f);//创建指向源输入流
        } catch (IOException e) {
     
            System.out.println("File read error:" + e);
        }

(2)使用输入流读取字节
文件字节流可以调用从父类继承的read方法顺序地读取文件,只要不关闭流,每次调用read方法就顺序地读取文件中的其余内容,直到文件的末尾或文件字节输入流被关闭。

➢int read();读取单个字节的数据,返回字节值(0~255整数) ,如果未读出字节就返回-1。
➢int read(byte b[]);读取b.length个字节到字节数组b中,返回实际读取的字节数。如果到达文件的末尾,则返回-1。
➢int read(byte b[], int off, int len);读取len个字节到字节数组b中,并返回实际读取的字节数目。如果到达文件的末尾,则返回-1,参数off指定从字节数组的某个位置开始存放读取的数据。

(3) 关闭流
输入流都提供了关闭方法close(),尽管程序结束时会自动关闭所有的流,但是当程序使用完流后,显示地关闭任何打开的流仍然是一个良好的习惯,如果没有关闭那些被打开的流,那么就可能不允许另一个程序操作这些所用的资源。

下面例子使用文件字节流读文件内容:

import java.io.*;

public class Example2_1 {
     
    public static void main(String[] args) {
     
        int n = -1;
        byte[] a = new byte[100];
        try {
     
            File f = new File("D:\\","Example2_1.java");
            InputStream in = new FileInputStream(f);
            while ((n = in.read(a, 0, 100)) != -1) {
     
                String s = new String(a, 0, n);
                System.out.print(s);
            }
            in.close();
        } catch (IOException e) {
     
            System.out.println("File read Error" + e);
        }
    }
}

2.2 文件字节输出流

➢使用输出流通常包括4个基本步骤:
(1)给出输出流的目的地
(2)创建指向目的地的输出流
(3)让输出流把数据写入到目的地
(4)关闭输出流。

(1)构造方法
使用FileOutputStream类的下列具有刷新功能的构造方法创建指向文件的输出流。

FileOutputStream(String name);
FileOutputStream(File file);
//参数name和file指定的文件称为输出流的目的地

FileOutpuStream输出流开通一个到达文件的通道(目的地就是这个文件,输出流指向这个文件)。需要特别注意的是,如果输出流指向的文件不存在,Java 就会创建该文件,如果指向的文件是已存在的文件,输出流将刷新该文件(使得文件的长度为0)。另外,与创建输入流相同,创建输出流时,可能会出现错误(被称为异常),例如,输出流试图要写入的文件可能不允许操作或有其他受限等原因。所以必须在try-catch语句中的try块部分创建输出流,在catch (捕获)块部分检测并处理这个异常。例如,创建指向名为destin.txt的输出流out。

        try {
     
            FileOutputStream out = new FileOutputStream("destin.txt");//创建指向文件destin.txt的输出流
        } catch (IOException e) {
     
            System.out.println("File writeerror:" + e);
        }

或者:

		File f = new File("destin.txt");//指定输出流的源
        try {
     
            FileOutputStream out = new FileOutputStream (f);//创建指向源输出流
        } catch (IOException e) {
     
            System.out.println("File write:" + e);
        }

可以使用FileOutputStream类的下列能选择是否具有刷新功能的构造方法创建指向文件的输出流。

FileOutputStream(String name, boolean append) ;
FileOutputStream(File file, boolean append) ;

当用构造方法创建指向一个文件的输出流时,如果参数append取值true, 输出流不会刷新所指向的文件(假如文件已存在),输出流的write的方法将从文件的末尾开始向文件写入数据,参数append取值false, 输出流将刷新所指向的文件(假如文件已存在)。

(2)使用输出流写字节
输出流的wirie方法以字节单位向目的地写数据。

void write(int n)//向目的地写入单个字节。
void write(byte b[])//向目的地写入一个字节数组。
void write(byte b[],int off,int len)//从字节数组中偏移量off处取len个字节写到目的地。

FileOutputStream流顺序地写文件,只要不关闭流,每次调用write方法就顺序地向目的地写入内容,直到流被关闭。

(3)关闭流
通过调用close()方法,可以保证操作系统把流缓冲区的内容写到它的目的地,即关闭输出流可以把该流所用的缓冲区的内容冲洗掉(通常冲洗到磁盘文件上)。

例子2.2使用文件字节输出流写文件a.txt。
例子2.2首先使用具有刷新功能的构造方法创建指向文件a.txt的输出流、并向a.txt文件写入“新年快乐”,然后再选择使用不刷新文件的构造方法指向a.txt,并向文件写入( 即尾加)“ Happy New Year

import java.io.*;

public class Example2_2 {
     
    public static void main(String[] args) {
     
        byte[] a = "新年快乐".getBytes();
        byte[] b = "Happy New Year".getBytes();
        File file = new File("D:\\","a.txt");                         //输出的目的地
        try {
     
            OutputStream out = new FileOutputStream(file);      //指向目的地的输出流
            System.out.println(file.getName() + "的大小:" + file.length() + "字节");//a.txt的大小:0字节
            out.write(a);                                    //向目的地写数据
            out.close();
            out = new FileOutputStream(file, true);             //准备向文件尾加内容
            System.out.println(file.getName() + "的大小:" + file.length() + "字节");///a.txt的大小:8字节
            out.write(b, 0, b.length);
            System.out.println(file.getName() + "的大小:" + file.length() + "字节");///a.txt的大小:8字节
            out.close();
        } catch (IOException e) {
     
            System.out.println("Error " + e);
        }
    }
}

【Java 输入、输出流】_第3张图片

3 文件字符输入、输出流

➢Java把Reader抽象类的子类创建的流对象称作字符输入流;Writer抽象类的子类创建的流对象称作字符输出流。

与FileInputStream. FileOutputStream字节流相对应的是FileReader、FileWriter字符流(文件字符输入、输出流),FileReader 和FileWriter 分别是Reader和Writer的子类,其构造方法分别是:

FileReader (String filename) ; 
FileReader (File filename) ;

FileWriter (String filename) ; 
FileWriter (File filename) ;
FileWriter (String filename, boolean append) ; 
FileWriter (File filename,boolean append) ;

字符输入流和输出流的read和write方法使用字符数组读写数据,即以字符为基本单位处理数据。

➢1. Reader类提供的read方法以字符为单位顺序地读取源中的数据。

int read();
int read(char b[]);
int read(char b[], int off, int len);
void close();

➢2. Writer流 以字符为单位顺序地写文件,每次调用write方法就顺序地向目的地写入内容。Writer类有 如下常用的方法。

void write(int n)//向输出流写入一个字符。
void write(byte b[])//向输出流写入一个字符数组。
void write(byte b[],int off,int length)//从给定字符数组中起始于偏移量off处取len个字符写到输出流。
void close()//关闭输出流。

例子3使用文件字符输入、输出流将文件a.txt的内容尾加到文件b.txt中

import java.io.*;

public class Example3 {
     
    public static void main(String args[]) {
     
        File sourceFile = new File("a.txt");  //读取的文件
        File targetFile = new File("b.txt");  //写入的文件
        char c[] = new char[19];               //char型数组
        try {
     
            Writer out = new FileWriter(targetFile, true); //指向目的地的输出流
            Reader in = new FileReader(sourceFile);   //指向源的输入流
            int n = -1;
            while ((n = in.read(c)) != -1) {
     
                out.write(c, 0, n);
            }
            out.flush();
            out.close();
        } catch (IOException e) {
     
            System.out.println("Error " + e);
        }
    }
}

注:对于Writer流,write 方法将数据首先写入到缓冲区,每当缓冲区溢出时,缓冲区的内容被自动写入到目的地,如果关闭流,缓冲区的内容会立刻被写入到目的地。流调用flush0方法可以立刻冲洗当前缓冲区,即将当前缓冲区的内容写入到目的地。

4 缓冲流

➢BufferedReader和BufferedWriter类创建的对象称作缓冲输入、输出流。二者的源和目的地必须是字符输入流和字符输出流。
➢构造方法:

BufferedReader(Reader in);
BufferedWriter(Writer out);

BufferedReader流能够读取文本行,方法是readLine()。通过向BufferedReader 传递一个Reader子类的对象(如FileReader 的实例),来创建一个BufferedReader对象,如:

FileReader inOne = new FileReader ("Student. txt") ;
BufferedReader inTwo = BufferedReader (inOne) ;

然后inTwo流调用readLine()方法中读取Student.txt,例如:

String strLine = inTwo. readLine () ;

类似地,可以将BufferedWriter流和FileWriter 流连接在一起, 然后使用BufferedWriter流将数据写到目的地,例如:

FileWriter tofile = new FileWriter ("hello.txt") ;
BufferedWriter out = BufferedWriter (tofile) ;

然后out使用BufferedReader类的方法wite(tring s,int off,int len)把字符串s写到hello.txt中,参数off是s开始处的偏移量,len是写入的字符数量。
另外,BufferedWriter 流有-一个独特的向文件写入一 个回行符的方法

newLine() ;

➢BufferedReader和BufferedWriter类读 写文件的方法:

readLine()//读取文本行
write(String s,int of,int len)//把字符串s写到文件中
newLine();// 向文件写入一个回行符

由英语句子构成的文件english. txt (每句占一行):
The arrow missed the target.
They rejected the union demand.
Where does this road go to?

例子4按行读取english. txt,并在该行的后面尾加上该英语句子中含有的单词数目,然后再将该行写入到一个名字为englishCount. txt的文件中

import java.io.*;
import java.util.*;

public class Example10_1 {
     
    public static void main(String[] args) {
     
        File fRead = new File("D:\\","english.txt");
        File fWrite = new File("D:\\","englishCount.txt");
        try {
     
            Writer out = new FileWriter(fWrite);//指向目的地的输出流
            BufferedWriter bufferWrite = new BufferedWriter(out);

            Reader in = new FileReader(fRead);//指向源的输入流
            BufferedReader bufferRead = new BufferedReader(in);

            String str = null;
            while ((str = bufferRead.readLine()) != null) {
     
                StringTokenizer fenxi = new StringTokenizer(str);
                int count = fenxi.countTokens();
                str = str + " 句子中单词个数:" + count;
                bufferWrite.write(str);
                bufferWrite.newLine();
            }
            bufferWrite.close();
            out.close();
            in = new FileReader(fWrite);
            bufferRead = new BufferedReader(in);
            String s = null;
            System.out.println(fWrite.getName() + "内容:");
            while ((s = bufferRead.readLine()) != null) {
     
                System.out.println(s);
            }
            bufferRead.close();
            in.close();
        } catch (IOException e) {
     
            System.out.println(e.toString());
        }
    }
}

【Java 输入、输出流】_第4张图片

你可能感兴趣的:(《JAVA从入门到精通》,java,编程语言,输入输出流,java语言)