1、I/O Streams
数据文件是基于byte(字节)而非bit(位)保存以及传输。1 byte = 8 bit。
一个字节(byte) = 8个二进制位(bit)
8个二进制位(bit),可以用十进制整数来表示!
即,一个字节可以用255以内的十进制整数来表示。
读取字节的十进制整数,然后去找到相应的字符,显示出来。
2、AutoCloseable
上图概念的代码实现:
资源如果没有被手动关闭,就会一直在内存中占用着!
用finally语句来关闭,关闭资源句一定会被执行:
// 但这个代码冗余度太高了,以后不用了,有新办法
★ AutoCloseable接口
【理解try-with-resources方法的使用!】
注意,①try语句和try块不是一个东西;②资源关闭和异常处理没有半毛钱关系。
★ 该方法实现了资源的自动关闭——
无论是否引发异常,都在try块执行完时自动关闭资源!!
3、ByteArrayBuffer
4、Paths
5、Files
懒得记了。。。都是些写好的方法,可以直接用。
6、编程例题
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.FileAlreadyExistsException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.Comparator;
public class IOTest {
public static void main(String[] args) throws IOException {
String fileName = "C:/example/from.txt";
System.out.println("----- 1、创建文件 ------");
createFile(fileName);
System.out.println("----- 2、将字符串写入文件 -------");
// \r\n在txt文本中换行
String str =
"白日依山尽\r\n" +
"黄河入海流\r\n" +
"欲穷千里目\r\n" +
"更上一层楼\r\n";
writeToFile(fileName, str);
System.out.println("--------- 3、基于基本IO流实现文件的复制 ----------");
String toFile = "C:/example/to.txt";
copyByIO(fileName, toFile);
System.out.println("--------- 4、基于NIO实现文件的复制 ----------");
String toFile2 = "C:/example/nio/to.txt";
copyByNIO(fileName, toFile2);
System.out.println("---------- 5、删除指定文件 -------------");
deleteFile(toFile);
System.out.println("---------- 6、遍历指定目录文件 -------------");
String dir = "C:/example";
walkDirectories(dir);
}
/**
* 基于指定文件名称创建目录及文件
* 如果文件已经存在,则忽略
*
* @param fileName
* @throws IOException
*/
private static void createFile(String fileName) throws IOException {
Path dir = Paths.get(fileName);
Files.createDirectories(dir.getParent());// 创建目录,存在目录也不会抛出异常
try{
Files.createFile(dir);// 创建文件,若文件已经存在则会抛出异常
System.out.println("创建文件成功!文件位置:" + fileName);
}
catch(FileAlreadyExistsException e) {
System.out.println("文件 " + fileName + " 已存在,无需创建!");
}
System.out.println();
}
/**
* 提示:文件以字节操作,因此可以
* 字符串,转字节数组,直接基于Files写入文件
*
*
* @param fileName
* @param content
* @throws IOException
*/
private static void writeToFile(String fileName, String content) throws IOException{
String[] lines = content.split("\r\n"); // 先把要写入的字符串按行分割
try( BufferedWriter output = new BufferedWriter(new FileWriter(fileName)); ) {
for (String line: lines) {
output.write(line); // 写入一行(不含换行符)
output.newLine(); // 写入换行符
}
output.flush();
System.out.println("数据写入成功!文件位置:" + fileName);
}
System.out.println();
}
/**
* 基于基本IO,以及字节数组缓冲区,复制文件
* 打印显示循环读写循环次数
*
* @param sourceFile
* @param targetFile
* @throws IOException
*/
private static void copyByIO(String sourceFile, String targetFile) throws IOException {
try( InputStream input = new FileInputStream(sourceFile);
OutputStream output = new FileOutputStream(targetFile); ){
int size = 4;
byte[] buffer = new byte[size]; // 字节数组缓冲区,大小为size
int len;
int cnt = 0;
while( (len = input.read(buffer)) != -1) {
output.write(buffer, 0, len);
cnt++;
}
System.out.println(sourceFile + " -> " + targetFile + " 复制成功!");
System.out.println("字节数组缓冲区大小为" + size + "时,读写循环次数为" + cnt + "\n");
}
}
/**
* 基于NIO,实现文件的复制
*
* @param sourceFile
* @param targetFile
* @throws IOException
*/
private static void copyByNIO(String sourceFile, String targetFile) throws IOException {
Path source = Paths.get(sourceFile);
Path target = Paths.get(targetFile);
Files.createDirectories(target.getParent());
Files.copy(source, target, StandardCopyOption.REPLACE_EXISTING); // 如果输出文件存在,则替换
System.out.println(sourceFile + " -> " + targetFile + " 复制成功!\n");
}
/**
* 删除文件
*
* @param fileName
* @throws IOException
*/
private static void deleteFile(String fileName) throws IOException {
Path dir = Paths.get(fileName);
Files.deleteIfExists(dir);
System.out.println(fileName + " 删除成功!\n");
}
/**
* 遍历打印指定目录下全部目录/文件名称
*
* @param dir
* @throws IOException
*/
private static void walkDirectories(String dir) throws IOException {
Path d = Paths.get(dir);
Files.walk(d)
//.sorted(Comparator.reverseOrder()) // 反向遍历
.forEach(System.out::println);
}
}