目录
IO流在我们的Java中使用还是非常重要的,那么在学习IO流之前。我们先来了解一些有关IO流相关的知识。我们IO流最后操作的还是我们磁盘中的文件,所以我们先了解一些文件相关的知识。
文件
文件的基本概念
文件,对我们并不陌生,文件是保存数据的地方,比如我们经常使用的word文档,txt文件,excel文件...都是文件。它既可以保存一张图片,也可以保持视频,声音...
文件流
文件在程序中是以流的形式来操作的
流:数据在数据源(文件)和程序(内存)之间经历的路径
输入流:数据从数据源(文件)到程序(内存)的路径
输出流:数据从程序(内存)到数据源(文件)的路径
常用的文件操作
创建文件对象相关构造器和方法
new File(String pathname) //根据路径构建一个File对象
new File(File parent,String child) //根据父目录文件+子路径构建
new File(String parent,String child) //根据父目录+子路径构建
createNewFile 创建新文件
代码演示:
创建文件的步骤,首先我们需要定义一个路径,也就是我们创建出来的文件,最后存放在哪里,所以我们在代码中定义了这么一段话
String filePath = "e:\\news1.txt";
上面这段代码就表示我们要在E盘下创建一个名称为news1.txt的文件
然后我们创建了一个FIle对象,在创建出file对象之后,我们在调用了一个方法createNewFile,该方法就是创建一个文件,因为该方法会有可能会发生异常,因此我们需要将其try catch,或者将其抛出也行
package com.file;
import org.junit.jupiter.api.Test;
import java.io.File;
import java.io.IOException;
/**
* 演示创建文件
*/
public class FileCreate {
public static void main(String[] args) {
}
//方式1 new File(String pathname)
@Test
public void create01() {
String filePath = "e:\\news1.txt";
File file = new File(filePath);
try {
file.createNewFile();
System.out.println("文件创建成功");
} catch (IOException e) {
e.printStackTrace();
}
}
//方式2 new File(File parent,String child) //根据父目录文件+子路径构建
//e:\\news2.txt
@Test
public void create02() {
File parentFile = new File("e:\\");
String fileName = "news2.txt";
//这里的file对象,在java程序中,只是一个对象
//只有执行了createNewFile 方法,才会真正的,在磁盘创建该文件
File file = new File(parentFile, fileName);
try {
file.createNewFile();
System.out.println("创建成功~");
} catch (IOException e) {
e.printStackTrace();
}
}
//方式3 new File(String parent,String child) //根据父目录+子路径构建
@Test
public void create03() {
//String parentPath = "e:\\";
String parentPath = "e:\\";
String fileName = "news4.txt";
File file = new File(parentPath, fileName);
try {
file.createNewFile();
System.out.println("创建成功~");
} catch (IOException e) {
e.printStackTrace();
}
}
//下面四个都是抽象类
//
//InputStream
//OutputStream
//Reader //字符输入流
//Writer //字符输出流
}
获取文件的相关信息
getName获取文件名字
getAbsolutePath文件绝对路径
getParent文件父级目录
length文件大小(字节)
exists文件是否存在
isFile是不是一个文件
isFileisDirectory是不是一个目录
代码演示:
package com.file;
import org.junit.jupiter.api.Test;
import java.io.File;
public class FileInformation {
public static void main(String[] args) {
}
//获取文件的信息
@Test
public void info() {
//先创建文件对象
File file = new File("e:\\news1.txt");
//调用相应的方法,得到对应信息
System.out.println("文件名字=" + file.getName());
//getName、getAbsolutePath、getParent、length、exists、isFile、isDirectory
System.out.println("文件绝对路径=" + file.getAbsolutePath());
System.out.println("文件父级目录=" + file.getParent());
System.out.println("文件大小(字节)=" + file.length());
System.out.println("文件是否存在=" + file.exists());//T
System.out.println("是不是一个文件=" + file.isFile());//T
System.out.println("是不是一个目录=" + file.isDirectory());//F
}
}
目录的操作和文件删除
mkdir创建一级目录
mkdirs创建多级目录
delete删除空目录或文件
代码演示:
因为我们要先判单d盘下是否有个文件为new1.txt如果是,那么我们就创建该文件,反之就删除该文件,那么我们就先要得到一个File对象,然后调用方法中的exists方法来判断是否存在,如果文件存在就删除,如果不存在就创建一个新的文件
package com.file;
import org.junit.jupiter.api.Test;
import java.io.File;
public class Directory_ {
public static void main(String[] args) {
//
}
//判断 d:\\news1.txt 是否存在,如果存在就删除
@Test
public void m1() {
String filePath = "e:\\news1.txt";
File file = new File(filePath);
if (file.exists()) {
if (file.delete()) {
System.out.println(filePath + "删除成功");
} else {
System.out.println(filePath + "删除失败");
}
} else {
System.out.println("该文件不存在...");
}
}
//判断 D:\\demo02 是否存在,存在就删除,否则提示不存在
//这里我们需要体会到,在java编程中,目录也被当做文件
@Test
public void m2() {
String filePath = "D:\\demo02";
File file = new File(filePath);
if (file.exists()) {
if (file.delete()) {
System.out.println(filePath + "删除成功");
} else {
System.out.println(filePath + "删除失败");
}
} else {
System.out.println("该目录不存在...");
}
}
//判断 D:\\demo\\a\\b\\c 目录是否存在,如果存在就提示已经存在,否则就创建
@Test
public void m3() {
String directoryPath = "D:\\demo\\a\\b\\c";
File file = new File(directoryPath);
if (file.exists()) {
System.out.println(directoryPath + "存在..");
} else {
if (file.mkdirs()) { //创建一级目录使用mkdir() ,创建多级目录使用mkdirs()
System.out.println(directoryPath + "创建成功..");
} else {
System.out.println(directoryPath + "创建失败...");
}
}
}
}
IO流原理及流的分类
Java IO流原理
1.l/O是Input/Output的缩写, I/O技术是非常实用的技术,用于处理数据传输如读/写文件,网络通讯等。
2.Java程序中,对于数据的输入/输出操作以”流(stream)” 的方式进行。
3java.io包下提供了各种“流”类和接口,用以获取不同种类的数据,并通过方法输入或输出数据
4.输入input: 读取外部数据(磁盘、光盘等存储设备的数据)到程序(内存) 中
5.输出output: 将程序(内存)数据输出到磁盘、光盘等存储设备中
流的分类
按操作数据单位不同分为: 字节流(8 bit) 二进制文件,字符流(按字符)文本文件
按数据流的流向不同分为: 输入流,输出流
按流的角色的不同分为: 节点流,处理流/包装流
(抽象基类) | 字节流 | 字符流 |
---|---|---|
输入流 | InputStream | Reader |
输出流 | OutputStream | Writer |
InputStream:字节输入流
InputStream抽象类是所有类字节输入流的超类
InputStream 常用的子类.
1.FilelnputStream: 文件输入流
2.BufferedInputStream: 缓冲字节输入流
3.ObjectInputStream: 对象字节输入流
FilelnputStream 介绍
代码演示
使用FileInputStream流读取文件数据,首先我们要指定要读取文件的路径,然后使用FileInputStream的read方法读取文件,当读取完毕的时候,该方法会返回一个-1所以我们使用while循环,只要方法的返回值不等于-1,我们就一直读取,这个是使用单个字节来读取,效率比较慢
使用byte数组来提取
和上面的逻辑一样,先制定要读取文件的路径,但是要提前定义好一个byte数组,也是while循环,当读取结束后,我们就可以直接构建一个String输出即可
注意事项
需要注意的是,FileInputStream只能读取二进制数据,如果需要读取文本文件可以使用InputStreamReader类将其转换为字符流。同时,读取数据时只能按字节读取,如果需要按字符读取可以使用BufferedInputStream和BufferedReader类。
package com.inputstream_;
import org.junit.jupiter.api.Test;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
/**
* 演示FileInputStream的使用(字节输入流 文件--> 程序)
*/
public class FileInputStream_ {
public static void main(String[] args) {
}
/**
* 演示读取文件...
* 单个字节的读取,效率比较低
* -> 使用 read(byte[] b)
*/
@Test
public void readFile01() {
String filePath = "e:\\hello.txt";
int readData = 0;
FileInputStream fileInputStream = null;
try {
//创建 FileInputStream 对象,用于读取 文件
fileInputStream = new FileInputStream(filePath);
//从该输入流读取一个字节的数据。 如果没有输入可用,此方法将阻止。
//如果返回-1 , 表示读取完毕
while ((readData = fileInputStream.read()) != -1) {
System.out.print((char) readData);//转成char显示
}
} catch (IOException e) {
e.printStackTrace();
} finally {
//关闭文件流,释放资源.
try {
fileInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 使用 read(byte[] b) 读取文件,提高效率
*/
@Test
public void readFile02() {
String filePath = "e:\\hello.txt";
//字节数组
byte[] buf = new byte[8]; //一次读取8个字节.
int readLen = 0;
FileInputStream fileInputStream = null;
try {
//创建 FileInputStream 对象,用于读取 文件
fileInputStream = new FileInputStream(filePath);
//从该输入流读取最多b.length字节的数据到字节数组。 此方法将阻塞,直到某些输入可用。
//如果返回-1 , 表示读取完毕
//如果读取正常, 返回实际读取的字节数
while ((readLen = fileInputStream.read(buf)) != -1) {
System.out.print(new String(buf, 0, readLen));//显示
}
} catch (IOException e) {
e.printStackTrace();
} finally {
//关闭文件流,释放资源.
try {
fileInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
FileOutputStream介绍
FileOutputStream支持写入字节流和字符流,可以将任何数据类型转换为字节流写入文件。在使用FileOutputStream写入数据时,需要通过构造函数指定输出文件的路径和文件名。如果指定的文件不存在,FileOutputStream会自动创建一个新的文件。
代码演示:
输出流,首先我们制定要把内容输出到哪一个文件,然后使用FIleOutputStream的write方法
write方法中的几个参数我们需要注意一下,第一个需要传入一个byte数组,那么假设我们要传入的是一个字符串 String a= hello 那么久可以调用String的getBytes()方法将其转成一个字节数组传入
第二个参数,表示从哪个位置开始,
第三个参数,表示到哪个位置结束
也就是说,把开始和结束位置之间的内容,写入到文件中
write(byte[] b, int off, int len) 将 len字节从位于偏移量 off的指定字节数组写入此文件输出流
package com.outputstream_;
import org.junit.jupiter.api.Test;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class FileOutputStream01 {
public static void main(String[] args) {
}
/**
* 演示使用FileOutputStream 将数据写到文件中,
* 如果该文件不存在,则创建该文件
*/
@Test
public void writeFile() {
//创建 FileOutputStream对象
String filePath = "e:\\a.txt";
FileOutputStream fileOutputStream = null;
try {
//得到 FileOutputStream对象 对象
//说明
//1. new FileOutputStream(filePath) 创建方式,当写入内容是,会覆盖原来的内容
//2. new FileOutputStream(filePath, true) 创建方式,当写入内容是,是追加到文件后面
fileOutputStream = new FileOutputStream(filePath, true);
//写入一个字节
//fileOutputStream.write('H');//
//写入字符串
String str = "hsp,world!";
//str.getBytes() 可以把 字符串-> 字节数组
//fileOutputStream.write(str.getBytes());
/*
write(byte[] b, int off, int len) 将 len字节从位于偏移量 off的指定字节数组写入此文件输出流
*/
fileOutputStream.write(str.getBytes(), 0, 3);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
fileOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}