IO流
1.File
File是一个类,可以由构造器创建对象,对应一个文件或者一个目录
1.1 构造函数
// 路径:
//绝对路径:包括盘符的完整的路径
//相对路径:相对于当前文件的路径
//File的属性separator存储了当前系统的路径分隔符。在UNIX、Linux中,此字段为‘/’,在Windows中,为‘\\’
File f1 = new File("d:/java/io/helloword.txt");
File f2 = new File("hello.txt");
File f3 = new File("d:\\java\\io");
1.2 方法
//文件名相关
getName();//获取文件名
getPath();//获取文件路径
getAbsoluteFile();//获取文件路径
getAbsolutePath();//获取文件绝对路径
getParent();//获取父路径
f1.renameTo(f2);//重命名,f1重命名为f2,f1一定存在,f2一定不存在
//文件检测判断
exists();
canWrite();
canRead();
isFile();
isDirectory();
//获取常规信息
lastModifed();//最后修改时间,long型值
length();//长度,long型
//文件创建、删除
boolean createNewFile();//创建新文件
boolean delete()
//目录相关操作
boolean mkdir();//创建目录,只有上层目录存在的时候才会创建成功
booolean mkdirs();//创建目录,上层目录不存在同时创建
tring[] list();//
File[] listFiles();//
2 IO流
输入:读取外部数据(磁盘、光盘等外部存储设备上的数据)到程序(内存)中。
输出:将程序(内存)中的数据输出到磁盘光盘等存储设备中。
2.1 分类
输入流:
输出流:
字节流:8bit,处理视频、音频等
字符流:16bit,处理文本文件
节点流:FileInputStream、FileOutputStream、FileReader、FileWriter
处理流:
分类 | 字节输入流 | 字节输出流 | 字符输入流 | 字符输出流 |
---|---|---|---|---|
抽象基类 | InputStream | OutputStream | Reader | Writer |
访问文件(节点流、文件流) | FileInputStream | FileOutputStream | FileReader | FileWriter |
访问数组 | ByteArrayInputStream | ByteArrayOutputStream | CharArrayReader | CharArrayWriter |
访问管道 | PipedInputStream | PipedOutputStream | PipedReader | PipedWriter |
访问字符串 | - | - | StringReader | StringWrited |
缓冲流 | bufferedInputStream | BufferedInputStream | BufferedReader | BufferedWriter |
转换流 | - | - | InputStreamReader | OutputStreamWriter |
对象流 | ObjectInputStream | ObjectOutputStream | - | - |
- | FilterInputStream | FilterOutputStream | FilterReader | FilterWriter |
打印流 | - | PrintStream | - | - |
推回输入流 | PushbackInputStream | - | PushbackReader | - |
特殊流 | DataInputStream | DataOutputStream | - | - |
2.2 FileInputStream 和 FileOutputStream
字节流用于读取和写非文本文件
@Test
public void testOut(){
File f1 = new File("fileOut.txt");
FileOutputStream fo = null;
try {
fo = new FileOutputStream(f1);
fo.write(new String("hello world !").getBytes());
}catch (Exception e){
e.printStackTrace();
}finally {
if (fo !=null)
try {
fo.close();
}catch (Exception e){
e.printStackTrace();
}
}
}
2.3 FileReader 和FileWriter
字符流,用于读和写
/**
* FileReader和FileWriter用于复制文件文件的字符流
* @param srcPath 源文件路径,源文件必须存在
* @param destPath 目标文件路径,可以不存在
*/
private void copyTextFile(String srcPath,String destPath){
File src = new File(srcPath);
if (!src.exists()||!src.isFile())
return;
FileReader fr = null;
FileWriter fw = null;
try {
//源文件一定要存在
File dest = new File(destPath);
fr = new FileReader(src);
fw = new FileWriter(dest);
char[] c = new char[24];
int len;
while ((len =fr.read(c))!=-1){
fw.write(c,0,len);
}
}catch (IOException e){
e.printStackTrace();
}finally {
if (fr!=null){
try {
fr.close();
} catch (IOException e) {
e.printStackTrace();
}finally {
if (fw!=null) {
try {
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
}
2.4 BufferedInputStream 和BufferedOutputStream
对字节流的操作进行加速,当字节数组大小为1024时, 一个200m视频文件采用字节流形式复制需要1400ms左右,采用缓冲流需要800ms左右。
/**
* 为了代码的简洁性采用抛出异常的方式,应使用try-catch-finally
* 采用缓冲流的方式加速文件复制处理
* 当字节数组大小为1024时, 一个200m视频文件采用字节流形式复制需要1400ms左右,采用缓冲流需要800ms左右
* @param src
* @param des
*/
private void copyBufferedStream(String src,String des) throws IOException{
File s = new File(src);
File d = new File(des);
//2.先创建相应的节点流:FileInputStream,FileOutputStream
BufferedInputStream bis =null;
BufferedOutputStream bos =null;
//3. 将创建的节点流对象传入缓冲流的构造器中
bis= new BufferedInputStream(new FileInputStream(s));
bos = new BufferedOutputStream(new FileOutputStream(d));
//4。 实现具体的文件复制操作
byte[] b = new byte[1024];
int len ;
while ((len = bis.read(b)) != -1) {
bos.write(b,0,len);
bos.flush();
}
// 5.关闭相应的流,可以只关闭外层
bis.close();
bos.close();
}
2.4 BufferedReader 和 BufferedWriter
对字符流的操作进行加速,用法和BufferedInputStream\BufferedOutputStream类似
2.5 转换流
实现字节流和字符流的转换。
编码:字符串–>字节数组 解码:字节数组–>字符串
2.6 标准输入流和标准输出流
System.In
System.out
2.7 打印流
2.8 数据流
DataInputStream 和 DataOutputStream
数据流:用来处理基本数据类型、String、字节数组的数据:DataInputStream DataOutputStream
2.9 对象流
用于存储和读取java对象的处理流。可以把java对象写入数据源中,也可以从数据源中还原java对象
2.9.1 对象的序列化
序列化(Serialize):把内存中的java对象转换成平台无关的二进制流,从而可以持久的保存在磁盘上或者通过网络传输到另一网络节点。
- 实现:用ObjectOutputStream将java对象写入IO流
反序列化:当程序获取到了序列化的二进制流,通过反序列化转化为原来的java对象。
- 实现:用ObjectInputStream类将IO流中还原出java对象
序列化是RMI(Remote Method Invoke远程方法调用)过程的参数和返回值都必须实现的机制
@Test
public void testObjectInputStream() {
ObjectInputStream ois = null;
try {
ois = new ObjectInputStream(new FileInputStream("person.txt"));
Person p1 = (Person)ois.readObject();
System.out.println(p1);
Person p2 = (Person)ois.readObject();
System.out.println(p2);
}catch (Exception e) {
e.printStackTrace();
}finally{
if(ois != null){
try {
ois.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
// 对象的序列化过程:将内存中的对象通过ObjectOutputStream转换为二进制流,存储在硬盘文件中
@Test
public void testObjectOutputStream() {
Person p1 = new Person("小米", 23,new Pet("花花"));
Person p2 = new Person("红米", 21,new Pet("小花"));
ObjectOutputStream oos = null;
try {
oos = new ObjectOutputStream(new FileOutputStream("person.txt"));
oos.writeObject(p1);
oos.flush();
oos.writeObject(p2);
oos.flush();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
if (oos != null) {
try {
oos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
/*
* 要实现序列化的类: 1.要求此类是可序列化的:实现Serializable接口
* 2.要求类的属性同样的要实现Serializable接口
* 3.提供一个版本号:private static final long serialVersionUID
* 4.使用static或transient修饰的属性,不可实现序列化
*/
class Person implements Serializable {
private static final long serialVersionUID = 23425124521L;
static String name;
transient Integer age;
Pet pet;
public Person(String name, Integer age,Pet pet) {
this.name = name;
this.age = age;
this.pet = pet;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + ", pet=" + pet + "]";
}
}
class Pet implements Serializable{
String name;
public Pet(String name){
this.name = name;
}
@Override
public String toString() {
return "Pet [name=" + name + "]";
}
}
2.10 RandomAccessFile
支持随机访问,既可以充当输入流也可以充当输出流,支持从任意位置读取和写入。支持只访问文件的部分内容,可以向已存在的文件后追加内容。
构造器
public RandomAccessFile(File file, String mode)
public RandomAccessFile(String name, String mode)
创建 RandomAccessFile 类实例需要指定一个 mode 参数,该参数指定 RandomAccessFile 的访问模式:
r: 以只读方式打开
rw:打开以便读取和写入
rwd:打开以便读取和写入;同步文件内容的更新
rws:打开以便读取和写入;同步文件内容和元数据的更新
方法:
long getFilePointer()//获取文件记录指针的当前位置
void seek(long pos)//将文件记录指针定位到pos
示例
@Test
public void test1() throws IOException {
String src ="";
String des="";
RandomAccessFile r1 = new RandomAccessFile(src,"r");
RandomAccessFile r2 = new RandomAccessFile(des,"rw");
byte[] bytes = new byte[1024];
int len = 0;
//将src内容连接到des文件末尾
r2.seek(r2.length());
while ((len = r1.read(bytes))!=-1){
r2.write(bytes,0,len);
}
r1.close();
r2.close();
}