一、File类
不管是文件和目录都是用file类来操作的,但是不能访问文件内容本身。
1、File类的使用
1)、访问文件名相关的方法
- String getName():返回此此对象表示但文件名或者路径
- String getPath():返回路径
- String getAbsoluteFile():返回此对象所对应的绝对路径的对象
- String getAbsolutePath():返回此对象所对应的绝对路径名。
- String getParent():返回此对象所对应目录的父目录名
- boolean renameTo(File newName):重命名此对象的文件或者目录,如果成功就返回true
2)、文件检测的相关的方法
- exists():判断file对象所对应的文件或者目录是否存在
- canWrite():判断是否可写
- canRead():是否可读
- isFile():判断是否是文件
- isDirectory():判断是否是目录
- isAbsolute:判断是否是绝对路径
3)、获取常规文件信息
- 返回文件最后修改的时间 lastModified
- 返回文件内容的长度 length
4)文件操作相关的方法
- boolean createNewFile():创建一个文件
- boolean delete():删除文件或者目录
- static File createTempFile():创建临时的空文件
- void deleteOnExit():当虚拟机退出的适合删除对应的文件或者目录
5)目录操作相关方法
- boolean mkdir():创建对应的目录
- String[] list():列出对象的所有子文件名和路径名,返回string数组
- File[] listFiles(): 返回file组
6)文件过滤器的使用
对于File类的list()方法中可以传入FilenameFilter参数,FilenameFilter接口有个accept方法,该方法返回true,list就会返回目录或者文件
// 返回后缀为.java 的文件
String[] nameList = file.list((dir,name) -> name.endsWith(".java"))
二 、java的io流
1、流的分类
- 输入流和输出流
输入流:只能从中读取数据,而不能向其写入数据。
输出流:只能向其写入数据,而不能从中读取数据。
都是从内存的角度划分的。 - 字节流和字符流
字节流操作的数据单元是8位的字节,而字符流操作的数据单元是16位的字符。 - 节点流和处理流
节点流也称为低级流是从io设备中读出或者写入的数据流。
处理流也称高级流
只要流的构造器参数不是一个物理节点,而是已经存在的流,那么这种流就一定是处理流,而所有的节点流都是直接以物理io节点作为构造器参数。
2、流的概念模型
java把所有设备里的有序数据抽象成流模型,相当于一个水管,读数据时接一个水管,输出的时候也放入到水管中。
3、字节流和字符流
- InputStream 和 Reader 是所有输入流的抽象基类。
- OutputStream 和 Write 是所有输出流的抽象基类。
4、输入/输出流体系
- FileInputStream、FileOutputStream、FileReader、FileWriter
File file = new File("test.txt");
FileInputStream fileInputStream = new FileInputStream(file);
// 这是一种
int read = fileInputStream.read();
System.out.println((char) read);
// 第二种读取
byte[] b = new byte[5];
int read1 = fileInputStream.read(b);
String string = new String(b, 0, read1);
System.out.println(string);
- StringReader、StringWriter
char[] chars = new char[32];
int hasread = 0;
String string1 = "testtest测试测试";
StringReader stringReader = new StringReader(string1);
while ((hasread = stringReader.read(chars)) > 0){
System.out.println(new String(chars,0,hasread));
}
- BufferedInputStream 、BufferedOutputStream、BufferedReader、BufferedWriter
InputStreamReader inputStreamReader = new InputStreamReader(System.in);
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
String reads = "";
while (( reads = bufferedReader.readLine()) != null){
}
5、重定向标准输入、输出
System类提供了3个重定向标准输入/输出的方法
static void setErr(PrintStream err):重定向“标准”错误输出流。
static void setIn(InputStream in):重定向“标准”输入流。
static void setOut(PrintStream out):重定向“标准”输出流
6、java虚拟机读写其他进程的数据
- InputStream getErrorStream():获取子进程的错误流
- InputStream getInputStream():获取子进程的输入流
- OutStream getOutputStream():获取子进程的输出流
Process process = Runtime.getRuntime().exec("javac");
BufferedReader bufferedReader1 = new BufferedReader(new InputStreamReader(process.getErrorStream()));
String line = null;
while ((line = bufferedReader1.readLine()) != null){
System.out.println(line);
}
7、RandomAccessFile
RandomAccessFile 可以读取文件内容,也可以向文件输出数据,与普通的输入/输出流不同的是,可以自由的访问文件的任意位置。
long getFilePointer():返回文件记录指针的当前位置
void seek(long pos):将文件记录指针定位到pos位置
8、对象序列化
1)、对象序列化的目标是将对象保存到磁盘中,或允许在网络中直接传输对象。
对象支持序列化,类实现两个接口之一:
Serializable
Externalizable
2)、两个步骤序列化对象:
- 创建一个ObjectOutputStream处理流
ObjectOutputSteam oos = new ObjectOutputStream(new FileOutputStream("xxx.txt"))
- 调用ObjectOutputStream对象的writeObject()方法输出可序列化对象。
反序列化使用objectoutputstream的readObject方法读取流中的对象。反序列化必须提供类的class文件,不然会抛出找不到类的错误。
3)、对象引用的序列化
对象的变量存在引用对象不是可序列化的对象无法序列化。
9、NIO
新IO采用内存映射文件的方式来处理输入/输出,将文件或者文件的一段区域映射到内存中,这种方式比传统的要快速很多。
1)、Channel(通道)
chnanel是对传统的输入输出系统的模拟,在新io系统中所有的数据都需要通过通道传输。提供了一个map()方法。
File file = new File("test.txt");
try (
// 所有channel不应该用构造器创建
// 创建channel
FileInputStream fileInputStream = new FileInputStream(file);
FileChannel inchannel = fileInputStream.getChannel();
FileChannel outchannel = new FileOutputStream(file).getChannel();
)
{
// 将channel的数据全部映射到buffer
MappedByteBuffer buffer = inchannel.map(FileChannel.MapMode.READ_ONLY, 0,file.length());
// 使用字符集
Charset charset = Charset.forName("GBK");
// 直接将buffer的数据输出
outchannel.write(buffer);
// clear
buffer.clear();
// 创建解码器对象
CharsetDecoder newDecoder = charset.newDecoder();
// 使用解码器转换
CharBuffer charBuffer = newDecoder.decode(buffer);
System.out.println(charBuffer.toString());
} catch (Exception e) {
// TODO: handle exception
}
2)、Buffer(缓冲)
buffer可以理解成一个容器,本质是一个数组。发送到所有的channel中的所有对象都必须先放在buffer中。
int capacity = 8;
// 创建buffer
CharBuffer buff = CharBuffer.allocate(capacity );
System.out.println("limite:" + buff.limit());
System.out.println("capacity:" + buff.capacity());
System.out.println("position" + buff.position());
// 放入元素
buff.put('a');
buff.put('b');
buff.put('c');
// 取出元素前调用flip
buff.flip();
// 取出元素
System.out.println("第一个元素:" + buff.get());
// 重新放入元素 调用 clear
buff.clear();
// 根据绝对位置拿出元素 clear后 元素还在 只是游标指向0
buff.get(2);
3)、字符集和Charset
- 编码(encode):把明文的字符序列遍成二进制
- 解码(decode):把二进制转为字符
- java 使用unicode字符集
- Charset提供处理字节系列和字符系列的关系
// 创建字符集
Charset charset = Charset.forName("UTf-8");
// 获取字符集的编码器和解码器
CharsetEncoder encoder = charset.newEncoder();
CharsetDecoder decoder = charset.newDecoder();
CharBuffer charBuffer = CharBuffer.allocate(8);
charBuffer.put('你');
charBuffer.put('好');
charBuffer.put('啊');
charBuffer.flip();
// 将字符系列转换成字节系列
ByteBuffer byteBuffer = encoder.encode(charBuffer);
for( int i = 0; i < byteBuffer.limit();i++){
System.out.println(byteBuffer.get(i) + " ");
}
// 解码输出
System.out.println("\n" + decoder.decode(byteBuffer));