1. File类
介绍
- java.io.File类:文件和文件目录路径的抽象表示形式,与平台无关
- File 能新建、删除、重命名文件和目录,但 File 不能访问文件内容本身。如果需要访问文件内容本身,则需要使用输入/输出流。
- 想要在Java程序中表示一个真实存在的文件或目录,那么必须有一个File对象,但是Java程序中的一个File对象,可能没有一个真实存在的文件或目录。
- File对象可以作为参数传递给流的构造器
常用构造器
public File(String pathname) public File(String parent,String child) public File(File parent,String child)
路径分隔符 路径中的每级目录之间用一个路径分隔符隔开, windows和DOS系统默认使用“\”来表示,UNIX和URL使用“/”来表示。Java程序支持跨平台运行,因此路径分隔符要慎用。为了解决这个隐患,File类提供了一个常量:public static final String separator。根据操作系统,动态的提供分隔符。
常用方法
栗子:筛选出以.txt结尾的文件,并打印文件名
File data = new File("E:\\CODE\\review\\javaReview\\data");
File[] files = data.listFiles();
for (File file : files) {
String name = file.getName();
if(name.contains(".txt")){
System.out.println(name);
}
}
2. IO流整体介绍
概述 I/O是Input/Output的缩写, I/O技术是非常实用的技术,用于处理设备之间的数据传输。如读/写文件,网络通讯等。Java程序中,对于数据的输入/输出操作以“流(stream)” 的 方式进行。 java.io包下提供了各种“流”类和接口,用以获取不同种类的数据,并通过标准的方法输入或输出数据。
输入input:读取外部数据(磁盘、光盘等存储设备的数据)到程序(内存)中。 输出output:将程序(内存)数据输出到磁盘、光盘等存储设备中。
IO流的分类 IO流体系如下: 4大抽象基类的说明 输入流基类Inputstream & Reader InputStream 和 Reader 是所有输入流的基类。InputStream的典型实现为FileInputStream,用于读取数据的常用方法如下:
int read()
int read(byte[] b)
int read(byte[] b, int off, int len)
Reader的典型实现为FileReader,读取数据常用的方法如下:
int read()
int read(char [] c)
int read(char [] c, int off, int len)
FileInputStream 从文件系统中的某个文件中获得输入字节。FileInputStream用于读取非文本数据之类的原始字节流。要读取字符流,需要使用 FileReader。要注意的是,程序中打开的文件 IO 资源不属于内存里的资源,垃圾回收机制无法回收该资源,所以应该显式关闭文件 IO 资源。
输出流基类 OutputStream && Writer OutputStream 和 Writer 也非常相似,提供的常用方法主要如下:
void write(int b/int c); void write(byte[] b/char[] cbuf); void write(byte[] b/char[] buff, int off, int len); void flush(); void close(); 需要先刷新,再关闭此流
但因为字符流直接以字符作为操作单位,所以 Writer 可以用字符串来替换字符数组,即以 String 对象作为参数,Writer额外的写出数据的方法如下:
void write(String str); void write(String str, int off, int len);
FileOutputStream 从文件系统中的某个文件中获得输出字节。FileOutputStream用于写出非文本数据之类的原始字节流。要写出字符流,需要使用 FileWriter。
3. 节点流的使用
节点输入流:FileInputStream \ FileReader 节点输出流:FileOuputStream \ FileWriter 使用节点流读取文件的步骤:
- 建立一个流对象,将已存在的一个文件加载进流。
- 创建一个临时存放数据的数组。
- 调用流对象的读取方法将流中的数据读入到数组中。
- 关闭资源。
栗子1:使用FileReader读取文件内容并打印
FileReader reader = null;
try {
reader = new FileReader(new File("E:\\CODE\\review\\javaReview\\data\\data1.txt"));
char[] chars = new char[1024];
int len ;
while ((len = reader.read(chars)) != -1){
System.out.println(new String(chars,0 ,len));
}
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
栗子二:使用FileInputStream和FileOutputStream实现文件的复制
FileInputStream fin = null;
FileOutputStream fout = null;
try {
fin = new FileInputStream(new File("E:\\CODE\\review\\javaReview\\data\\01.jpg"));
fout = new FileOutputStream(new File("E:\\CODE\\review\\javaReview\\data\\02.jpg"));
byte[] buff = new byte[1024];
int len;
while ((len = fin.read(buff)) != -1){
fout.write(buff,0, len);
fout.flush();
}
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
fin.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
fout.close();
} catch (IOException e) {
e.printStackTrace();
}
}
节点流使用注意点
- 定义文件路径时,注意:可以用“/”或者“\”。
- 在写入一个文件时,如果使用构造器FileOutputStream(file),则目录下有同名文件将被覆盖。
- 如果使用构造器FileOutputStream(file,true),则目录下的同名文件不会被覆盖,在文件内容末尾追加内容。
- 在读取文件时,必须保证该文件已存在,否则报异常。
- 字节流操作字节,比如:.mp3,.avi,.rmvb,mp4,.jpg,.doc,.ppt
- 字符流操作字符,只能操作普通文本文件。最常见的文本文件:.txt,.java,.c,.cpp 等语言的源代码。尤其注意.doc,excel,ppt这些不是文本文件。
4. 处理流
4.1 缓冲流
为了提高数据读写的速度,Java API提供了带缓冲功能的流类,在使用这些流类时,会创建一个内部缓冲区数组,缺省使用8192个字节(8Kb)的缓冲区。缓冲流要“套接”在相应的节点流之上,根据数据操作单位可以把缓冲流分为:
- BufferedInputStream 和 BufferedOutputStream
- BufferedReader 和 BufferedWriter
当使用BufferedInputStream读取字节文件时,BufferedInputStream会一次性从文件中读取8192个(8Kb),存在缓冲区中,直到缓冲区装满了,才重新从文件中读取下一个8192个字节数组。向流中写入字节时,不会直接写到文件,先写到缓冲区中直到缓冲区写满,BufferedOutputStream才会把缓冲区中的数据一次性写到文件里。使用方法flush()可以强制将缓冲区的内容全部写入输出流。 关闭流的顺序和打开流的顺序相反。只要关闭最外层流即可,关闭最外层流也会相应关闭内层节点流。 栗子:使用BufferReader和BufferWriter实现文本文件的复制
BufferedReader br = null;
BufferedWriter bw = null;
try {
br = new BufferedReader(new FileReader("E:\\CODE\\review\\javaReview\\data\\data1.txt"));
bw = new BufferedWriter(new FileWriter("E:\\CODE\\review\\javaReview\\data\\data3.txt"));
String buff;
while ((buff = br.readLine()) != null){
bw.write(buff);
bw.newLine();
}
} catch (Exception e) {
e.printStackTrace();
}finally {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
4.2 转换流
转换流提供了在字节流和字符流之间的转换,Java API提供了两个转换流:
- InputStreamReader:将InputStream转换为Reader
- OutputStreamWriter:将Writer转换为OutputStream
InputStreamReader
- 实现将字节的输入流按指定字符集转换为字符的输入流。
- 需要和InputStream“套接”。
- 构造器
public InputStreamReader(InputStream in) public InputSreamReader(InputStream in,String charsetName)
OutputStreamWriter
- 实现将字符的输出流按指定字符集转换为字节的输出流。
- 需要和OutputStream“套接”。
- 构造器
public OutputStreamWriter(OutputStream out) public OutputSreamWriter(OutputStream out,String charsetName)
FileInputStream fis = null;
FileOutputStream fos = null;
InputStreamReader isr = null;
OutputStreamWriter osw = null;
BufferedReader br = null;
BufferedWriter bw = null;
try {
fis = new FileInputStream("E:\\CODE\\review\\javaReview\\data\\data1.txt");
fos = new FileOutputStream("E:\\CODE\\review\\javaReview\\data\\data4.txt");
isr = new InputStreamReader(fis);
osw = new OutputStreamWriter(fos);
br = new BufferedReader(isr);
bw = new BufferedWriter(osw);
String str;
while ((str = br.readLine()) != null){
bw.write(str);
bw.newLine();
}
} catch (Exception e) {
e.printStackTrace();
}finally {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
4.3 对象流
ObjectInputStream && OjbectOutputSteam对象流,用于存储和读取基本数据类型数据或对象的处理流,对象流的作用如下: ObjectOutputStream:内存中的对象—>存储中的文件、通过网络传输出去:序列化过程 ObjectInputStream:存储中的文件、通过网络接收过来 —>内存中的对象:反序列化过程 对象的序列化 对象序列化机制允许把内存中的Java对象转换成平台无关的二进制流,从而允许把这种二进制流持久地保存在磁盘上,或通过网络将这种二进制流传输到另一个网络节点。 对象系列化步骤:
- 需要实现接口:Serializable
- 当前类提供一个全局常量:serialVersionUID
- 除了当前Person类需要实现Serializable接口之外,还必须保证其内部所属性 也必须是可序列化的。(默认情况下,基本数据类型可序列化)
栗子:
@Test
public void test1(){
ObjectOutputStream oos = null;
try {
oos = new ObjectOutputStream(new FileOutputStream("object.dat"));
oos.writeObject(new String("我爱中国!!"));
oos.writeObject(new Student("1001","小强"));
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
oos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
@Test
public void test2(){
ObjectInputStream ois = null;
try {
ois = new ObjectInputStream(new FileInputStream("object.dat"));
String str = (String)ois.readObject();
System.out.println(str);
Student stu = (Student)ois.readObject();
System.out.println(stu);
} catch (Exception e) {
e.printStackTrace();
}finally {
}
}
public class Student implements Serializable {
private static final long serialVersionUID = 12345678765432L;
private String id;
private String name;
public Student(String id, String name) {
this.id = id;
this.name = name;
}
@Override
public String toString() {
return "Student{" +
"id='" + id + '\'' +
", name='" + name + '\'' +
'}';
}
}
4.4 随机存储文件流
RandomAccessFile 声明在java.io包下,但直接继承于java.lang.Object类。并且它实现了DataInput、DataOutput这两个接口,也就意味着这个类既可以读也可以写。RandomAccessFile 类支持 “随机访问” 的方式,程序可以直接跳到文件的任意地方来读、写文件:
- 支持只访问文件的部分内容
- 可以向已存在的文件后追加内容
- RandomAccessFile 对象包含一个记录指针,用以标示当前读写处的位置。
RandomAccessFile 类对象可以自由移动记录指针:
- long getFilePointer():获取文件记录指针的当前位置
- void seek(long pos):将文件记录指针定位到 pos 位置
构造器
- public RandomAccessFile(File file, String mode)
- public RandomAccessFile(String name, String mode)
mode参数有如下4种:
r: 以只读方式打开 rw:打开以便读取和写入 rwd:打开以便读取和写入;同步文件内容的更新 rws:打开以便读取和写入;同步文件内容和元数据的更新
@Test
public void test3() throws IOException {
RandomAccessFile raf1 = new RandomAccessFile("hello.txt","rw");
raf1.seek(3);
StringBuilder builder = new StringBuilder((int) new File("hello.txt").length());
byte[] buffer = new byte[20];
int len;
while((len = raf1.read(buffer)) != -1){
builder.append(new String(buffer,0,len)) ;
}
raf1.seek(3);
raf1.write("xyz".getBytes());
raf1.write(builder.toString().getBytes());
raf1.close();
}
5. Path/Paths/Files的使用
NIO简单概述
- Java NIO (New IO,Non-Blocking IO)是从Java 1.4版本开始引入的一套新的IO API,可以替代标准的Java IO AP。
- NIO与原来的IO同样的作用和目的,但是使用的方式完全不同,NIO支持面向缓冲区的(IO是面向流的)、基于通道的IO操作。
- NIO将以更加高效的方式进行文件的读写操作。
- 随着 JDK 7 的发布,Java对NIO进行了极大的扩展,增强了对文件处理和文件系统特性的支持,以至于我们称他们为 NIO.2。
Path类:JDK7提供 实例化方法:
- static Path get(String first, String … more) : 用于将多个字符串串连成路径
- static Path get(URI uri): 返回指定uri对应的Path路径
Path 常用方法:
Files类:JDK7提供 用途:用于操作文件或目录的工具类 常用方法:
|