File与IO流
Author: Msuenb
Date: 2023-02-21
File类
- java.io.File类:文件和文件目录路径的抽象表示形式,与平台无关
- File 能新建、删除、重命名文件和目录,但不能访问文件内容。 访问文件内容,需要使用输入/输出流
- 想要在Java程序中表示一个真实存在的文件或目录,那么必须有一个File对象;但是Java程序中的一个File对象,可能没有一个真实存在的文件或目录
- File对象可以作为参数传递给流的构造器
File常用构造方法:
序号 | 方法 | 描述 |
---|---|---|
1 | public File(String pathname) | 通过将给定的路径名字符串转换为抽象路径名来创建新的 File实例。 |
2 | public File(String parent, String child) | 从父路径名字符串和子路径名字符串创建新的 File实例。 |
3 | public File(File parent, String child) | 从父抽象路径名和子路径名字符串创建新的 File实例。 |
File file1 = new File("D:\\aaa.txt");
FIle file2 = new File("D:\\ddd\bbb.txt");
File parentDir = new File("D:\\ddd");
File file3 = new File(parentDir, "ccc.txt");
File常用方法:
序号 | 方法 | 描述 |
---|---|---|
1 | public String getAbsolutePath() | 获取绝对路径 |
2 | public String getName() | 获取名称 |
3 | public String getParent() | 获取上层文件目录路径。若无,返回null |
4 | public long length() | 获取文件长度 |
5 | public boolean isDirectory() | 判断是否是文件目录 |
6 | public boolean isFile() | 判断是否是文件 |
7 | public boolean exists() | 判断是否存在 |
8 | public boolean createNewFile() | 创建文件 |
9 | public boolean mkdirs() | 创建文件目录。如果上层文件目录不存在,一并创建 |
10 | public boolean delete() | 删除文件或者文件夹 |
@Test
public void test01() throws IOException {
File dir1 = new File("E:\\iotest\\dir1"); // \ 为转义
if (!dir1.exists()) // 如果 E:\iotest\dir1 不存在 就创建为目录
dir1.mkdir();
// 创建dir2目录 以dir1为父目录
File dir2 = new File(dir1, "dir2");
if (!dir2.exists()) dir2.mkdirs();
// 在dir2目录下创建文件 a.txt
File file = new File(dir2, "a.txt");
if (!file.exists()) file.createNewFile();
}
@Test
public void test02() {
File file = new File("E:\\iotest\\dir1\\dir2\\a.txt");
File absoluteFile = file.getAbsoluteFile(); // 获取绝对路径
String name = file.getName();
String parent = file.getParent();
boolean isDirectory = file.isDirectory();
boolean isFile = file.isFile();
if (file.exists()) file.delete(); // 删除文件
}
IO流分类
根据数据的流向分为:输入流和输出流。
- 输入流:把数据从其他设备上读取到内存中的流。以InputStream,Reader结尾
- 输出流 :把数据从内存 中写出到其他设备上的流。以OutputStream、Writer结尾
根据数据的类型分为:字节流和字符流。
- 字节流 :以字节为单位,读写数据的流。以Stream结尾
- 字符流 :以字符为单位,读写数据的流。以Reader和Writer结尾
根据IO流的角色不同分为:节点流和处理流。
-
节点流:直接从数据源或目的地读写数据。常用的节点流:
-
文件IO流: FileInputStream、FileOutputStream、FileReader、FileWriter 。
-
字符串IO流: StringReader、StringWriter。
-
数 组IO流: ByteArrayInputStream、ByteArrayOutputStream、CharArrayReader、CharArrayWriter。
-
-
处理流:是对一个已存在的流进行连接和封装,通过所封装的流的功能调用实现数据读写。 常用处理流:
-
缓冲流:BufferedInputStream、BufferedOutputStream、BufferedReader、BufferedWriter。增加缓冲功能,避免频繁读写硬盘。
-
转换流:InputStreamReader、OutputStreamReader。实现字节流和字符流之间的转换。
-
数据流:DataInputStream、DataOutputStream。提供读写Java基础数据类型功能
-
对象流:ObjectInputStream、ObjectOutputStream。提供直接读写Java对象功能
-
打印流:PrintStream、PrintWriter。提供各种print、println方法输出各种类型的数据
-
管道IO流:PipedInputStream、PipedOutputStream、PipedReader、PipedWriter。负责两个线程之间的数据交互
装饰者设计模式:
IO流的设计使用了装饰模式(Decorator Pattern)也称为包装模式(Wrapper Pattern)。装饰模式是使用一种对客户端透明的方式来动态地扩展对象的功能,它是通过继承扩展功能的替代方案之一。
-
输入流 | 输出流 | |
---|---|---|
字节流 | InputStream | OutputStream |
字符流 | Reader | Writer |
文件流
- FIleInputStream和FileOutputStream是字节输入流和字节输出流。
- FileReader和FileWriter是字符输入流和字符输出流。
FIleInputStream和FileOutputStream
FileOutputStream 用于写出非文本数据之类的原始字节流;FileOutputStream 从文件系统中的某个文件中获得输出字节。
读入字节数据:
@Test
public void input() {
File file = new File("E:\\iotest\\dir\\test.txt");
// 1 建立一个字节流对象,将已存在的一个文件加载进流
FileInputStream fis = null;
try {
fis = new FileInputStream(file);
int len;
// 2 创建一个临时存放数据的数组
byte[] buf = new byte[1024];
// 3 调用字节流对象的读取方法将流中的数据读入到数组
while ((len = fis.read(buf)) != -1) {
System.out.println(new String(buf, 0, len));
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (fis != null) fis.close(); // 4 关闭资源
} catch (IOException e) {
e.printStackTrace();
}
}
}
写出字节数据:
@Test
public void output() {
File file = new File("E:\\iotest\\dir\\test.txt");
FileOutputStream fos = null;
try {
fos = new FileOutputStream(file, true); // 追加写
// fos = new FileOutputStream(file); // 覆盖写
String str = "hello, world!\r\n";
fos.write(str.getBytes()); // 写入数据
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
try {
if (fos != null) fos.close(); // 关闭资源
} catch (IOException e) {
e.printStackTrace();
}
}
}
FileReader和FileWriter
FileReader用于写出非文本数据之类的原始字符流;FileWriter从文件系统中的某个文件中获得输出字符。
读入字符数据:
@Test
public void reader() throws IOException {
File file = new File("E:\\iotest\\dir\\test.txt");
FileReader fr = new FileReader(file);
int len;
char[] cbuf = new char[1024];
while ((len = fr.read(cbuf)) != -1) {
System.out.println(new String(cbuf, 0, len));
}
fr.close();
}
写出字符数据:
@Test
public void writer() throws IOException {
File file = new File("E:\\iotest\\dir\\test.txt");
FileWriter fw = new FileWriter(file, true);
String str = "hello, java!";
fw.write(str);
fw.flush(); // 刷新缓冲区 fw还可以用
fw.close(); // 刷新缓冲区 并关闭资源
}
FileWriter与FileOutputStream不同。因为内置缓冲区的原因,需要flush 或 close才能写出字符到文件中
缓冲流
缓冲流,也叫高效流,按照数据类型分类:
- 字节缓冲流:BufferedInputStream,BufferedOutputStream
- 字符缓冲流:BufferedReader,BufferedWriter
缓冲流的基本原理,是在创建流对象时,会创建一个内置的默认大小的缓冲区数组(默认8K字节),通过缓冲区读写,减少系统IO次数,从而提高读写的效率。
使用缓冲流复制文件:
public class BufferStreamTest {
public static void main(String[] args) {
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
try {
bis = new BufferedInputStream(new FileInputStream("E:\\iotest\\dir\\test.txt"));
bos = new BufferedOutputStream(new FileOutputStream("E:\\iotest\\dest.txt"));
byte[] buf = new byte[1024];
int len;
while ((len = bis.read(buf)) != -1) {
bos.write(buf, 0, len);
}
bos.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (bis != null) bis.close();
if (bos != null) bos.close(); // 会自动关闭它包装的底层节点流
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
转换流
转换流提供了在字节流和字符流之间的转换
Java API提供了两个转换流:
- InputStreamReader:将InputStream转换为Reader,需要和InputStream“套接”。
- OutputStreamWriter:将Writer转换为OutputStream,需要和OutputStream“套接”
字节流中的数据都是字符时,转成字符流操作更高效。很多时候我们使用转换流来处理文件乱码问题。实现编码和解码的功能。
public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream("E:\\iotest\\dir\\test.txt");
FileOutputStream fos = new FileOutputStream("E:\\iotest\\dest2.txt");
InputStreamReader isr = new InputStreamReader(fis, "GBK");
OutputStreamWriter osw = new OutputStreamWriter(fos, "GBK");
BufferedReader br = new BufferedReader(isr);
BufferedWriter bw = new BufferedWriter(osw);
String str = null;
while ((str = br.readLine()) != null) {
bw.write(str);
bw.newLine();
bw.flush();
}
bw.close();
br.close();
}
对象流
ObjectInputStream 和 OjbectOutputSteam 用于存储和读取基本数据类型数据或对象的处理流。它的强大之处就是可以把Java中的对象写入到数据源中,也能把对象从数据源中还原回来。
- 序列化:用ObjectOutputStream类保存基本类型数据或对象的机制
- 反序列化:用ObjectInputStream类读取基本类型数据或对象的机制
ObjectOutputStream和ObjectInputStream不能序列化static和transient修饰的成员变量
某个类的对象需要序列化输出时,该类必须实现java.io.Serializable
接口。如果对象的某个属性也是引用数据类型,那么如果该属性也要序列化的话,也要实现Serializable接口
class User implements Serializable {
private String username;
private String password;
// 该版本号的目的在于验证序列化的对象和对应类是否版本匹配
private static final long serialVersionUID = -2991413533082785204L;
public User(String username, String password) {
this.username = username;
this.password = password;
}
@Override
public String toString() {
return "User{" +
"username='" + username + '\'' +
", password='" + password + '\'' +
'}';
}
}
@Test
public void serializable() throws IOException {
User u = new User("zhangsan", "6934y8234");
FileOutputStream fos = new FileOutputStream("E:\\iotest\\user.dat");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(u);
oos.close();
}
@Test
public void deserializable() throws IOException, ClassNotFoundException {
FileInputStream fis = new FileInputStream("E:\\iotest\\user.dat");
ObjectInputStream ois = new ObjectInputStream(fis);
Object o = ois.readObject();
System.out.println(o);
ois.close();
}
输入输出流和打印流
System.out对象是PrintStream类型的。它也是IO流对象。
PrintStream 为其他输出流添加了功能,使它们能够方便地打印各种数据值表示形式。它还提供其他两项功能。与其他输出流不同,PrintStream永远不会抛出 IOException;另外,PrintStream可以设置自动刷新。
import java.io.FileNotFoundException;
import java.io.PrintStream;
public class TestPrintStream {
public static void main(String[] args) throws FileNotFoundException {
PrintStream ps = new PrintStream("io.txt");
ps.println("hello");
ps.println(1);
ps.println(1.5);
ps.close();
}
}
实现键盘输入都是通过Scanner类的对象来完成的,Scanner类不只是键盘输入。
import org.junit.Test;
import java.io.*;
import java.util.Scanner;
public class TestScanner {
@Test
public void test01() throws IOException {
Scanner input = new Scanner(System.in);
PrintStream ps = new PrintStream("1.txt");
while(true){
System.out.print("请输入一个单词:");
String str = input.nextLine();
if("stop".equals(str)){
break;
}
ps.println(str);
}
input.close();
ps.close();
}
@Test
public void test2() throws IOException {
Scanner input = new Scanner(new FileInputStream("1.txt"));
while(input.hasNextLine()){
String str = input.nextLine();
System.out.println(str);
}
input.close();
}
}
数据流
为了方便地操作Java语言的基本数据类型和String的数据,可以使用数据流。
数据流有两个类:DataInputStream 和 DataOutputStream,分别“套接”在 InputStream 和 OutputStream 子类的流上
@Test
public void output() throws IOException {
DataOutputStream dos = new DataOutputStream(new FileOutputStream("E:\\iotest\\dir\\data.txt"));
dos.writeUTF("写入UTF字符串"); //
dos.writeBoolean(true);
dos.writeInt(123455);
System.out.println("写入文件成功");
dos.close();
}
public void input() throws IOException {
DataInputStream dis = new DataInputStream(new FileInputStream("E:\\iotest\\dir\\data.txt"));
String info = dis.readUTF();
boolean flag = dis.readBoolean();
int num = dis.readInt();
System.out.println(info);
System.out.println(flag);
System.out.println(num);
dis.close();
}
try...resource
语法格式:
try(需要关闭的资源对象的声明){
业务逻辑代码
}catch(异常类型 e){
处理异常代码
}catch(异常类型 e){
处理异常代码
}
....
它没有finally,也不需要程序员去关闭资源对象,无论是否发生异常,都会关闭资源对象。
需要指出的是,为了保证try语句可以正常关闭资源,这些资源实现类必须实现AutoCloseable或Closeable接口,实现这两个接口就必须实现close方法。Closeable是AutoCloseable的子接口。Java7几乎把所有的“资源类”(包括文件IO的各种类、JDBC编程的Connection、Statement等接口…)进行了改写,改写后资源类都是实现了AutoCloseable或Closeable接口,并实现了close方法。
写到try()中的资源类的变量默认是final声明的,不能修改。
示例代码:
@Test
public void test03() {
//从d:/1.txt(GBK)文件中,读取内容,写到项目根目录下1.txt(UTF-8)文件中
try(
FileInputStream fis = new FileInputStream("d:/1.txt");
InputStreamReader isr = new InputStreamReader(fis,"GBK");
BufferedReader br = new BufferedReader(isr);
FileOutputStream fos = new FileOutputStream("1.txt");
OutputStreamWriter osw = new OutputStreamWriter(fos,"UTF-8");
BufferedWriter bw = new BufferedWriter(osw);
){
String str;
while((str = br.readLine()) != null){
bw.write(str);
bw.newLine();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
标签:file,String,IO,File,new,txt,public
From: https://www.cnblogs.com/msuenb/p/17138424.html