JAVA IO
参考
位、字节、字符
File
File对象
构造方法
方法名 | 说明 |
---|---|
File(File parent, String child) |
根据 parent 抽象路径名和 child 路径名字符串创建一个新 File 实例。 |
File(String pathname) |
通过将给定路径名字符串转换为抽象路径名来创建一个新 File 实例。 |
File(String parent, String child) |
根据 parent 路径名字符串和 child 路径名字符串创建一个新 File 实例。 |
File(URI uri) |
通过将给定的 file: URI 转换为一个抽象路径名来创建一个新的 File 实例 |
常用方法
方法名 |
说明 |
public boolean createNewFile() |
当具有该名称的文件不存在时,创建一个由该抽象路径名命名的新空文件 |
public boolean mkdir() |
创建由此抽象路径名命名的目录 |
public boolean mkdirs() |
创建由此抽象路径名命名的目录,包括任何必需但不存在的父目录 |
public boolean delete() |
删除由此抽象路径名表示的文件或目录 |
public boolean isDirectory() |
测试此抽象路径名表示的File是否为目录 |
public boolean isFile() |
测试此抽象路径名表示的File是否为文件 |
public boolean exists() |
测试此抽象路径名表示的File是否存在 |
public String getAbsolutePath() |
返回此抽象路径名的绝对路径名字符串 |
public String getPath() |
将此抽象路径名转换为路径名字符串 |
public String getName() |
返回由此抽象路径名表示的文件或目录的名称 |
public String[] list() |
返回此抽象路径名表示的目录中的文件和目录的名称字符串数组 |
public File[] listFiles() |
返回此抽象路径名表示的目录中的文件和目录的File对象数组 |
创建文件
//在路径下创建test.txt
//构造函数一
//File file = new File("G:\\test.txt");
//构造函数二
//File file = new File("G:\\","test.txt");
//构造函数三
File file0 = new File("G:\\");
File file = new File(file0,"test.txt");
try {
boolean success = file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
创建目录
//在路径下创建java目录
File file = new File("G:\\java");
boolean success = file.mkdir();
//创建多级目录
//File file = new File("G:\\java\\javaweb\\web");
//file.mkdirs();
检查目录或文件是否存在
获取目录下全部文件路径
public static void main(String[] args) {
File file = new File("G:\\java");
getAllFilePath(file);
}
public static void getAllFilePath(File srcFile){
File[] fileArray = srcFile.listFiles();
if(fileArray !=null){
for(File file : fileArray){
if(file.isDirectory()){
getAllFilePath(file);
}else{
System.out.println(file.getAbsoluteFile());
}
}
}
}
Stream
总结
InputStream与OutputStream是两个抽象类,是字节流的基类,所有具体的字节流实现类都是分别继承了这两个类。
字节流
FileInputStream和FileOutputStream将文件转输入流和输出流
为了提高效率,BufferedInputStream和BufferedOutputStream对此两个对象进行包装进行缓冲处理
// 字节输出流
FileOutputStream out = new FileOutputStream("filename/file", true);
//字节缓冲输出流
BufferedOutputStream bos = new BufferedOutputStream(out);
//字节输入流
FileInputStream fi = new FileInputStream("filename/file");
//字节缓冲输入流
BufferedInputStream in = new BufferedInputStream(fi);
字符流
//字符输出流OutputStreamWriter借助字节输出流FileOutputStream实现
FileOutputStream os = new FileOutputStream("filename/file", true);
OutputStreamWriter writer = new OutputStreamWriter(os,"UTF-8");
//字符输入流
FileInputStream fi = new FileInputStream("filename/file");
InputStreamReader in = new InputStreamReader(fi, "UTF-8");
字符流便捷类
FileWriter和FileReader简化字符流的读写
new FileWriter("filename/file",true)等同于new OutputStreamWriter(new FileOutputStream("filename/file", true))
new FileWriter("filename/file")等同于new InputStreamReader(new FileInputStream("filename/file"))
转换流
InputStreamReader和OutputStreamWriter 对字节流进行字符流转换,两个对象的构造函数需要借助
FileInputStream和FileOutputStream
字符缓冲流
//BufferedReader对InputStreamReader进行包装缓冲,BufferedWriter对OutputStreamReader进行包装缓冲
InputStream is =new FileInputStream("filename/file");
BufferedReader in = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8));
//http请求处理响应的一个例子
URL realUrl = new URL(url);
URLConnection conn = realUrl.openConnection();
BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8));
InputStream用InputStreamReader读取转换为字符,BufferedReader包装缓冲字符
流分类

字节流和字符流区别
IO流导图
「节点流」:直接操作数据读写的流类,比如FileInputStream
「处理流」:对一个已存在的流的链接和封装,通过对数据进行处理为程序提供功能强大、灵活的读写功能,例如BufferedInputStream
(缓冲字节流)
处理流和节点流应用了Java的装饰者设计模式。
下图就很形象地描绘了节点流和处理流,处理流是对节点流的封装,最终的数据处理还是由节点流完成的。


释放资源

字节流

InputStream

public abstract class InputStream
extends Object
implements Closeable
FileInputStream
FileInputStream(File file) |
通过打开与实际文件的连接来创建
FileInputStream ,该文件由文件系统中的 File 对象 file 命名。 |
---|---|
FileInputStream(String name) |
通过打开与实际文件的连接来创建
FileInputStream ,该文件由文件系统中的路径名 name 命名。 |
测试
try (FileInputStream fi = new FileInputStream(new File("test.txt"))) {
int by;
while ((by = fi.read()) != -1) {
char c = (char) by;
System.out.print(c);
}
} catch (Exception e) {
}
FileInputStream fi = new FileInputStream("G:\\java\\javase\\se1.txt");
int by;
while ((by = fi.read()) != -1) {
System.out.println((char)by);
}
public static void read() throws IOException {
File file = new File("D:\\io.txt");
InputStream in = new FileInputStream(file);
// 一次性取多少个字节
byte[] bytes = new byte[1024];
// 用来接收读取的字节数组
StringBuilder sb = new StringBuilder();
// 读取到的字节数组长度,为-1时表示没有数据
int length = 0;
// 循环取数据
while ((length = in.read(bytes)) != -1) {
// 将读取的内容转换成字符串
sb.append(new String(bytes, 0, length));
}
// 关闭流
in.close();
System.out.println(sb.toString());
}
字节流复制文件
FileInputStream fi = new FileInputStream("G:\\java\\javase\\1234.png");
FileOutputStream fo = new FileOutputStream("G:\\java\\javaweb\\456.png");
byte[] bytes = new byte[1024];//1024及其整数倍
int len;
while ((len = fi.read(bytes)) != -1) {
fo.write(bytes, 0, len);
}
fi.close();
fo.close();
//文件复制
private static void copyFile(File srcfile, File destFile) {
try(
FileInputStream fis = new FileInputStream(srcfile);
FileOutputStream fos = new FileOutputStream(destFile);
) {
byte [] bytes = new byte[1024];
int len = fis.read(bytes);
while ( (len = fis.read(bytes)) != -1){
fos.write(bytes, 0, len);
}
} catch (Exception e) {
// TODO: handle exception
}
}
//文件复制
private static void copyFile(String srcFileName, String destFileName) {
try{
BufferedInputStream fis = new BufferedInputStream(new FileInputStream(srcFileName));
FileOutputStream fos = new FileOutputStream(destFileName);
byte [] bytes = new byte[1024];
int len = 0;
while ( (len = fis.read(bytes)) != -1){
fos.write(bytes, 0, len);
}
fis.close();
fos.close();
} catch (Exception e) {
// TODO: handle exception
}
}
OutputStream

public abstract class OutputStream
extends Object
implements Closeable, Flushable
FileOutputStream


write(int b)
// 相对路径
try (FileOutputStream fo = new FileOutputStream("test.txt", true)) {
// FileOutputStream fo = new FileOutputStream("test.txt") 覆盖此文件
// 追加文本
fo.write(97);
fo.close();
} catch (Exception e) {
e.printStackTrace();
}
write(byte[] b)
/**
* 字节流写入
*/
public static void bytewrite() throws IOException {
FileOutputStream os = new FileOutputStream("D:\\io.txt",true);
// 要写入的字符串
String string = "松下问童子,言师采药去。只在此山中,云深不知处。";
// 写入文件
os.write(string.getBytes());
// 关闭流
os.close();
}
//下载文件的一个例子
//输出到文件
File file = new File("文件名称");
FileOutputStream fos = new FileOutputStream(file);
InputStream is = conn.getInputStream();//http中获取流
BufferedInputStream bis = new BufferedInputStream(is);
byte[] buffer = new byte[1024];
int len;
while ((len = bis.read(buffer)) != -1) {
fos.write(buffer, 0, len);
}
fos.close();
bis.close();
is.close();
write(byte[] b, int off, int len)
try {
FileOutputStream fo = new FileOutputStream("G:\\java\\javase\\se1.txt");
try {
byte[] bytes = {97,98,99,100};
//输出bcd
fo.write(bytes,1,bytes.length-1);
fo.close();
} catch (IOException e) {
e.printStackTrace();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
字节流换行
String name = "ABCD\r\nEFG";
//输出bcd
fo.write(name.getBytes());
字符流

Writer字符输出流

OutputStreamWriter
OutputStreamWriter(OutputStream out) |
创建使用默认字符编码的OutputStreamWriter。
|
---|---|
OutputStreamWriter(OutputStream out, String charsetName) |
创建使用指定charset的OutputStreamWriter。
|
FileOutputStream fo = new FileOutputStream("文件名称");
OutputStreamWriter os = new OutputStreamWriter(fo,"UTF-8");
字符流写数据的方法
void write(int c) |
写一个字符 |
void write(char[] cbuf) |
写入一个字符数组 |
void write(char[] cbuf, int off, int len) |
写入字符数组的一部分 |
void write(String str) |
写一个字符串 |
void write(String str, int off, int len) |
写一个字符串的一部分 |
flush() |
刷新流,还可以继续写数据 |
close() |
关闭流,释放资源,但是在关闭之前会先刷新流。一旦关闭,就不能再写数据 |
写文件
public static void write() throws IOException {
File file = new File("D:\\io.txt");
if(!file.exists()) {
file.createNewFile();
}
OutputStreamWriter os = new OutputStreamWriter(new FileOutputStream(file, true), "UTF-8");
// 要写入的字符串
String string = "松下问童子,言师采药去。只在此山中,云深不知处。";
// 写入文件
os.write(string);
// 关闭流
os.close();
}
Reader字符输入流

InputStreamReader
InputStreamReader(InputStream in) |
创建一个使用默认字符集的InputStreamReader。
|
---|
字符流读取数据
int read() |
一次读一个字符数据 |
int read(char[] cbuf) |
一次读一个字符数组数据 |
读取文件
public static void read() throws IOException {
File file = new File("D:\\io.txt");
InputStreamReader in = new InputStreamReader(new FileInputStream(file), "UTF-8");
// 一次性取多少个字符
char[] bytes = new char[1024];
// 用来接收读取的字符数组
StringBuilder sb = new StringBuilder();
// 读取到的字符数组长度,为-1时表示没有数据
int length = 0;
// 循环取数据
while ((length = in.read(bytes)) != -1) {
// 将读取的内容转换成字符串
sb.append(new String(bytes, 0, length));
}
// 关闭流
in.close();
System.out.println(sb.toString());
}
FileWriter&FileReader
public static void write() throws IOException {
File file = new File("D:\\io.txt");
if(!file.exists()) {
file.createNewFile();
}
//OutputStreamWriter os = new OutputStreamWriter(new FileOutputStream(file, true), "UTF-8");
FileWriter os = new FileWriter(file,true);
// 要写入的字符串
String string = "松下问童子,言师采药去。只在此山中,云深不知处。";
// 写入文件
os.write(string);
// 关闭流
os.close();
}
public static void read() throws IOException {
File file = new File("D:\\io.txt");
//InputStreamReader in = new InputStreamReader(new FileInputStream(file), "UTF-8");
FileReader in = new FileReader(file);
// 一次性取多少个字节
char[] bytes = new char[1024];
// 用来接收读取的字符数组
StringBuilder sb = new StringBuilder();
// 读取到的字节数组长度,为-1时表示没有数据
int length = 0;
// 循环取数据
while ((length = in.read(bytes)) != -1) {
// 将读取的内容转换成字符串
sb.append(new String(bytes, 0, length));
}
// 关闭流
in.close();
System.out.println(sb.toString());
}
缓冲流
字节缓冲流
public static void read() throws IOException {
File file = new File("D:\\io.txt");
BufferedInputStream in = new BufferedInputStream(new FileInputStream(file));
// 一次性取多少个字节
byte[] bytes = new byte[1024];
// 用来接收读取的字节数组
StringBuilder sb = new StringBuilder();
// 读取到的字节数组长度,为-1时表示没有数据
int length = 0;
// 循环取数据
while ((length = in.read(bytes)) != -1) {
// 将读取的内容转换成字符串
sb.append(new String(bytes, 0, length));
}
// 关闭流
in.close();
System.out.println(sb.toString());
}
private static void writeData() throws IOException {
// 字节输出流
FileOutputStream out = new FileOutputStream("D:\\io.txt", true);
// 使用字节缓冲流对out字节流进行包装(缓冲)
BufferedOutputStream bos = new BufferedOutputStream(out);
//写入的数据
String msg = "使用字节缓冲流保存数据到文件";
//转换字节数组
byte[] bytes = msg.getBytes();
bos.write(bytes);
bos.flush();
bos.close();
}
字符缓冲流
/**
* 字符缓冲流
* @throws IOException
*/
public static void charwrite() throws IOException {
File file = new File("D:\\io.txt");
if(!file.exists()) {
file.createNewFile();
}
//BufferedWriter os = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file, true), "UTF-8"));
//等同上面
BufferedWriter os = new BufferedWriter(new FileWriter(file,true));
// 要写入的字符串
String string = "松下问童子,言师采药去。只在此山中,云深不知处。";
// 写入文件
os.write(string);
// 关闭流
os.close();
}
/**
* 字符缓冲流
* @throws IOException
*/
public static void charread() throws IOException {
File file = new File("D:\\io.txt");
//BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF-8"));
BufferedReader in = new BufferedReader(new FileReader(file));
// 一次性取多少个字符
char[] bytes = new char[1024];
// 用来接收读取的字符数组
StringBuilder sb = new StringBuilder();
// 读取到的字符数组长度,为-1时表示没有数据
int length = 0;
// 循环取数据
while ((length = in.read(bytes)) != -1) {
// 将读取的内容转换成字符串
sb.append(new String(bytes, 0, length));
}
// 关闭流
in.close();
System.out.println(sb.toString());
}
/**
* 字符缓冲输入流按行读取
* @throws IOException
*/
public static void BufferedReader() throws IOException {
File file = new File("D:\\io.txt");
InputStream is =new FileInputStream(file);
BufferedReader in = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8));
StringBuilder sb = new StringBuilder();
String temp = null;
while ((temp = in.readLine()) != null) {
// 将读取的内容转换成字符串
sb.append(temp);
sb.append("\r\n");
}
// 关闭流
in.close();
System.out.println(sb.toString());
}
http的一个例子
URL realUrl = new URL(url);
URLConnection conn = realUrl.openConnection();
BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8));
转换流
public static void write() throws IOException {
File file = new File("D:\\io.txt");
if(!file.exists()) {
file.createNewFile();
}
//字节输出流
FileOutputStream os = new FileOutputStream(file, true);
//转为字符输出流
OutputStreamWriter writer = new OutputStreamWriter(os,"UTF-8");
// 要写入的字符串
String string = "松下问童子,言师采药去。只在此山中,云深不知处。";
// 字符流输出
writer.write(string);
// 关闭流
writer.close();
}
public static void read() throws IOException {
File file = new File("D:\\io.txt");
//字节流
FileInputStream fi = new FileInputStream(file);
//转字符流
InputStreamReader in = new InputStreamReader(fi, "UTF-8");
// 一次性取多少个字符
char[] chars = new char[1024];
// 用来接收读取的字符数组
StringBuilder sb = new StringBuilder();
// 读取到的字节数组长度,为-1时表示没有数据
int length = 0;
// 循环取数据
while ((length = in.read(chars)) != -1) {
// 将读取的内容转换成字符串
sb.append(new String(chars, 0, length));
}
// 关闭流
in.close();
System.out.println(sb.toString());
}
打印流
PrintStream字节流
PrintWriter字符流
对象流
ObjectInputStream
InputStream in = new FileInputStream("d:/obj.txt");
ObjectInputStream ois = new ObjectInputStream(in);
Object obj = ois.readObject(); //从文件中读取一个对象, readObject()方法的返回值是Object类型的
//文件中实际存储的是Person对象, 使用obj引用指向Person对象
System.out.println( obj ); //实际上调用的是Person对象的toString()方法
ois.close();
/*
* 在对象序列化之后 ,即把对象已经保存到文件中了, 又在Person类中添加了一个字段,修改了Person类结构,
* 再进行反序列化时, 出现了异常:
* java.io.InvalidClassException:
* com.wkcto.chapter06.objectstream.Person; local class incompatible:
* stream classdesc serialVersionUID = 3479771803741762411,
* local class serialVersionUID = 1549311491347595402
* 分析原因:
* 流中类的描述信息中 serialVersionUID的值与本地字节码文件中 serialVersionUID字段的值不相等引发的异常
*
* 当类Person实现了Serializable接口后, 系统会自动的在Person类中增加一个serialVersionUID序列化版本号字段
* 在lisi对象序列化时, serialVersionUID字段的值是: 3479771803741762411
* 当序列化后, 又在Person类添加了gender字段, 编译后,在字节码文件中重新生成了一个serialVersionUID的值:1549311491347595402
* 在进行反序列化时, 系统会检查流中serialVersionUID序列化版本号字段与本地字节码文件中serialVersionUID字段的值是否一样
* 如果相等就认为是同一个类的对象, 如果这个serialVersionUID序列化版本号字段的值不相等,就认为是不同类的对象
* 解决方法:
* 保证反序列化时流中serialVersionUID字段 的值,与本地字节码文件中serialVersionUID字段的值相等即可
* 可以在Person类实现了Serializable接口后, 手动的添加一个serialVersionUID字段
*/
ObjectOutputStream
//声明对象并实现接口
public class Person implements Serializable{}
//创建Person对象
Person lisi = new Person("lisi", 18);
//把lisi对象序列化, 就是把lisi对象保存到文件中
OutputStream out = new FileOutputStream("d:/obj.txt");
ObjectOutputStream oos = new ObjectOutputStream(out);
oos.writeObject(lisi); //对象序列化
oos.close();