【JAVA】并发-基础IO
一、java.io包支持。java的IO流有输入、输出两种,每种输入、输出流又可分为字节流、字符流两大类,字节流以字节为单位处理IO操作,字符流以字符为单位处理IO操作
JDK 1.4以后有java.nio包,新IO,提供了全新的API,支持更高效的IO操作
二、File类
1、java.io包下代表与平台无关的文件、目录,能新建、删除、重命名文件和目录,不能访问文件本身
2、方法
(1)访问文件名或路径名
String getName() | 返回File对象的文件名或路径名 |
String getPath() | 返回File对象的路径名 |
File getAbsoluteFile() | 绝对目录形式的File对象 |
String getAbsolutePath() | 返回File对象的绝对路径名 |
String getParent() | 返回父目录名 |
boolean renameTo(File newName) | 重命名 |
(2)文件测试
boolean exists() | 是否存在 |
boolean canWrite() | 是否可写 |
boolean canRead() | 是否可读 |
boolean isFile() | 是否文件 |
boolean isDirectory() | 是否目录 |
boolean isAbsolute() | 是否绝对路径 |
(3)获取常规文件信息
long lastModified() | 最后修改时间 |
long length() | 文件内容长度 |
(4)文件操作
boolean createNewFile() | 新建文件 |
boolean delete() | 删除文件 |
static File createTempFile(String prefix,String suffix) | 在默认临时文件目录中创建一个临时的空文件,pefix至少三个字节长,suffix默认是.tmp |
static File createTempFile(String prefix,String suffix,File Directory) | 在directory指定目录里创建临时文件 |
void deleteOnExit() | 注册一个删除钩子,当JVM退出时删除File对象对应的文件和目录 |
(5)目录操作
boolean mkdir() | 创建目录 |
String[] list() | 列出File对象的所有子文件名和路径名 |
File[] listFiles() | 列出File对象的所有子文件和路径 |
static File[] listRoots() | 列出系统所有的根路径 |
3、Java支持/作为路径分隔符,与平台无关。在windows上可以用\\作为分隔符
换行符是平台有关的,windows换行符是\r\n,linux换行符是\n
4、文件过滤器
File对象的 list方法可以接受一个实现了FilenameFilter接口的类的对象(需要实现accept方法)作为参数,来过滤文件列表
三、IO流
1、概念
(1)输入流是数据流入内存,输出流是数据从内存流出。是从程序所在内存的角度来考虑的。输入流主要由InputStream和Reader作为基类,输出流主要由OutputStream和Writer作为基类
(2)字节流操作的最小数据单元是8位的字节,字符流操作的最小数据单元是16位的字符。字节流主要由InputStream和OutputStream作为基类,字符流主要由Reader和Writer作为基类
字节输入流InputStream、字节输出流OutputStream、字符输入流Reader、字符输出流Writer
(3)可以从/向一个特定的IO设备读/写数据流,称为节点流;处理流用于包装节点流。处理流可以消除不同节点流的实现差异,提供更方便的IO方法。是一种典型的装饰器实现模式
2、InputStream和Reader
是所有输入流的基类,是抽象类
(1)InputStream提供的方法
int read() | 从输入流中读取单个字节,并以int形式返回 |
int read(byte[] b) | 从输入流中最多读取b.length个字节,并存入b数组,返回实际读取的字节数 |
int read(byte[] b,int off,int len) | 从输入流中最多读取len个字节,并在数组off起点处存入b数组,返回实际读取的字节数 |
(2)Reader提供的方法
int read() | 从输入流中读取单个字符,并以int形式返回 |
int read(char[] cbuf) | 从输入流中最多读取 cbuf.length个字符,并存入cbuf 数组,返回实际读取的字符数 |
int read(char[] cbuf,int off,int len) | 从输入流中最多读取len个字符,并在数组off起点处存入cbuf 数组,返回实际读取的字符数 |
(3)子类
用于读取文件的节点流:FileInputStream和FileReader
文件IO无法自动回收,需要在finally块里显式用close方法
增加的方法
void mark(int readAheadLimit) | 在记录指针当前位置记录一个标记 |
boolean markSupported() | 判断此输入流是否支持mark操作 |
void reset() | 将此流的记录指针重新定位到上一个标记的位置 |
long skip(long n) | 记录指针向前移动n个字节/字符 |
3、OutputStream和Writer
void write(int c) | 将指定字节/字符输出到输出流中 |
void write(byte[]/char[] buf) | 将字节/字符数组输出到输出流中 |
void write(byte[]/char[] buf,int off,int len) | 将字节/字符数组从off开始,输出len个字节/字符到输出流中 |
Write特有的
void write(String buf) |
void write(String buf,int off,int len) |
四、IO流体系
1、处理流
(1)输入
BufferedReader=new BufferedReader(new InputStreamReader(new FileInputStream("a.java")));
(2)输出
PrintStream ps=new PrintStream(new FileOutputStream("a.java"));
2、使用场景
所有能用记事本打开并看到其中内容的,都是文本文件;其他的是二进制文件
若需要进行IO的内容是文本文件,则用字符流;需要进行IO的内容是二进制文件,则用字节流。
3、推回输入流
对照read方法增加了三个unread方法,将指定内容推到推回缓冲区,推回输入流在进行read操作时,总是先从推回缓冲区中进行读取,只有完全读取了缓冲区的内容而未填满数组时才会从原输入流中读取。
4、重定向标准输入输出
System的静态方法。定义后System.out、System.in操作的流将发生变化
static void setOut(PrintStream out) | 定义标准输出流 |
static void setIn(InputStream in) | 定义标准输入流 |
static void setErr(PrintStream err) | 定义标准错误输出流 |
5、JVM读取其他进程的数据
Process对象提供了三个方法,用于程序和其子进程进行通信。Process对象由Runtime对象的exec()方法生成
InputStream getInputStream() | 获取子进程的输入流 |
InputStream getErrorStream() | 获取子进程的错误输出流 |
OutputStream getOutputStream() | 获取子进程的输出流 |
当子进程获取进程数据时,需要用输出流
Process p=Runtime.getRuntime().exec("javac");
BufferedReader br=new BufferedReader(new InputStreamWriter(p.getErrorStream()));
6、RandomAccessFile
任意访问文件,可以在文件的任意地方来读写数据
(1)构造器
RandomAccessFile(String name, String mode) | mode: r只读 rw读写 rwd读写且内容的更新都同步写入到底层存储设备 rws读写且内容元数据的更新都同步写入到底层存储设备 |
RandomAccessFile(File file, String mode) |
(2)操作文件指针
long getFilePointer() | 返回文件记录指针的当前位置 |
void seek(long pos) | 文件记录指针定位到pos |
(3)若要追加写入文件,可以seek(raf.length())定位到最后再写入
若要在中间写入,需要先将插入点后的字符写入缓冲区(如临时文件)里,再从插入点写入新的字符,再将缓冲区里的数据追加写进去