目录
都属于java.io包
一、简介:
- 输出是写操作,输入是读操作。
- 流是指一连串流动的字符,以先进先出的方式发送信息的通道。
二、File类:
- 在Java中,使用java.io.File类对文件进行操作。
方法 | 说明 |
File(File parent,String child) | (构造方法)为File对象指明对哪个目录或文件操作 |
File(String parthname) | (构造方法) |
File(String parent,String child) | (构造方法) |
File(URI url) | (构造方法) |
boolean canRead() | 是否可读 |
boolean canWrite() | 是否可写 |
boolean exists() | 是否存在 |
String getName() | 获取名称 |
boolean isDirectory() | 是否是目录 |
boolean isFile() | 是否是文件 |
boolean mkdir() | 创建目录 |
boolean mkdirs() | 创建多级目录 |
例:
package com.file;
import java.io.File;
import java.io.IOException;
public class File1 {
public static void main(String[] args) {
//创建File对象
//法1:
File file1=new File("C:\\Users\\dell\\Desktop\\file\\io\\2.txt"); //注意转义字符的写法
//法2:
File file2=new File("C:\\Users\\dell\\Desktop", "file\\io\\1.txt"); //把路径分成2部分
//法3:
File file3=new File("C:\\Users\\dell\\Desktop");
File file4=new File(file3, "file\\io\\1.txt");
//判断文件是目录还是文件
System.out.println("是否是目录?"+file1.isDirectory());
System.out.println("是否是文件?"+file1.isFile());
System.out.println("是否是文件?"+file2.isFile());
System.out.println("是否是文件?"+file4.isFile());
//创建文件
File file5=new File("C:\\Users\\dell\\Desktop\\file\\set", "a");
if (!file5.exists()) {
file5.mkdir();
}
//在C:\Users\dell\Desktop\file\set下创建多级目录:a\b 。
File file6=new File("C:\\Users\\dell\\Desktop\\file\\set", "a\\b");
file6.mkdirs();
//创建文件
if (!file1.exists()) {
try {
file1.createNewFile(); //调用该方法需要捕获异常
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
二、绝对路径和相对路径:
- 绝对路径:从盘符开始的路径。
- 相对路径:从当前路径开始的路径。
- ..\ 向上返回一级目录
例:
package com.file;
import java.io.File;
import java.io.IOException;
public class File2 {
public static void main(String[] args) {
File f=new File("A\\m.txt");
try {
f.createNewFile();
//是否是绝对路径
System.out.println(f.isAbsolute());
//获取相对路径
System.out.println(f.getPath());
//获取绝对路径
System.out.println(f.getAbsolutePath());
//获取文件名
System.out.println(f.getName());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
注意:在Ecipse中生成的文件的位置:
三、字节流:
1.简介:
- 分为:字节输入流InputStream(从输入设备读取数据)和字节输出流OutputStream(把数据写入到输出设备中)。
- 类结构:
2.文件输入流FileInputStream:
- 从文件系统的某个文件中获取输入字节。
- 用于读取诸如图像数据之类的原始字节流。
方法 | 说明 |
FileInputStream(File file) | (构造方法) |
FileInputStream(FileDescriptor fd0bj) | (构造方法)使用文件描述符去创建对象 |
FileInputStream(String name) | (构造方法) |
public int read(int b) | 从输入流中读取1个数据字节 |
public int read(byte[] b) | 从输入流中将最多b.length个字节的数据读入一个byte数组中 |
public int read(byte[] b,int off,int len) | 从输入流中将最多len个字节的数据读入到byte数组中,off是偏移量(=0即从头开始读),len 是数据长度 |
public void close() | 关闭此文件输入流并是否与此流相关的所有系统资源 |
read()方法的int型的返回值为-1表示已读到文件末尾!是判断文件是否读完的标志。
例A:
先在项目中新建一个txt文件(内容为:Hello,Isebal!):
package com.file;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class File3 {
public static void main(String[] args) {
try {
FileInputStream fileInputStream = new FileInputStream("A.txt");
int n = 0;
while ((n = fileInputStream.read()) != -1) {
System.out.print((char) n); // 注意要强制转换成字符型,因为它读的是ASCILL码
}
fileInputStream.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) { // 注意这个异常写在后面,因为FileNotFoundException是其子类,会被覆盖。
e.printStackTrace();
}
}
}
例B:
package com.file;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class File4 {
public static void main(String[] args) {
try {
FileInputStream f1 = new FileInputStream("A.txt");
FileInputStream f2 = new FileInputStream("A.txt");
byte[] a = new byte[100];
byte[] b = new byte[100];
f1.read(a);
System.out.println(new String(a));
f2.read(b, 0, 5);
System.out.println(new String(b));
f1.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) { // 注意这个异常写在后面,因为FileNotFoundException是其子类,会被覆盖。
e.printStackTrace();
}
}
}
3.文件输出流FileOutputStream:
- 将数据写如入到文件中。
方法 | 说明 |
FileOutputStream(File file) | (构造方法) |
FileOutputStream(File file,boolean append) | (构造方法)append为true时在文件末尾追加数据 |
FileOutputStream(FileDescriptor fd0bj) | (构造方法) |
FileOutputStream(String name) | (构造方法) |
public void write(int b) | 将指定字节写入到此文件输出流 |
public void write(byte[] b) | 将b.length个字节从指定byte 数组写入此文件输出流中 |
public void write(int b)(byte[] b,int off,int len) | 将指定byte数组中从偏移量 off 开始的 len 个字节写入此文件输出流 |
public void close() | 关闭此文件输入流并是否与此流相关的所有系统资源 |
例A:
package com.file;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class FileOutPut {
public static void main(String[] args) {
FileOutputStream fileOutputStream; // 流的声明写在外面
FileInputStream fileInputStream;
try {
fileOutputStream = new FileOutputStream("A.txt"); //A
fileOutputStream.write(50);
fileOutputStream.write('a'); // 字符型和整型可互相转换
fileInputStream = new FileInputStream("A.txt");
System.out.println(fileInputStream.read()); // 按写发的顺序读,读50
System.out.println((char) fileInputStream.read()); // 读a
fileOutputStream.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
如果在A处的方法中添加参数2:true,文件发送变化如下:不是覆盖,而是在后面追加。
例B:文件的拷贝
package com.file;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class FileCopy {
public static void main(String[] args) {
// 文件拷贝
try {
FileInputStream file1 = new FileInputStream("jing.PNG");
FileOutputStream file2 = new FileOutputStream("jingxx.PNG");
int n = 0;
byte[] b = new byte[1024];
while ((n = file1.read(b)) != -1) {
file2.write(b);
}
file1.close();
file2.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
注意:此时发现拷贝后的文件总比原文件大1kb。解决:把write()方法添加2个参数:write(b,0,n) 。n表示实际读取的字节数组中的字节数,以保证2个文件的大小一致。
四、缓冲流:
- 包括缓冲输入流BufferedInputStream和缓冲输出流BufferedOutputStream。
- 直接从内存中读取数据,速度更快。
- 缓冲输入流BufferedInputStream和文件输入流FileInputStream结合使用,读取文件的过程为:FileInputStream将数据从数据源中读取出来,此时不是直接读到文件中进行接收,中间要通过一个缓冲流。用字节数组存放缓冲数据。
方法 | 说明 |
BufferedInputStream(inputStream in) | (构造方法)参数可以是任何inputStream的子类 |
BufferedInputStream(inputStream in,int size) | (构造方法)指定缓冲区大小 |
方法 | 说明 |
BufferedOutputStream(OutputStream in) | (构造方法)参数可以是任何inputStream的子类 |
BufferedOutputStream(OutputStream in,int size) | (构造方法)指定缓冲区大小 |
void flush() | 清空缓冲区 |
若缓冲区满,则自动执行写操作。 若缓存区不满,是不会触发write()方法,把数据写入到文件中。所以当缓冲区不满时,需要调用flush()方法进行缓冲区的强制清空。
五、字符流:
1.简介:
- 分为字符输入流Reader和字符输出流Writer。
- 类结构:
- 与字节输入/出流的区别:用途不同。字节输入/出流读写的都是二进制格式的数据。
2.字节字符转换流:
- 分为InputStreamReader和OutputStreamWriter。
方法 | 说明 |
InputStreamReader(InputStream in) | (构造方法) |
InputStreamReader(InputStream in, Charset cs) | (构造方法)可设置编码 |
InputStreamReader(InputStream in, CharsetDecoder dec) | (构造方法)可设置编码 |
InputStreamReader(InputStream in, String charsetName) | (构造方法) |
String getEncoding() | 获取字符编码 |
int read() | |
int read(char[] cbuf, int offset, int length) | |
boolean ready() | 判断流是否准备好读 |
方法 | 说明 |
OutputStreamWriter( OutputStream out) | (构造方法) |
OutputStreamWriter( OutputStream out, Charset cs) | (构造方法)可设置编码 |
OutputStreamWriter( OutputStream out, CharsetEncoder enc) | (构造方法)可设置编码 |
OutputStreamWriter( OutputStream out, String charsetName) | (构造方法) |
void write(int c) | |
void write(char[] cbuf, int off, int len) | |
void write(String str, int off,int len) |
package com.file;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
public class Reader {
public static void main(String[] args) {
try {
FileInputStream fis=new FileInputStream("A.txt");
//把FileInputStream和InputStreamReader连接:把fis作为InputStreamReader的参数。
InputStreamReader isr=new InputStreamReader(fis);
FileOutputStream fos=new FileOutputStream("AA.txt");
OutputStreamWriter osw=new OutputStreamWriter(fos);
int n=0;
char[]c=new char[10]; //注意这个是读到字符数组,而非字节数组。
//法1:
// while((n=isr.read())!=-1) {
// System.out.print((char)n);
// }
//法2:
while((n=isr.read(c))!=-1) {
String s=new String(c,0,n); //实际存储到字符数组的字符
System.out.println(s);
osw.write(c, 0, n);
osw.flush();
}
fis.close();
isr.close();
fos.close();
osw.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
}catch (IOException e) {
e.printStackTrace();
}
}
}
注意:读、写数据的编码要一致,否则会出现中文乱码问题。
3.字符的缓冲流:
- 包括BufferedReader和BufferedWriter。
方法 | 说明 |
BufferedReader(Reader in) | (构造方法) |
BufferedReader(Reader in, int sz) | (构造方法)自定义字符数 |
int read() | |
int read(char[] cbuf,int off, int len) | |
String readLine() | 读取一行(以/r或/n作为换行标志) |
方法 | 说明 |
BufferedWriter(Writer out) | (构造方法) |
BufferedWriter(Writer out, int sz) | (构造方法)自定义字符数 |
void write(int c) | |
void write(char[] cbuf,int off, int len) | |
void write(String s,int off,int len) | |
void newLine() | 写一个行分隔符 |
六、对象序列化与反序列化:
1.简介:
- 序列化:把Java对象转换成字节序列的过程(即写对象的过程)。
- 反序列化:把字节序列恢复成Java对象的过程(即读对象的过程)。
2.步骤:
- 创建一个类,继承Serializable接口(序列化接口)。
- 创建对象。
- 将对象写入文件。
- 从文件读取对象信息。
3.涉及到2个类:
- 对象输入流ObjectInputStream和对象输出流ObjectOutputStream。
方法 | 说明 |
ObjectInputStream() | (构造方法) |
ObjectInputStream(InputStream out) | (构造方法) |
String readObject(Object obj) | 读取writeObject()写的数据,与其搭配使用 |
方法 | 说明 |
ObjectOutputStream() | (构造方法) |
ObjectOutputStream(OutputStream out) | (构造方法) |
void writeObject(Object obj) | 写对象 |
方法 说明 (构造方法)
例:
package com.serial;
import java.io.Serializable;
public class Goods implements Serializable {
private String id;
private String name;
private double price;
public Goods(String id, String name, double price) {
this.id = id;
this.name = name;
this.price = price;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
@Override
public String toString() {
return "商品信息[编号:" + id + ",名称:" + name + ",价格:" + price + "]";
}
}
package com.serial;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
public class GoodeTest {
public static void main(String[] args) {
Goods goods1 = new Goods("01", "电脑", 3000);
try {
FileOutputStream fos = new FileOutputStream("A.txt");
ObjectOutputStream oos = new ObjectOutputStream(fos);
FileInputStream fis = new FileInputStream("A.txt");
ObjectInputStream ois = new ObjectInputStream(fis);
// 将Goods对象信息写入文件
oos.writeObject(goods1);
oos.writeBoolean(true);
oos.flush();
// 读对象信息
try {
Goods goods2 = (Goods) ois.readObject();
System.out.println(goods2);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
System.out.println(ois.readBoolean()); // 注意读的顺序要和写的顺序一致。
fos.close();
fis.close();
oos.close();
ois.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
文件A.txt仍然是乱码。