一、文件的概念以及文件基本函数的操作
1. 什么是文件:文件可认为是相关记录或放在一起的数据的集合
2. File类是“文件和目录路径名的抽象表示”。 而不是指文件的内容。
3. File类定义了一些与平台无关的方法操作,如:创建、删除文件和重命名等。
4. Java中目录被看成是一个特殊的文件。List()方法可以返回目录中所有的子目录和文件。
5. 在unix下路径分隔符为(/),而在windos中则是为(\),在java中可以正确的处理不同系统中的分隔符。
示例代码:
package com.study.test;
import java.io.*;
import java.util.Date;
import static java.lang.System.*;
//什么是文件:文件可认为是相关记录或放在一起的数据的集合
//File类是“文件和目录路径名的抽象表示”。 而不是指文件的内容。
//File类定义了一些与平台无关的方法操作,如:创建、删除文件和重命名等。
//Java中目录被看成是一个特殊的文件。List()方法可以返回目录中所有的子目录和文件。
//在unix下路径分隔符为(/),而在windos中则是为(\),在java中可以正确的处理不同系统中的分隔符。
public class MyFile {
public static void main(String[] args) {
// //F:\\temp\\java\\luna\\io\\src\\aa.txt
File f1 = new File("D:\\study\\aa.txt");// 通过File类的构造函数传入一个文件名称
out.println(f1.getName());
out.println(f1.getPath());// 获取相对路径
out.println(f1.getAbsolutePath());// 获取绝对路径
out.println(f1.getAbsoluteFile());// 目录也可以看作一个文件
out.println(f1.getParent());// 返回此文件对象的父目录
File f2 = new File("D:\\study\\bb.txt");
out.println(f1.renameTo(f2));// 把文件aa.txt重新命名为bb.txt
out.println(f2.exists());
out.println(f1.canRead());
out.println(f1.canWrite());
out.println(f1.isFile());
out.println(f1.isDirectory());
out.println(new Date(f2.lastModified()));// 文件最后的修改时间
out.println(f1.length());// 获取文件内容的长度
}
}
二、文件字节流FileInputStream与FileOutputStream的区别以及文件复制的实现
1. 文件输入流(FileInputStream)与文件输出流(FileOutputStream)的区别
1.1 FileInputStream:从已经存在的文件中获取里面已输入的内容,获取的是ASCII码字节
1.2 FileOutputStream:把内容写入到指定的文件中去,如果指定的文件不存在则自己创建一个,写入是以字节为单位的,每次只能写一个
2. 文件复制的实质就是从一个文件中读取内容到另一个文件中去,如果目标文件不存在则自动创建一个
示例代码:
package com.study.test;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
//文件输入流(FileInputStream)与文件输出流(FileOutputStream)的区别
//FileInputStream:从已经存在的文件中获取里面已输入的内容,获取的是ASCII码字节
//FileOutputStream:把内容写入到指定的文件中去,如果指定的文件不存在则自己创建一个,写入是以字节为单位的,每次只能写一个
//文件复制的实质就是从一个文件中读取内容到另一个文件中去,如果目标文件不存在则自动创建一个
public class FileCopy {
public static void main(String[] args) throws IOException {
FileInputStream f1 = new FileInputStream("D:\\study\\bb.txt");
FileOutputStream f2 = new FileOutputStream("D:\\study\\aa.txt");
while (true) {
int i = f1.read();
f2.write(i);
if (i == -1)
break;
}
f1.close();
f2.close();
}
}
3. 往文件里面写入字符串
示例代码:
package com.study.test;
import java.io.BufferedWriter;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
public class ReadFileAndWirteFile {
public static void main(String[] args) throws IOException {
// 写内容(以字节写入)到指定文件中,如果文件不存在则自动创建
FileOutputStream f2 = new FileOutputStream("D:\\study\\dd.txt");
// 把写入的字节转换成字符流
OutputStreamWriter osw = new OutputStreamWriter(f2);
// 以整行方式把字符流写入目标文件中 调用
BufferedWriter bw = new BufferedWriter(osw);
bw.write("您好!");
bw.write("您好!");
bw.write("您好!");
bw.close();// 一定要关闭,否则不能写入 缓冲区游离
f2.close();
}
}
三、文件字符流读取(FileReader)与写入(FileWriter)的区别
package com.study.test;
import java.io.*;
//文件字符流读取FileReader与写入FileWriter的区别
import static java.lang.System.*;
public class ReadFileAndWirteFile {
public static void main(String[] args) throws IOException {
// 文件字符流读取:FileReader
FileReader fr = new FileReader("D:\\study\\bb.txt");// 读取指定文件的内容并将其转换为字符流
BufferedReader br = new BufferedReader(fr);// 将字符流包装到缓冲区
String s;
while ((s = br.readLine()) != null) {
out.println(s);
}
// 文件字符流写入:FileWriter
// 把字符文件写入指定文件中,如果文件不存在则自动创建, FileWriter已经将字节转换为字符不用再用OutputStreamWriter来转换
FileWriter fw = new FileWriter("D:\\study\\ee.txt");
BufferedWriter bw = new BufferedWriter(fw);
bw.write("我们");
bw.close();// 一定要关闭 否则不能写入
}
}
四、找到指定目录下指定文件格式的文件
package com.study.test;
import static java.lang.System.out;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
class AA implements FilenameFilter {
private String i;
AA(String i) {
this.i = i;
}
@Override
public boolean accept(File dir, String name) {
return name.endsWith(this.i);
}
}
public class ReadFileAndWirteFile {
public static void main(String[] args) throws IOException {
File f = new File("D:\\study");
// 只想搜索.txt文件
for (File temp : f.listFiles(new AA("txt")))
out.println(temp.getName());
}
}
五、什么是NIO
NIO提供了一个全新的底层I/O模型,与最初的java.io包中面向流的概念不同,NIO中采用了面向块的概念。
I/O操作以大的数据块为单位进行,而不是一次一个字节或字符进行。
采用这样的操作方式java的I/O性能有很大提高,但也牺牲了java操作的简单性。
NIO中所有的操作都要使用到缓冲区(内存)处理,且所有的读写操作都是通过缓冲区(内存)完成的。
NIO提供与平台无关的非阻塞I/O。与面向线程的、阻塞式I/O方式比较,多道通信、非阻塞I/O技术可以使应用程序更有效地处理大量连接的情况。
Java新IO中使用Buffer和Channel支持以上的操作。
六、NIO之Buffer类以及其方法的使用
1. Buffer类与StringBuffer非常类似,都可以自动扩容,只不过Buffer的效率更高,因为Buffer类是把内容放入内存中(缓冲区)以数据块的方式读写的,而StringBuffer是以流的方式读写的
示例代码:
package com.study.test;
import static java.lang.System.*;
import java.nio.CharBuffer;
public class NIOBuffer {
public static void main(String[] args) {
// Buffer类与StringBuffer非常类似,都可以自动扩容,只不过Buffer的效率更高,
// 因为Buffer类是把内容放入内存中(缓冲区)以数据块的方式读写的,而StringBuffer是以流的方式读写的
// 创建缓冲
// CharBuffer存储字符 用allocate 用allocate(int capacity)分配缓冲区空间
CharBuffer buffer = CharBuffer.allocate(4);
buffer.put('a');// 位置0插入a
buffer.put('b');// 位置1插入b
out.println(buffer.position());// 当前位置为2 缓冲区的指针指向即将操作的下一个位置
out.println(buffer.limit());// limit=4 //把缓冲区的容量限制为当前容量 不能再自动扩容 只能存储4个字符
// out.println(buffer.capacity());//capacity=4//缓冲区的当前容量
// buffer.put('c');
// buffer.put('d');
// buffer.put('e');//异常 bufferoverflowexception 因为缓冲区容量已被limit方法限制为4
// 所以此时不能插入多余数据到缓冲区
out.println(buffer);// 从当前位置输出什么都没有
out.println("-------------------改变指针-------------------------");
// 改变指针
buffer.position(0);
out.println(buffer.limit());// limit=4
out.println(buffer.capacity());// capacity=4;
out.println(buffer);// 输出内容 ab
// 重置缓冲区
out.println("-------------------重置缓冲区-------------------------");
buffer.flip();
out.println(buffer.position());
out.println(buffer.limit());// limit=2
out.println(buffer.capacity());// capacity=4;
out.println(buffer);// 输出内容,仅仅输出到limit,不会输出多余字符
out.println(buffer.position(4));// 定位到b之后继续输入
buffer.put('c');// 缓冲区已经重置到0位置 所以不能插入 必须 重置到位置2才能插入
// //子缓冲区
// CharBuffer childBuffer=buffer.slice();//截取0到达limit的位置
// out.println(childBuffer);//
// out.println(childBuffer.limit());
// out.println(childBuffer.capacity());
// //只读缓冲区
// CharBuffer bufferRO=buffer.asReadOnlyBuffer();
// bufferRO.put('x');//出错
}
}
七、NIO之内存映射与传统IO流的区别
1. 内存映射可以把文件映射到内存中,这样文件内的数据就可以用内存读写指令来访问,而不是用InputStream或OutputStream这样的I/O操作类,采用此方式读取文件的速度是最快的。使用FileChannel类提供的map()方法。
2. Map()方法在使用时要指定映射模式,在内存映射中提供三种模式:读取和写入:READ_WRITE,只读READ_ONLY,专用(写入时复制)映射模式
示例代码:
package com.study.test;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
//内存映射可以把文件映射到内存中,这样文件内的数据就可以用内存读写指令来访问,而不是用InputStream或OutputStream这样的I/o操作类,
//采用此方式读取文件的速度是最快的。使用FileChannel类提供的map()方法。
//Map()方法在使用时要指定映射模式,在内存映射中提供三种模式:读取和写入:READ_WRITE,只读READ_ONLY,专用(写入时复制)映射模式
public class NIOBuffer {
public static void main(String[] args) throws IOException {
// 下面再次读取文件,原来的流其实是一个管子
RandomAccessFile fis = new RandomAccessFile("D:\\study\\cc.txt", "rw");// 获取一个文件
// 不直接通过流了,出现了一个管道
FileChannel fc = fis.getChannel();// 通过通道把文件映射到内存中去
// 怎么用通道读取内容? 通过FileChannel的map()方法读写文件
MappedByteBuffer mb = fc.map(FileChannel.MapMode.READ_WRITE, 4,
new File("D:\\study\\cc.txt").length());
mb.put(1, (byte) '2');
mb.put(2, (byte) '3');
}
}