IO流简介
(1)IO流是一个抽象的概念,可以理解为一段单向的数据序列,是Java实现输入输出的基础
| 概念 | 简介 |
|---|
| 流(Stream) | 数据在程序(内存)和数据源(文件)之间经历的路径 |
| 输入流(Input) | 数据从数据源(文件)到程序(内存)的路径 |
| 输出流(Output) | 数据从程序(内存)到数据源(文件)的路径 |
(2)Java把所有的传统的流类型都放到在java.io包下,用于实现输入和输出功能,输入也叫做读取数据,输出也叫做作写出数据
(3)Java的IO模型使用装饰者模式(Decorator),按功能划分流(Stream),您可以动态装配这些流(Stream),以便获得您需要的功能
IO流分类
抽象基类
Java的IO流共涉及40多个类,实际上非常规则,都是从4个抽象基类派生,派生出来的子类名称都是以其父类名作为子类名后缀,由于抽象基类都是抽象类,本身不能创建实例,但是继承它们的子类有对应的功能
| 分类 | 抽象基类 |
|---|
| 字节输入流 | InputStream |
| 字节输出流 | OutputStream |
| 字符输入流 | Reader |
| 字符输出流 | Writer |
输入流和输出流
按照流的流向分,可以分为输入流和输出流
| IO流 | 简介 |
|---|
| Input输入流 | 负责读,外部 -> 内存 |
| Output输出流 | 负责写,内存 -> 外部 |
字节流和字符流
按照操作单元划分,可以划分为字节流和字符流,使用字节流读取文件为中文的时候,GBK占用2个字节(byte),UTF-8占用3个字节
| IO流 | 简介 |
|---|
| 字节流 | 操作的单元是数据单元是8位的字节,例如图片、音乐、视频等文件,可以对二进制文件进行处理 |
| 字符流 | 操作的是数据单元为16位的字符,例如.txt、.java、.c、.cpp等文本文件,.doc、excel、ppt这些不是文本文件 |
节点流和处理流
按照流的角色划分为节点流和处理流
| IO流 | 简介 |
|---|
| 节点流 | 直接从数据源或目的地读写数据 |
| 处理流 | 处理流也叫包装流,对节点流进行包装,使用了修饰器设计模式,不会直接与数据源相连,而是“连接”在已存在的流(节点流或处理流)之上,处理流也被称为高级流,处理流以增加缓冲的方式来提高输入输出的效率 |
节点流
| 分类 | 字节输入流 | 字节输出流 | 字符输入流 | 字符输出流 |
|---|
| 抽象基类 | InputStream | OutputStream | Reader | Writer |
| 访问文件 | FileInputStream | FileOutputStream | FileReader | FileWriter |
| 访问数组 | ByteArrayInputStream | ByteArrayOutputStream | charArrayReader | charArrayWriter |
| 访问管道 | PipedInputStream | PipedOutputStream | PipedReader | PipedWriter |
| 访问字符串 | 无 | 无 | StringReader | StringWriter |
处理流
| 分类 | 字节输入流 | 字节输出流 | 字符输入流 | 字符输出流 |
|---|
| 缓冲流 | BufferedInputStream | BufferedOutputStream | BufferedReader | BufferedWriter |
| 对象流 | ObjectInputStream | ObjectOutputStream | 无 | 无 |
| 转换流 | 无 | 无 | InputStreamReader | OutputStreamWriter |
| 过滤流 | FilterInputStream | FilterOutputStream | FilterReader | FilterWriter |
| 打印流 | 无 | PrintStream | 无 | PrintWriter |
| 数据流 | DataInputStream | DataOutputStream | 无 | 无 |
| 回退流 | PushbackInputStream | 无 | PushbackReader | 无 |
File类
路径分隔符
路径中的每级目录之间需要用一个路径分隔符隔开,但路径分隔符和系统有关,比如windows和DOS系统默认使用\\来表示、UNIX和URL使用/来表示,为了解决Java程序跨平台运行,File类提供了一个常量,可以根据操作系统,动态的提供分隔符(盘符+路径+文件名)
1
| public static final String separator;
|
File类简介
(1)java.io.File类的一个对象,代表一个文件或一个文件目录(文件夹)
(2)File 能新建、删除、重命名文件和目录,但File不能访问文件内容本身,如果需要访问文件内容本身,则需要使用输入/输出流。
(3)想要在Java程序中表示一个真实存在的文件或目录,那么必须有一个File对象,但是Java程序中的一个File对象,可能没有一个真实存在的文件或目录。
File类构造器
| 构造器 | 简介 |
|---|
| File(String pathname) | 以pathname为路径创建File对象,可以是绝对路径或者相对路径 |
| File(String parent,String child) | 以parent为父路径,child为子路径创建File对象 |
| File(File parent,String child) | 根据一个父File对象和子文件路径创建File对象 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| public class Demo { @Test public void test() { File file1 = new File("hello.txt"); System.out.println(file1);
File file2 = new File("E:\\test\\hello.txt"); System.out.println(file2);
File file3 = new File("E:\\test", "java"); System.out.println(file3);
File file4 = new File(file3, "hello.txt"); System.out.println(file4);
File file5 = new File("E:" + File.separator + "test" + File.separator + "hello.txt"); System.out.println(file5); } }
|
File类常用方法
获取操作
(1)方法示例
| 方法 | 简介 |
|---|
| getAbsolutePath() | 获取绝对路径 |
| getPath() | 获取路径 |
| getName() | 获取名称 |
| getParent() | 获取上层文件目录路径,若无则返回null |
| length() | 获取文件长度(字节数)不能获取目录的长度 |
| lastModified() | 获取最后一次的修改时间,毫秒值 |
| list() | 获取指定目录下的所有文件或者文件目录的名称数组 |
| listFiles() | 获取指定目录下的所有文件或者文件目录的File数组 |
(2)代码示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| public class Demo { @Test public void test() { File file1 = new File("hello.txt"); System.out.println(file1.getAbsolutePath()); System.out.println(file1.getPath()); System.out.println(file1.getName()); System.out.println(file1.getParent()); System.out.println(file1.length()); System.out.println(file1.lastModified()); System.out.println(new Date(file1.lastModified()));
File file2 = new File("E:\\java"); String[] list = file2.list(); for (String f : list) { System.out.println(f); } File[] files = file2.listFiles(); for (File f : files) { System.out.println(f); } } }
|
重命名操作
(1)方法示例
| 方法 | 简介 |
|---|
| renameTo(File dest) | 把文件重命名为指定的文件路径 |
(2)代码示例
1 2 3 4 5 6 7 8 9 10
| public class Demo { @Test public void test(){ File file1 = new File("E:\\test\\hello.txt"); File file2 = new File("hello.txt"); boolean b = file1.renameTo(file2); System.out.println(b); } }
|
判断操作
(1)方法示例
| 方法 | 简介 |
|---|
| isDirectory() | 判断是否是文件目录 |
| isFile() | 判断是否是文件 |
| exists() | 判断是否存在 |
| canRead() | 判断是否可读 |
| canWrite() | 判断是否可写 |
| isHidden() | 判断是否隐藏 |
(2)代码示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| public class Demo { @Test public void test() { File file = new File("hello.txt"); System.out.println(file.isDirectory()); System.out.println(file.isFile()); System.out.println(file.exists()); System.out.println(file.canRead()); System.out.println(file.canWrite()); System.out.println(file.isHidden()); } }
|
创建操作
(1)方法示例
注意事项:如果创建文件或者文件目录没有写盘符路径,那么,默认在项目路径下
| 方法 | 简介 |
|---|
| createNewFile() | 创建文件,若文件存在,则不创建,返回false |
| mkdir() | 创建文件目录, 如果此文件目录存在,就不创建了 如果此文件目录的上层目录不存在,也不创建 |
| mkdirs() | 创建文件目录,如果上层文件目录不存在,一并创建 |
(2)代码示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| public class 创建操作 { @Test public void test5() throws IOException { File file1 = new File("test1.txt"); boolean exists = file1.createNewFile(); if (exists) { System.out.println("创建成功"); } else { System.out.println("创建失败"); }
File file2 = new File("E:\\test1"); boolean mkdir = file2.mkdir(); if (mkdir) { System.out.println("创建成功"); } else { System.out.println("创建失败"); }
File file3 = new File("E:\\test1\\test2\\test3"); boolean mkdirs = file3.mkdirs(); if (mkdirs) { System.out.println("创建成功"); } else { System.out.println("创建失败"); } } }
|
删除操作
(1)方法示例
注意事项: Java中的删除不走回收站,要删除一个文件目录,请注意该文件目录内不能包含文件或者文件目录
(2)代码示例
1 2 3 4 5 6 7 8 9 10 11 12 13
| public class Demo { @Test public void test() throws IOException { File file = new File("test.txt"); file.mkdir(); boolean delete = file.delete(); if (delete){ System.out.println("删除成功"); }else{ System.out.println("没有这个文件"); } } }
|
字符流(Character Stream)
字符流是Java IO库中用于处理字符数据的流。它以字符为单位进行读取和写入操作,适用于处理文本文件、配置文件等字符数据。
FileReader读取文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
| public class FileReaderTest {
@Test public void test1() { FileReader fileReader = null; try { File file = new File("hello.txt");
fileReader = new FileReader(file);
int data = fileReader.read(); while (data != -1) { System.out.print((char) data); data = fileReader.read(); } } catch (IOException e) { e.printStackTrace(); } finally { if (fileReader != null) { try { fileReader.close(); } catch (IOException e) { e.printStackTrace(); } } } }
@Test public void test2() { FileReader fileReader = null; try { File file = new File("hello.txt");
fileReader = new FileReader(file);
int data; while ((data = fileReader.read()) != -1) { System.out.print((char) data); } } catch (IOException e) { e.printStackTrace(); } finally { if (fileReader != null) { try { fileReader.close(); } catch (IOException e) { e.printStackTrace(); } } } }
@Test public void test3() { FileReader fileReader = null; try { File file = new File("hello.txt"); fileReader = new FileReader(file); char[] c = new char[5]; int num; while ((num = fileReader.read(c)) != -1) { for (int i = 0; i < num; i++) { System.out.print(c[i]); } } } catch (IOException e) { e.printStackTrace(); } finally { if (fileReader != null) { try { fileReader.close(); } catch (IOException e) { e.printStackTrace(); } } } }
@Test public void test4() { FileReader fileReader = null; try { File file = new File("hello.txt"); fileReader = new FileReader(file); char[] c = new char[5]; int num; while ((num = fileReader.read(c)) != -1) { String str = new String(c, 0, num); System.out.print(str); } } catch (IOException e) { e.printStackTrace(); } finally { if (fileReader != null) { try { fileReader.close(); } catch (IOException e) { e.printStackTrace(); } } } }
}
|
FileWriter写出文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| public class FileWriterTest {
@Test public void test() { FileWriter fileWriter = null; try { File file = new File("E:\\test.txt"); fileWriter = new FileWriter(file); fileWriter.write("FileWriter流测试"); } catch (IOException e) { e.printStackTrace(); } finally { if (fileWriter != null) { try { fileWriter.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
|
FileReader、FileWriter复制文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
| public class FileReader_FileWriter_Copy {
@Test public void test() { FileReader fileReader = null; FileWriter fileWriter = null; try { File file1 = new File("hello.txt"); File file2 = new File("E:\\test.txt");
fileReader = new FileReader(file1); fileWriter = new FileWriter(file2);
char[] c = new char[5]; int num; while ((num = fileReader.read(c)) != -1) { fileWriter.write(c, 0, num); } } catch (IOException e) { e.printStackTrace(); } finally { if (fileWriter != null) { try { fileWriter.close(); } catch (IOException e) { e.printStackTrace(); } } if (fileReader != null) { try { fileReader.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
|
字节流(Byte Stream)
字节流是Java IO库中处理二进制数据的流。它以字节为单位进行读取和写入操作,适用于处理图像、音频、视频等二进制数据。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| public class FileInputStreamTest {
@Test public void test() { FileInputStream fileInputStream = null; try { File file = new File("1.png"); fileInputStream = new FileInputStream(file); byte[] b = new byte[3]; int num; while ((num = fileInputStream.read(b)) != -1) { String str = new String(b, 0, num); System.out.print(str); } } catch (IOException e) { e.printStackTrace(); } finally { if (fileInputStream != null) { try { fileInputStream.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
|
FileOutputStream写出文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| public class FileOutputStreamTest {
@Test public void test() { FileOutputStream fileOutputStream = null; try { File file = new File("E:\\test.txt"); fileOutputStream = new FileOutputStream(file); fileOutputStream.write(12345); } catch (IOException e) { e.printStackTrace(); } finally { if (fileOutputStream != null) { try { fileOutputStream.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
|
(1)FileInputStream、FileOutputStream复制非文本文件复制
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
| public class FileInputStream_FileOutputStream_Copy {
@Test public void test() { FileInputStream fileInputStream = null; FileOutputStream fileOutputStream = null; try { File file1 = new File("1.png"); File file2 = new File("E:\\1.png"); fileInputStream = new FileInputStream(file1); fileOutputStream = new FileOutputStream(file2); byte[] b = new byte[3]; int num; while ((num = fileInputStream.read(b)) != -1) { fileOutputStream.write(b, 0, num); } } catch (IOException e) { e.printStackTrace(); } finally { if (fileOutputStream != null) { try { fileOutputStream.close(); } catch (IOException e) { e.printStackTrace(); } } if (fileInputStream != null) { try { fileInputStream.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
|
(2)复制代码逻辑封装
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
| public class copyUtils {
public static void main(String[] args) { long startTime = System.currentTimeMillis();
String startPath = "E:\\1.png"; String endPath = "E:\\1.png"; copyFile(startPath, endPath);
long endTime = System.currentTimeMillis();
System.out.println("复制花费的时间为:" + (endTime - startTime)); }
public static void copyFile(String startPath, String endPath) { FileInputStream fileInputStream = null; FileOutputStream fileOutputStream = null; try { File file1 = new File(startPath); File file2 = new File(endPath); fileInputStream = new FileInputStream(file1); fileOutputStream = new FileOutputStream(file2); byte[] b = new byte[3]; int num; while ((num = fileInputStream.read(b)) != -1) { fileOutputStream.write(b, 0, num); } } catch (IOException e) { e.printStackTrace(); } finally { if (fileOutputStream != null) { try { fileOutputStream.close(); } catch (IOException e) { e.printStackTrace(); } } if (fileInputStream != null) { try { fileInputStream.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
|
转换流(Transcoder Streams)
转换流是Java IO库中的字符流类,在字节流和字符流之间提供了一个桥梁,用于将字节流转换为字符流或将字符流转换为字节流
将字节流转换为字符流,读取字节并将其解码为字符。可以指定不同的字符编码方式,例如UTF-8、GBK等,以正确地将字节流转换为对应的字符。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| public class InputStreamReaderExample { public static void main(String[] args) { try { InputStream inputStream = new FileInputStream("input.txt");
Reader reader = new InputStreamReader(inputStream, "UTF-8");
int data = reader.read();
while (data != -1) { char character = (char) data; System.out.print(character); data = reader.read(); }
reader.close(); } catch (IOException e) { e.printStackTrace(); } } }
|
字符流转字节流(OutputStreamWriter)
将字符流转换为字节流,将字符编码为字节,并将其写入输出流。同样可以指定字符编码方式。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| public class OutputStreamWriterExample { public static void main(String[] args) { try { OutputStream outputStream = new FileOutputStream("output.txt"); Writer writer = new OutputStreamWriter(outputStream, "UTF-8");
String text = "Hello, World!"; writer.write(text);
writer.close(); } catch (IOException e) { e.printStackTrace(); } } }
|
文件编解码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| public class Demo {
@Test public void test() throws IOException { InputStreamReader inputStreamReader = null; java.io.OutputStreamWriter outputStreamWriter = null; try { File file1 = new File("hello.txt"); File file2 = new File("test.txt");
FileInputStream fileInputStream = new FileInputStream(file1); FileOutputStream fileOutputStream = new FileOutputStream(file2);
inputStreamReader = new InputStreamReader(fileInputStream,"utf-8"); outputStreamWriter = new OutputStreamWriter(fileOutputStream, "gbk");
char[] c = new char[5]; int num; while ((num = inputStreamReader.read(c)) != -1) { outputStreamWriter.write(c, 0, num); } } catch (IOException e) { e.printStackTrace(); } finally { if (outputStreamWriter != null) { outputStreamWriter.close(); } if (inputStreamReader != null) { inputStreamReader.close(); } } } }
|
缓冲流(Buffered Stream)
缓冲流是Java IO库提供的一种流装饰器,用于提高IO操作的性能。内部维护了一个缓冲区(Buffer),在读取和写入数据时,先将数据存储到缓冲区中。当缓冲区满了或者达到一定条件时,才将数据真正读取或写入到底层数据源(如文件、网络等)中。
字符缓冲流
BufferedReader
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| public class BufferedReaderTest {
@Test public void readerFile() { BufferedReader bufferedReader = null; FileReader fileReader = null; try { File file = new File("hello.txt"); fileReader = new FileReader(file); bufferedReader = new BufferedReader(fileReader); char[] c = new char[3]; int num; while ((num = bufferedReader.read(c)) != -1) { String str = new String(c, 0, num); System.out.print(str); } } catch (IOException e) { e.printStackTrace(); } finally { if (bufferedReader != null) { try { bufferedReader.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
|
BufferedWriter
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| public class BufferedWriterTest { @Test public void writerFile() { BufferedWriter bufferedWriter = null; try { File file = new File("E:\\test.txt"); FileWriter fileWriter = new FileWriter(file); bufferedWriter = new BufferedWriter(fileWriter); bufferedWriter.write("hello"); bufferedWriter.newLine(); bufferedWriter.write("hello");
} catch (IOException e) { e.printStackTrace(); } finally { if (bufferedWriter != null) { try { bufferedWriter.close(); } catch (IOException e) { e.printStackTrace(); } } } }
public static void main(String[] args) throws IOException { String filePath = "E:\\note.txt"; BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(filePath, true)); bufferedWriter.write("hello"); bufferedWriter.newLine(); bufferedWriter.write("hello");
bufferedWriter.close(); } }
|
BufferedReader、BufferedWriter复制文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
| public class BufferedReader_BufferedWriter_Copy {
@Test public void copyFile() { BufferedReader bufferedReader = null; BufferedWriter bufferedWriter = null; try { File file1 = new File("E:\\1.png"); File file2 = new File("E:\\1.png"); FileReader fileReader = new FileReader(file1); FileWriter fileWriter = new FileWriter(file2); bufferedReader = new BufferedReader(fileReader); bufferedWriter = new BufferedWriter(fileWriter); char[] c = new char[3]; int num; while ((num = bufferedReader.read(c)) != -1) { bufferedWriter.write(c, 0, num); } } catch (IOException e) { e.printStackTrace(); } finally { if (bufferedWriter != null) { try { bufferedWriter.close(); } catch (IOException e) { e.printStackTrace(); } } if (bufferedReader != null) { try { bufferedReader.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
|
字节缓冲流
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| public class BufferedInputStreamTest { @Test public void inputFile() { BufferedInputStream bufferedInputStream = null; try { File file1 = new File("1.png");
FileInputStream fileInputStream = new FileInputStream(file1); bufferedInputStream = new BufferedInputStream(fileInputStream);
byte[] b = new byte[3]; int num; while ((num = bufferedInputStream.read(b)) != -1) { String str = new String(b, 0, num); System.out.print(str); } } catch (IOException e) { e.printStackTrace(); } finally { if (bufferedInputStream != null) { try { bufferedInputStream.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
|
BufferedOutputStream
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| public class BufferedOutputStreamTest {
@Test public void outputFile() { BufferedOutputStream bufferedOutputStream = null; try { File file = new File("E:\\test.txt"); FileOutputStream fileOutputStream = new FileOutputStream(file); bufferedOutputStream = new BufferedOutputStream(fileOutputStream); bufferedOutputStream.write(12345); } catch (IOException e) { e.printStackTrace(); } finally { if (bufferedOutputStream != null) { try { bufferedOutputStream.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
|
(1)FileInputStream、FileOutputStream复制非文本文件复制
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
| public class BufferedInputStream_BufferedOutputStream_Copy {
@Test public void copyFile() { BufferedInputStream bufferedInputStream = null; BufferedOutputStream bufferedOutputStream = null; try { File file1 = new File("E:\\1.png"); File file2 = new File("E:\\1.png");
FileInputStream fileInputStream = new FileInputStream(file1); FileOutputStream fileOutputStream = new FileOutputStream(file2); bufferedInputStream = new BufferedInputStream(fileInputStream); bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
byte[] b = new byte[3]; int num; while ((num = bufferedInputStream.read(b)) != -1) { bufferedOutputStream.write(b, 0, num); } } catch (IOException e) { e.printStackTrace(); } finally { if (bufferedOutputStream != null) { try { bufferedOutputStream.close(); } catch (IOException e) { e.printStackTrace(); } } if (bufferedInputStream != null) { try { bufferedInputStream.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
|
(2)复制代码逻辑封装
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
| public class Demo {
public static void main(String[] args) { long startTime = System.currentTimeMillis();
String startPath = "E:\\1.png"; String endPath = "E:\\1.png"; copyFile(startPath, endPath);
long endTime = System.currentTimeMillis();
System.out.println("复制花费的时间为:" + (endTime - startTime)); }
public static void copyFile(String startPath, String endPath) { BufferedInputStream bufferedInputStream = null; BufferedOutputStream bufferedOutputStream = null; try { File file1 = new File(startPath); File file2 = new File(endPath);
FileInputStream fileInputStream = new FileInputStream(file1); FileOutputStream fileOutputStream = new FileOutputStream(file2); bufferedInputStream = new BufferedInputStream(fileInputStream); bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
byte[] b = new byte[3]; int num; while ((num = bufferedInputStream.read(b)) != -1) { bufferedOutputStream.write(b, 0, num); } } catch (IOException e) { e.printStackTrace(); } finally { if (bufferedOutputStream != null) { try { bufferedOutputStream.close(); } catch (IOException e) { e.printStackTrace(); } } if (bufferedInputStream != null) { try { bufferedInputStream.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
|
对象流(Object Stream)
对象流是Java IO库中用于序列化和反序列化对象的流。它提供了将对象以字节流的形式进行读写的功能,可以实现对象的持久化、传输和共享。
ObjectOutputStream序列化
对象的序列化(Serialization)是指将一个对象转换为字节流的过程,以便于在网络上传输或者存储到文件中。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| public class Demo {
@Test public void test() { ObjectOutputStream objectOutputStream = null; try { objectOutputStream = new ObjectOutputStream(new FileOutputStream("hello.txt")); objectOutputStream.writeObject(new String("你好java")); objectOutputStream.writeObject(new Person("小明", 18)); objectOutputStream.flush(); } catch (IOException e) { e.printStackTrace(); } finally { if (objectOutputStream != null) { try { objectOutputStream.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
|
反序列化(Deserialization)是将字节流重新转换为对象的过程,以便于恢复对象的状态和数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| public class Demo {
@Test public void test() { ObjectInputStream objectInputStream = null; try { objectInputStream = new ObjectInputStream(new FileInputStream("hello.txt")); Object o = objectInputStream.readObject(); String str = (String) o; Person person = (Person) objectInputStream.readObject();
System.out.println(str); System.out.println(person); } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } finally { if (objectInputStream != null) { try { objectInputStream.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
|
打印流(PrintStream)
打印流(PrintStream)是Java中用于将数据打印到控制台或文件的输出流。是Java标准库中的一个类,属于java.io包下的一部分。使用PrintStream可以方便地输出各种类型的数据,包括基本类型和对象。
常用方法
打印流提供了一系列的print和println方法来输出数据,并且具有自动转换数据类型和格式化输出的功能。
| 方法签名 | 描述 |
|---|
println(String str) | 将指定的字符串以行的形式输出到打印流。每次调用该方法会输出一行内容,并在行末自动添加换行符 \n。 |
print(String str) | 将指定的字符串输出到打印流,不换行。 |
flush() | 刷新打印流,将缓冲区的内容立即输出。调用该方法可以确保内容被及时输出到目标设备。 |
PrintStream(OutputStream out) | 创建一个新的打印流对象,并将输出重定向到指定的输出流。 |
使用案例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| public class PrintStreamTest {
@Test public void test() { PrintStream printStream = null; try { FileOutputStream fileOutputStream = new FileOutputStream(new File("E:\\text.txt")); printStream = new PrintStream(fileOutputStream, true); if (printStream != null) { System.setOut(printStream); } for (int i = 0; i <= 255; i++) { System.out.print((char) i); if (i % 50 == 0) { System.out.println(); } } } catch (FileNotFoundException e) { e.printStackTrace(); } finally { if (printStream != null) { printStream.close(); } } } }
|
标准输入输出流
| 标准输入输出流 | 简介 |
|---|
| System.in | 标准的输入流,默认从键盘输入 |
| System.out | 标准的输出流,默认从控制台输出 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
| public class Demo {
@Test public void test1() { Scanner scan = new Scanner(System.in); String num = scan.next();
System.out.println("请输入字符:"); while (true) { if ("e".equalsIgnoreCase(num) || "exit".equalsIgnoreCase(num)) { System.out.println("安全退出!!"); break; } else { System.out.println(num.toUpperCase()); } } }
@Test public void test2() { System.out.println("请输入信息(退出输入e或exit):"); BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String s = null; try { while ((s = br.readLine()) != null) { if ("e".equalsIgnoreCase(s) || "exit".equalsIgnoreCase(s)) { System.out.println("安全退出!!"); break; } System.out.println("-->:" + s.toUpperCase()); System.out.println("继续输入信息"); } } catch (IOException e) { e.printStackTrace(); } finally { try { if (br != null) { br.close(); } } catch (IOException e) { e.printStackTrace(); } } } }
|
RandomAccessFile类
简介
(1)RandomAccessFile类是 Java 输入/输出流体系中功能最丰富的文件内容访问类,不属于流,但提供了众多的方法来访问文件内容,可以读取文件内容,也可以向文件输出数据,既可以作为一个输入流也可以作为一个输出流
(2)RandomAccessFile类直接继承于java.lang.Object类,实现了DataInput、DataOutput这两个接口
(3)与普通的输入/输出流不同的是,RandomAccessFile 支持随机访问的方式,程序可以直接跳转到文件的任意地方来读写数据。
(4)RandomAccessFile类允许自由定位文件记录指针,可以不从开始的地方开始输出,因此如果只需要访问文件部分内容,而不是把文件从头读到尾或向已存在的文件后追加内容,使用 RandomAccessFile类是更好的选择
构造器
| 构造器 | 简介 |
|---|
| RandomAccessFile(File file, String mode) | 使用File参数来指定文件本身,mode 参数用来访问模式 |
| RandomAccessFile(String name, String mode) | 使用String参数来指定文件名,mode 参数用来访问模式 |
创建 RandomAccessFile 类实例需要指定一个 mode 参数,该参数指定 RandomAccessFile 的访问模式
| 访问模式 | 简介 |
|---|
| r | 以只读方式打开 |
| rw | 打开以便读取和写入 |
| rwd | 打开以便读取和写入;同步文件内容的更新 |
| rws | 打开以便读取和写入;同步文件内容和元数据的更新 |
常用方法
| 方法 | 简介 |
|---|
| skipBytes(int n) | 使读写指针从当前位置开始,跳过n个字节 |
| write(byte[] b) | 将指定的字节数组写入到这个文件,并从当前文件指针开始 |
| getFilePointer() | 返回当前读写指针所处的位置 |
| seek(long pos) | 设定读写指针的位置,与文件的开头相隔pos个字节数 |
| setLength(long newLength) | 设置此文件的长度 |
| readLine() | 从指定文件当前指针读取下一行内容 |
文件的读写操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| public class Demo {
@Test public void test() { RandomAccessFile randomAccessFile1 = null; RandomAccessFile randomAccessFile2 = null; try { randomAccessFile1 = new RandomAccessFile(new File("带土.jpg"), "r"); randomAccessFile2 = new RandomAccessFile(new File("带土111.jpg"), "rw");
int num; byte[] b = new byte[3]; while ((num = randomAccessFile1.read(b)) != -1) { randomAccessFile2.write(b, 0, num); } } catch (IOException e) { e.printStackTrace(); } finally { if (randomAccessFile2 != null) { try { randomAccessFile2.close(); } catch (IOException e) { e.printStackTrace(); } } if (randomAccessFile1 != null) { try { randomAccessFile1.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
|
数据的插入操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| public class Demo {
@Test public void test() { RandomAccessFile randomAccessFile = null; try { randomAccessFile = new RandomAccessFile(new File("hello.txt"), "rw");
randomAccessFile.seek(3); StringBuffer stringBuffer = new StringBuffer((int) (new File("hello.txt").length())); byte[] b = new byte[5]; int num; while ((num = randomAccessFile.read(b)) != -1) { String str = new String(b, 0, num); stringBuffer.append(str); } randomAccessFile.seek(3); randomAccessFile.write("123".getBytes()); randomAccessFile.write(stringBuffer.toString().getBytes()); } catch (IOException e) { e.printStackTrace(); } finally { if (randomAccessFile != null) { try { randomAccessFile.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
|
I/O 模型
IO与I/O 模型
什么是IO?
- 从计算机角度理解IO:从计算机角度来看,输入输出(IO)是指
计算机与外部设备之间进行数据传递的过程,包括将外部设备的数据输入到计算机中进行处理,以及将计算机处理结果输出到外部设备进行显示或者存储。 - 从操作系统角度理解IO:从操作系统角度来看,IO是指
应用程序通过调用操作系统提供的API,将数据从用户空间传输到内核空间进行实际的输入输出操作,包括磁盘读写、网络通信等。用户空间是应用程序访问的内存区域,而内核空间是操作系统内核访问的受保护内存区域。因此应用程序的IO操作可以看作是IO调用触发操作系统内核执行实际的IO操作。
什么是IO模型?
IO模型(Input/Output Model)是描述在计算机系统中,如何处理输入和输出操作的一种模型,常见的有如下几种
- 阻塞IO模型(Blocking IO Model):当应用程序执行IO操作时,整个进程会被阻塞,直到操作完成。在等待IO完成期间无法执行其他任务,效率较低。
- 非阻塞IO模型(Non-blocking IO Model):当应用程序执行IO操作时,可以立即返回,而不必等待操作完成。通过轮询或异步通知方式,应用程序可以继续执行其他任务,并周期性地检查IO操作是否完成,但仍然需要主动轮询,效率仍然有限。
- 多路复用IO模型(Multiplexing IO Model):通过使用系统调用(如select、poll、epoll等),可以同时监听多个IO操作的完成情况。应用程序将IO操作注册给内核,内核会通知应用程序哪些IO操作已经完成,从而避免了轮询的开销,提高了效率。
- 信号驱动IO模型(Signal-driven IO Model):应用程序将IO操作注册给内核,并指定一个信号处理函数。当IO操作完成时,内核会向应用程序发送一个信号,应用程序在信号处理函数中进行相应的处理。这种模型可以避免轮询,但需要处理信号的开销。
- 异步IO模型(Asynchronous IO Model):应用程序发起IO操作后,不需要等待操作完成,可以继续执行其他任务。当IO操作完成时,系统会通知应用程序,应用程序可以回调相应的处理函数进行后续处理。异步IO模型相对于其他模型较为复杂,但具有较高的性能和灵活性。
为了方便理解IO模型,可以拿现实中的例子来比喻这个过程,假设一个老师正在收取学生的作业。
- 同步阻塞方式(Blocking):老师逐个学生地等待每个学生完成作业再继续收下一个学生的作业。当一个学生没有完成作业时,老师会一直等待,直到该学生完成作业后才能继续收取下一个学生的作业。这种方式下,老师需要阻塞等待每个学生完成作业,效率较低。
- 同步非阻塞方式(Non-blocking):老师逐个学生地收取作业,但如果某个学生还没完成作业,老师会暂时跳过该学生继续收取下一个学生的作业,直到之前的学生完成作业后再回来收取。这种方式下,老师不会阻塞在每个学生上,但仍然需要轮询每个学生是否完成作业。
- IO多路复用方式(select和poll):老师相当于在询问所有的学生是否完成作业,但并不知道具体哪个学生完成了。老师持续地询问每个学生是否完成作业,直到所有学生中有学生举手表示完成作业为止。这种方式下,老师需要不断地轮询每个学生来确定是否完成作业,存在一定的性能开销。
- IO多路复用方式(epoll):学生举手相当于触发了一个事件,并告诉老师是哪个学生举手了。老师只需要关注那些举手的学生,而不需要轮询询问每个学生,从而提高了效率。这种方式下,老师能够直接知道具体是哪个学生完成了作业,避免了轮询和性能开销。
- 异步IO方式(Async):老师委托一位助教负责收取学生的作业,然后可以继续进行其他工作。助教负责等待学生完成作业,当有学生完成作业时,助教会通知老师。这种方式下,老师完全不需要关注学生的作业进度,只需等待助教的通知即可。与其他模型相比,异步IO方式能够充分利用时间,提高效率。
常见的五种 IO 模型
阻塞IO模型(Blocking IO Model)
阻塞IO是最传统的IO模型,它的特点是当应用程序执行IO操作时,整个进程会被阻塞,直到操作完成
这种模型在等待IO完成期间无法执行其他任务,直到IO操作完成,效率较低。

非阻塞IO模型(Non-blocking IO Model)
非阻塞IO模型中,当应用程序执行IO操作时,可以立即返回并执行其他任务,而不必等待操作完成。
但应用程序需要轮询或者使用多线程,周期性检查IO操作是否已经完成,如果IO操作还未完成,则返回一个错误码或者空数据,应用程序需要再次发起IO操作。
虽然非阻塞IO模型可以在应用程序执行IO操作时立即返回并执行其他任务,避免了等待操作完成的阻塞状态,但应用进程需要主动轮询,效率仍然有限。

多路复用IO模型(Multiplexing IO Model)
多路复用IO模型中,通过使用操作系统提供的select、poll或者epoll机制,可以同时监听多个IO操作的完成情况。
- select:
select是最早出现的多路复用函数之一,适用于Unix/Linux等操作系统。 - poll:
poll是对select的改进,也用于Unix/Linux等操作系统。 - epoll:
epoll是Linux特有的多路复用机制,具有更高的性能和可扩展性。
应用程序将IO操作注册给内核,内核会调用select、poll或者epoll函数,进行监听多个IO操作的完成情况。这些函数会阻塞等待,直到任何一个IO事件发生,一旦有IO事件发生,内核会通知应用程序,并返回哪些文件描述符已经就绪,以便应用程序进行相应的IO操作处理,从而避免了应用进程轮询的开销,提高了效率。

信号驱动IO模型(Signal-driven IO Model)
信号驱动IO模型中,应用程序将IO操作注册给内核,并指定一个信号处理函数,可以继续执行其他任务而不被阻塞。
当操作系统完成IO操作后,内核会向应用程序发送一个信号,表示IO已经完成。应用程序收到信号后,可以处理已完成的IO操作。
这种模型可以避免轮询,但需要操作系统支持,并且对信号处理也是开销。

异步IO模型(Asynchronous IO Model)
异步IO模型中,应用程序发起IO操作后,不需要等待操作完成,可以继续执行其他任务。当操作系统完成IO操作后,系统会通知应用程序,并将结果返回给应用程序,应用程序可以回调相应的处理函数进行后续处理。异步IO模型相对于其他模型较为复杂,但具有较高的性能和灵活性。

BIO、NIO、AIO
BIO(Blocking I/O)、NIO(Non-blocking I/O)和AIO(Asynchronous I/O)是Java中用于处理I/O操作的三种不同的编程模型
BIO、NIO、AIO对比
| 对比 | BIO | NIO | AIO |
|---|
| IO模型 | 同步阻塞 | 同步非阻塞 (多路复用) | 异步非阻塞 |
| 编程难度 | 简单 | 复杂 | 复杂 |
| 处理效率 | 低 | 中 | 高 |
| 并发力 | 低 | 高 | 高 |

BIO、NIO、AIO使用场景
虽然Java-NIO、Java-AIO,在性能上比Java-BIO要强很多,但是基本没人直接用Java-NIO、Java-AIO,如果要进行网络通信,一般都会采用Netty,它对原生的Java-NIO进行了封装优化
| I/O 模型 | 使用场景 |
|---|
| BIO | 连接数较少且并发要求不高的场景,如传统的Socket编程 |
| NIO | 大规模并发连接的场景,如弹幕系统、聊天服务器、游戏服务器等 |
| AIO | 大规模并发连接且每个连接的数据处理时间较长的场景,如高性能服务器、文件传输等 |
BIO(同步阻塞I/O)
BIO简介
(1)BIO也称为阻塞I/O模型,在JDK1.4之前建立网络连接时采用的都是 BIO 模式,是最传统的Java I/O编程模型
(2)BIO相关的类和接口位于java.io包下,如InputStream、OutputStream、Reader和Writer等。
(3)BIO模型在处理客户端请求时,通常会为每个请求分配一个线程。当连接建立之后,如果该线程没有操作,它将会一直阻塞等待,这样会导致服务器资源浪费,在高并发的场景下,机器资源很快就会被耗尽。
BIO 通信模型图

NIO(同步非阻塞I/O)
NIO简介
(1)NIO是从Java 1.4版本引入的一套新的IO API,可以替代标准的Java IO API,提供了一系列改进的输入/输出的新特性
(2)NIO相关类都被放在 java.nio 包及子包下,并且对原 java.io 包中的很多类进行改写。
(3)NIO的特点是同步非阻塞,同步指的是必须等待 IO 缓冲区内的数据就绪,而非阻塞指的是,用户线程不原地等待 IO 缓冲区,可以先做一些其他操作,但是要定时轮询检查 IO 缓冲区数据是否就绪
NIO三大核心部分
NIO的执行流程
- 创建通道(Channel):首先,需要创建一个通道对象,可以是文件通道(FileChannel)或网络通道(SocketChannel、ServerSocketChannel)。通道负责与数据源进行交互。
- 创建缓冲区(Buffer):为了进行数据的读取和写入,需要创建一个缓冲区对象。不同类型的数据可以使用不同的缓冲区,如字节缓冲区(ByteBuffer)、字符缓冲区(CharBuffer)等。缓冲区是存储数据的容器。
- 将通道注册到选择器(Selector):将创建的通道注册到选择器上。选择器是多路复用器,可以同时监控多个通道的状态。通过选择器,可以实现单线程处理多个通道的就绪事件。
- 轮询选择器:使用一个线程轮询选择器上注册的通道,以获取就绪状态的通道。当通道准备好进行读取或写入时,选择器会返回相应的通道集合。
- 处理就绪事件:根据选择器返回的就绪通道集合,进行相应的读取或写入操作。可以使用缓冲区从通道中读取数据,或者将数据写入到通道中。
- 循环执行轮询:在一次循环执行完毕后,再次进行轮询操作,处理新的就绪事件。这样,可以不断地处理多个通道的就绪事件,实现高效的非阻塞式 I/O 操作。
NIO 通信模型图

AIO(异步非阻塞I/O)
AIO简介
(1)AIO是NIO的升级版本,也被称为NIO 2.0。它引入了异步通道的概念,并采用了Proactor模式。
(2)AIO模型采用了异步的方式处理I/O操作。当应用程序发起一个I/O请求后,不需要等待操作完成,而是继续执行其他任务。当I/O操作完成时,系统会通知应用程序,并可以通过回调机制来处理已完成的操作
(3)JDK 7引入了Path、Paths和Files三个类,声明在java.nio.file包下。这些类增强了对文件处理和文件系统特性的支持,让处理文件和I/O操作变得更加便捷。这些类的引入是为了进一步完善NIO,使其更适合处理现代应用中的文件操作需求
| 类 | 简介 |
|---|
| Path | Path表示文件或目录的路径。它提供了一系列方法来操作路径,例如获取父路径、解析路径、合并路径等,可以看做是java.io.File类的升级版本 |
| Paths | Paths类是Path类的工具类,提供了静态方法用于创建Path对象 |
| Files | Files类提供了一系列静态方法来进行文件和目录的操作。它可以完成文件的复制、移动、删除、创建目录等操作,还可以读取和写入文件的内容 |
NIO的执行流程
创建异步通道:首先,需要创建一个异步通道对象,用于与数据源进行交互,可以是文件通道或网络通道。
创建缓冲区:与 NIO 类似,在 AIO 中也需要创建一个缓冲区对象来存储数据。
准备回调函数:回调函数是异步操作完成后的回调方法。在发起异步操作之前,需要准备一个回调函数来处理操作完成后的结果。
发起异步操作:通过异步通道发起读取或写入操作。与传统的同步 I/O 不同,AIO 的异步操作不会阻塞线程,而是在后台进行。
继续执行其他任务:在异步操作进行的同时,可以继续执行其他任务。
异步操作完成后触发回调:当异步操作完成时,会触发事先准备好的回调函数。回调函数会将异步操作的结果返回,并进行相应的处理。
AIO模型的优点
- 异步处理:应用程序在发起I/O请求后可以继续执行其他任务,不需要等待I/O操作完成。
- 非阻塞:AIO模型允许应用程序在执行I/O操作时不被阻塞,而是立即返回并继续执行其他任务。
- 资源效率:由于不需要为每个I/O操作创建一个线程,AIO模型能够更有效地利用系统资源,提高并发性能。
Path
Path类常用方法
| 方法 | 描述 |
|---|
getFileName() | 返回路径中表示文件或目录的最后一个元素 |
getParent() | 返回路径中表示父目录的Path对象 |
resolve(String other) | 将给定的字符串(或另一个Path对象)添加到当前路径后面 |
toAbsolutePath() | 返回绝对路径的Path对象 |
normalize() | 返回表示去除冗余标识符的规范化路径的Path对象 |
示例代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| public class PathTest {
public static void main(String[] args) { Path path = Paths.get("/path/to/file.txt");
System.out.println("File name: " + path.getFileName());
System.out.println("Parent directory: " + path.getParent());
System.out.println("Resolved path: " + path.resolveSibling("newFile.txt"));
System.out.println("Absolute path: " + path.toAbsolutePath());
System.out.println("Normalized path: " + path.normalize()); } }
|
Paths
Paths类常用方法:
| 方法 | 描述 |
|---|
get(String first, String... more) | 根据给定的路径元素获取Path对象 |
get(URI uri) | 根据给定的URI获取Path对象 |
示例代码:
1 2 3 4 5 6 7 8 9 10
| public class PathsTest { public static void main(String[] args) { Path path1 = Paths.get("/path/to"); Path path2 = Paths.get("file.txt");
Path fullPath = Paths.get(path1.toString(), path2.toString()); System.out.println("Full path: " + fullPath); } }
|
Files
Files类常用方法:
| 方法 | 描述 |
|---|
copy(Path source, Path target, CopyOption... options) | 复制文件或目录 |
move(Path source, Path target, CopyOption... options) | 移动文件或目录 |
delete(Path path) | 删除文件或目录 |
exists(Path path) | 判断文件或目录是否存在 |
createDirectory(Path dir, FileAttribute<?>... attrs) | 创建目录 |
readAllLines(Path path, Charset cs) | 读取文件的所有行 |
write(Path path, byte[] bytes, OpenOption... options) | 将字节数组写入文件 |
newInputStream(Path path, OpenOption... options) | 创建文件输入流 |
newOutputStream(Path path, OpenOption... options) | 创建文件输出流 |
示例代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| public class FilesTest { public static void main(String[] args) throws Exception { Path sourcePath = Paths.get("/path/to/source.txt"); Path targetPath = Paths.get("/path/to/target.txt");
Files.copy(sourcePath, targetPath, StandardCopyOption.REPLACE_EXISTING);
boolean exists = Files.exists(targetPath);
Files.delete(targetPath);
Path directoryPath = Paths.get("/path/to/directory"); Files.createDirectory(directoryPath);
List<String> lines = Files.readAllLines(sourcePath, StandardCharsets.UTF_8);
byte[] data = "Hello, World!".getBytes(); Files.write(targetPath, data, StandardOpenOption.CREATE);
InputStream inputStream = Files.newInputStream(sourcePath);
OutputStream outputStream = Files.newOutputStream(targetPath); } }
|