Java(IO流)
一、IO流的概述
Java IO流可以概括为**“两个对应,一个桥梁”**:两个对应是指字节流和字符串的对应,输入流和输出
流的对应;一个桥梁指从字节流到字符流的桥梁。分别由以下四个抽象类来表示流。
InputStream 字节流,读取数据
OutputStream 字节流,写入数据
Reader 字符流,读取数据
Writer 字符流,写入数据
Java中其他各种变化的流均是继承了它们,并进行"豪华装饰",派生出"加强版",例如,有的带
有缓冲功能,提供效率,有的提供了过滤功能,有的支持原始数据类型读写等等。
二、File类的使用
File类对象表示磁盘上的文件或目录。
它提供了与平台无关的方式来对磁盘上的文件或目标进行操作,其构造方法如表:
构造方法 | 摘要 |
---|---|
File(File parent, String child) | 根据 parent 抽象路径名和 child 路径名字符串创建一个新 File 实例。 |
File(String pathname) | 通过将给定路径名字符串转换成抽象路径名来创建一个新 File 实例。 |
File(String parent, String child) | 根据 parent 路径名字符串和 child 路径名字符串创建一个新 File实例。 |
File(URI uri) | 通过将给定的 fifile: URI 转换成一个抽象路径名来创建一个新的File 实例。 |
File提供大量的实用的方法,而且很容易记忆,通过方法名就可获知方法的作用,其具体使用,如下代码:
/******************************
*
* @author xiaochong
* @描述 File可以表示目录也可以表示文件
*
*/
public class FileTestDemo {
public static void main(String[] args) {
test1();
}
// 使用File创建文件或目录
public static void test1() {
// 创建文件
File file1 = new File("lesson1.txt"); // 相对路径 相对于classpath
File file2 = new File("d:\\lesson2.txt"); // 在磁盘D盘的根目录创建文件
lesson2.txt
File file3 = new File("d:/gaga", "lesson3.txt"); // 在D盘的gaga目录,下面创
建lesson3.txt文件
// 创建目录
File file4 = new File("hehe");// 在相对路径创建hehe目录
try {
// 如果file1 对应的文件已经存在,不会重复执行创建
boolean b1 = file1.createNewFile(); // 返回文件是否创建成功
if (b1) {
System.out.println("lesson1.txt文件创建成功");
} else {
System.out.println("file1:对应文件绝对路径:" + file1.getCanonicalPath());
}
boolean b2 = file2.createNewFile();
if (b2) {
System.out.println("d:\\\\lesson2.txt文件创建成功");
}
boolean b3 = file3.createNewFile();
if (b3) {
System.out.println("d:/gaga\", \"lesson3.txt文件创建成功");
} else {
System.out.println("文件名:(getName)" + file3.getName());
System.out.println("文件路径:(getPath)" + file3.getPath());
System.out.println("文件绝对路径:" + file3.getAbsolutePath());
}
if (!file4.exists()) {
// 创建目录
boolean b4 = file4.mkdir();
} else {
System.out.println("hehe目录已经创建成功");
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
三、字节流
按照数据流的方向的不同,也可将流分为输入流和输出流,在Java语言中有两个抽象类分别表示输
入流:InputStream类和输出流(OutputStream)。输入流的“输入”的“入”就是表示从磁盘文件或者网络
等外部的数据流向程序和内存的方向;而输出类的输出的“出”就表示是从程序或内存流向本地磁盘、远
程磁盘文件、硬件设备等外部,和输入流正好相反。FileInputStream和FileOutputStream是基于文件
的输入与输出流中使用最多的流。
3.1 FileInputStream
FileInputStream和FileOutputStream是InputStream和OuputStream的子类,适于操作字节流,即最高操作8个位的单位,字节流处理单位为1个字节,操作字节和字节数组。所有的文件的存储方式都是字节(byte)的存储,在磁盘上保留的不是文件的字符,而是把字符编码成字节,然后将这些字节都存储到磁盘上,所以字节可以处理任何类型的对象,包括二进制对象。
/*****************************************
* @功能描述:读取指定文件目录的内容
* @说明:读取文件操作步骤: 1、打开文件流 2、操作(读或者写) 3、关闭流 IO操作三部曲
*/
public static void readContentFromFile() {
String filePth = "lesson1.txt";
FileInputStream inputStream = null;
StringBuilder stringBuilder = new StringBuilder();
try {
// 实例化一个FileInputStream对象
// 步骤1:打开流
inputStream = new FileInputStream(new File(filePth));
byte[] b = new byte[100];
// 步骤2:操作-读取数据
// 检查是否读取完毕,如果文件读取完毕,read(byte[]) 返回 -1,否则返回已读取的字
节数
int length = 0;
// 循环读取文件中的内容
while ((length = inputStream.read(b)) != -1) {
stringBuilder.append(new String(b, 0, length, "utf-8"));
}
System.out.println(stringBuilder.toString());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (inputStream != null) {
try {
// 步骤3:关闭流
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
3.2 FileOutPutStream
FileOutputStream类中提供了三种写入数据的write()方法
/****************************************
*
* @author xiaochong FileOutputStream类的使用方法
*
*/
public class FileOuputStreamTestDemo {
public static void main(String[] args) {
writeContentToFile();
}
public static void writeContentToFile() {
String content = "FileOutputStream类的使用方法";
FileOutputStream outputStream = null;
try {
// 打开流
outputStream = new FileOutputStream(new File("lesson1.txt"));
// 如何把字符串转换为一个byte[]
byte[] b = content.getBytes();
// 操作 -写入操作
outputStream.write(b);
System.out.println("文件写入成功!");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
if (outputStream != null) {
try {
// 关闭IO流
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
四、字符流
字节流处理单位为1个字节,操作字节和字节数组,而字符流处理的单元为2个字节的 Unicode字符,可以操作字符、字符串数组以及字符串。在实际开发中我们推荐使用字节流去操作视 频、图片、歌曲等。如果是操作中文格式的文本,则使用字符流更好!在字符流中,使用FileReader类 和FileWrite类进行对数据进行读写操作,数据的传输效率比较低,而Java提供的BufffferedReader和 BufffferWriter以缓冲流的方式进行数据读写操作,则更高效。
41 FileReader
FileReader类与FileInputStream功能相似,都是文件的输入流,即把外部设备的内容读取到内存中,但他们区别在于FileReader类使用基于字符的方式进行处理文件内容。
4.2 BufffferedReader
相对于FileReader类,BufffferedReader实现类自带缓冲区的字符流高效读写,其最小的操作单位 为一个字符(16位)。同时,我们也可自行指定缓冲区的大小,默认的缓冲区有8192个字符,通常情 况下已经足够了。在这里我们理解BufffferedReader类是一个工具类,用来增强FileReader类功能。
4.3 FileWrite
FileWrite类可以使用字符串的方式进行写文件的操作
五、转换流InputStreamReader和OutputStreamWriter
在转换流 InputStreamReader和OutputStreamWriter分别解决输入流和输出流的转换的问题
/*****************************************
*
* @author xiaochong InputStreamReader类的使用方法
*
*/
public class InputStreamReaderTestDemo {
public static void main(String[] args) {
String targetFilePath = "output/test.txt";
BufferedWriter bufferedWriter = null;
BufferedReader bufferedReader = null;
try {
// 使用InputStreamReader类把System.in返回的InputStream字节流转换为Reader
类,最后包装为BufferedReader
bufferedReader = new BufferedReader(new
InputStreamReader(System.in));
bufferedWriter = new BufferedWriter(new FileWriter(new
File(targetFilePath)));
// 读取控制输入的内容
String content = bufferedReader.readLine();
// 写入到目标文件中
bufferedWriter.write(content);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
if (bufferedReader != null) {
try {
bufferedReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (bufferedWriter != null) {
try {
bufferedWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
小结:
• File类的用来创建文件、文件夹,并实现对它们属性的读取及修改
• 字节流InputStream、OutputStream可以用来读取二进制文件
• 字符流Reader、Writer能够高效的读取文本文件
• Java提供了字节流向字符流的转换:InputStreamReader、OutputStreamWriter
• PrintWriter能够对通往输出流的数据进行格式化