1. File
- File类可以使用文件路径字符串来创建File实例,该文件路径可以是绝对路径或相对路径
- File类的list()方法中可以接收一个FilenameFilter参数,通过该参数可以只列出符合条件的文件
2. 流(Stream)
- Stream是从起源(source)到接收(sink)的有序数据
- 按照流向分可以分为输入流和输出流
- 输入流:只能从中读取数据,不能写入数据(基类是InputStream和Reader)
- 输出流:只能向其中写入数据,不能读取数据(基类是OutputStream和Writer)
- 按照操作的数据单元分为字节流和字符流
- 字节流:操作的数据单元是8位的字节(基类是InputStream和OutputStream)
- 字符流:操作的数据单元是16位的字节(基类时Reader和Writer)
- 按照角色可以分为节点流和处理流
- 节点流:可以从/向一个特定的IO设备中读/写数据的流,也被称为低级流
- 处理流:用于对一个已存在的流进行连接或封装来实现读/写功能,也称为高级流或包装流
3. 字节流和字符流
- 字节流输入
-
public class FileInputStreamTest { public void main(String[] args) throws IOException { FileInputStream fis = new FileInputStream("FileInputStreamTest.java"); byte[] bytes = new byte[1024]; int hasRead = 0; while ((hasRead = fis.read(bytes)) > 0) { System.out.println(new String(bytes,0,hasRead)); } fis.close(); } }
- 字节流输出
-
public class FileOutputStreamTest { public void main(String[] args) { try (FileOutputStream fileOutputStream = new FileOutputStream("file.txt"); FileInputStream fileInputStream = new FileInputStream("FileInputStreamTest.java")) { byte[] bytes = new byte[1024]; int hasRead = 0; while ((hasRead = fileInputStream.read(bytes)) > 0) { fileOutputStream.write(bytes,0,hasRead); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } }
- 字符流输入
-
public class FileReaderTest { public void main(String[] args) { try (FileReader fileReader = new FileReader("FileInputStreamTest.java")) { char[] chars = new char[1024]; int hasRead = 0; while ((hasRead = fileReader.read(chars)) > 0) { System.out.println(new String(chars,0,hasRead)); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } }
- 字符流输出
-
public class FileWriterTest { public void main(String[] args) { try (FileWriter fileWriter = new FileWriter("poem.txt")){ fileWriter.write("一天又很快的结束了!\r\n"); } catch (IOException e) { e.printStackTrace(); } } }
4. 处理流/转换流
- 构造器参数不是一个物理节点,而是已经存在的流
- 关闭最上层的流时,会自动关闭被该处理流包装的节点流
- 如果进行输入/输出的是文本内容,应当考虑字符流,如果进行输入/输出的内容时二进制内容,则应该考虑使用字节流
- 转换流用于实现将字节流转换成字符流,InputStreamReader将字节输入流转换成字符输入流;OutputStreamWriter将字节输出流转换成字符输出流
- BufferReader流具有缓冲功能
5. 重定向标准输入/输出
- 重定向输出流
-
public class RedirectOut { public void main(String[] args) { try (PrintStream printStream = new PrintStream(new FileOutputStream("out.txt"))){ System.setOut(printStream); System.out.println("普通字符串"); System.out.println(new RedirectOut()); } catch (FileNotFoundException e) { e.printStackTrace(); } } }
- 重定向输入流
-
public class RedirectIn { public void main(String[] args) { try (FileInputStream fileInputStream = new FileInputStream("poem.txt")) { System.setIn(fileInputStream); Scanner scanner = new Scanner(System.in); scanner.useDelimiter("\n");//只把回车作为换行符 while (scanner.hasNext()) { System.out.println("键盘输入内容:" + scanner.next()); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } }
6. RandomAccessFile
- RandomAccessFile支持任意访问,可以直接调整到文件的任意地方读写数据
- 可以向已存在的文件后追加内容
- 只能读写文件,不能读写其他IO节点
- 包含一个记录指针,用以标识当前读写处的位置
- 直接将文件记录指针移动到中间某位置后进行输出会覆盖原有的内容
- 读取文件
-
public class RandomAccessFileTest {
public void main(String[] args) {
try (RandomAccessFile randomAccessFile = new RandomAccessFile("poem.txt", "r")) {
System.out.println("指针初始位置:" + randomAccessFile.getFilePointer());
randomAccessFile.seek(300);
byte[] buffer = new byte[1024];
int hasRead = 0;
while ((hasRead = randomAccessFile.read(buffer)) > 0) {
System.out.println(new String(buffer, 0, hasRead));
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public class RandomAccessFileTest {
public void main(String[] args) {
try (RandomAccessFile randomAccessFile = new RandomAccessFile("poem.txt", "r")) {
System.out.println("指针初始位置:" + randomAccessFile.getFilePointer());
randomAccessFile.seek(300);
byte[] buffer = new byte[1024];
int hasRead = 0;
while ((hasRead = randomAccessFile.read(buffer)) > 0) {
System.out.println(new String(buffer, 0, hasRead));
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
- 向文件末尾追加内容
-
public class AppendContent { public void main(String[] args) { try (RandomAccessFile randomAccessFile = new RandomAccessFile("poem.txt", "rw")) { randomAccessFile.seek(randomAccessFile.length()); randomAccessFile.write("追加的内容!\n".getBytes()); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } }
- 向指定位置添加内容
-
public class InsertContent { public void main(String[] args) throws IOException { File file = File.createTempFile("tmp", null); file.deleteOnExit(); try (RandomAccessFile randomAccessFile = new RandomAccessFile("poem.txt", "rw"); FileOutputStream tmpOut = new FileOutputStream(file); FileInputStream tmpIn = new FileInputStream(file)) { randomAccessFile.seek(300); //将文件内容写入临时文件中 byte[] buffer = new byte[64]; int hasRead = 0; while ((hasRead = randomAccessFile.read(buffer)) > 0) { tmpOut.write(buffer, 0, hasRead); } randomAccessFile.seek(300); randomAccessFile.write("插入的内容".getBytes()); //追加之前的内容 while ((hasRead = tmpIn.read(buffer)) > 0) { randomAccessFile.write(buffer, 0, hasRead); } } } }