概述
File类可以对文件或目录的属性进行操作,但是File类不能访问文件的内容,即不能从文件中读取数据或者往文件里写数据。
读文件是指把文件中的数据读取到内存中。反之,写文件是把内存中的数据写到文件中。读写文件的工具是流。
流是指一连串流动的字符,是以先进先出的方式发送和接受数据的通道。流分为输入流和输出流。如果数据输入到内存,则称为输入流,如果从内存中输出则称为输出流。java中的输出流主要由OutputStream和Write作为基类,而输入流则主要由InputStream和Reader作为基类。
这个地方我可不可以这么理解:流有其对应的类,类是对象的抽象,可以把流理解为一个接受和发送数据通道,在构造流对象时把这个通道和数据源关联起来,然后用这个通道的方法来把数据源里面的数据读取或者发送。
那java中的类都是对现实之中存在的实体实物的抽象吗?还是说也可以对过程进行抽象?
在java.io包中,封装了许多输入、输出流的API。在程序中,这些输入、输出流类的对象称为流对象。可以通过这些流对象将内存中的数据以流的方式写入文件,也可以通过流对象将文件中的数据以流的方式读取到内存。
构造流对象往往会和数据源(文件)联系起来。数据源分为源数据源和目标数据源。输入流关联的是源数据源,输出流关联的是目标数据源。
输入\输出流又分为字节流和字符流两种形式。
字节流是8位通用字节流,其基本单位是字节。字节流的基类是InputStream类和OutputStream类它们是抽象类。
字符流是16位Unicode字符流,基本单位是Unicode字符。字符流最适合用来处理字符串和文本,因为它们支持国际上大多数的字符集和语言。字符流的基类是Reader类和Writer类,它们也是抽象类。
字节输入流常用方法
InputStream是一个抽象类,里面定义了字节输入流常用的方法。因为抽象类不能实例化,所以在实际中我们通常使用的都是它的子类FileInputStream类。
int read():从输入流中读取下一个字节数据;将数据源中的数据以一个字节一个字节的形式读入进来,而且读进来之后会把这些字节对应的整数形式返回给你。如果到了输入流的末尾,则返回-1。
int read (byte[] b):从输入流中读取数据,并将数据存储在缓冲区数组b中,返回实际读取的字节数(注:这个方法在读的时候也是将读进来的字节以对应整数形式存储在数组中,当从数组中读取时,需要进行强制装换(char))。如果到了输入流的末尾,则返回-1。
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class FileInputStreamDemo {
public static void main(String[] args) {
FileInputStream fis = null;
try {
fis = new FileInputStream("H:/demo.txt");
System.out.println(fis.available());
byte[] save = new byte[4];
int length = fis.read(save);
while (length != 0) {
for (int i = 0; i < length; i++) {
System.out.print((char) save[i]);
}
length = fis.read(save);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
字节输出流常用方法
OuputStream是一个抽象类,里面定义了字节输出流常用的方法。因为抽象类不能实例化,所以在实际中我们通常使用的都是它的子类FileOuputStream类。
实例:
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class FileoutputStreamDemo {
public static void main(String[] args) {
FileOutputStream fos = null;
FileInputStream fis = null;
try {
fos = new FileOutputStream("H:/demo.txt");
String str = "醉后不知天在水,满船清梦压星河。";
byte[] b = str.getBytes();
fos.write(b);
fis = new FileInputStream("H:/demo.txt");
System.out.println(fis.available());
byte[] c = new byte[10];
int length = fis.read(c);
while (length != 0) {
for (int i = 0; i < length; i++) {
System.out.println((char) c[i]);
}
length = fis.read(c);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
fis.close();
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
注:
1、在上面这个程序中当输入的字符串是abcdefg时,可以在后面的输出流中正常输出,但是要是是汉字的话,就比如“醉后不知天在水,满船清梦压星河。”就会出现一堆问号。可以写进去,但是读不出来。
这个问题后面有解答。
2、因为在输出的时候需要判定是追加还是覆盖,所以在FileOuputStream的构造方法后面可以加true或者不加。同时若目标文件不存在,还可以自己创建目标文件。