目录
FileInputStream FileOutputStream
BufferedInputStream BufferedOutputStream
DataInputStream DataOutputStream
File类
File类是java.io包中很重要的一个类
File类的对象可以表示文件,还可以表示目录,在程序中一个File类对象可以代 表一个文件或目录
文本文档
创建文本文档
代码
package com.ffyc.javaIO.file;
import java.io.*;
public class FileDemo1 {
public static void main(String[] args) throws IOException {
//表示D盘中的文本文档
File f = new File("D:/a.txt");
if(!f.exists()){
//创建文件
boolean res = f.createNewFile();
System.out.println(res);
}
}
}
运行
删除文本文档
代码
package com.ffyc.javaIO.file;
import java.io.*;
public class FileDemo1 {
public static void main(String[] args) throws IOException {
//表示D盘中的文本文档
File f = new File("D:/a.txt");
if(!f.exists()){
//创建文件
boolean res = f.createNewFile();
System.out.println(res);
}
//删除文件
System.out.println(f.delete());
}
}
运行
文件夹
创建文件夹
单级目录
代码
package com.ffyc.javaIO.file;
import java.io.*;
public class FileDemo1 {
public static void main(String[] args) throws IOException {
File f = new File("D:/a");
//只能创建单级目录
f.mkdir();
}
}
运行
多级目录
代码
package com.ffyc.javaIO.file;
import java.io.*;
public class FileDemo1 {
public static void main(String[] args) throws IOException {
File f = new File("D:/a/b/c");
//可以创建多级目录
f.mkdirs();
}
}
运行
删除文件夹
可以删除文件夹,要求文件夹没有其他内容
代码
package com.ffyc.javaIO.file;
import java.io.*;
public class FileDemo1 {
public static void main(String[] args) throws IOException {
File f = new File("D:/a/c/b");
f.delete();
}
}
方法
一个File类的对象,可以表示计算机硬盘上一个具体的文件或目录(文件夹)
通过File类的对象,来获取文件或目录的相关信息(例如创建时间,是否可写....),但是不能读取文件中的内容的
代码
package com.ffyc.javaIO.file;
import java.io.File;
import java.io.IOException;
import java.util.Date;
public class FileDemo2 {
public static void main(String[] args) throws IOException {
File f1 = new File("D:/a.txt");//表示D盘中的文本文档
File f2 = new File("D:/a");//表示D盘中的a文件夹
//返回文件是否可以写入
System.out.println(f1.canWrite());
//文件/目录是否存在
System.out.println(f1.exists());
//获取文件绝对地址
System.out.println(f1.getAbsoluteFile());
//返回文件或目录是否隐藏模式
System.out.println(f1.isHidden());
//判断是否是目录
System.out.println(f1.isDirectory());
//判断是否是文件
System.out.println(f1.isFile());
//返回文件最后一次修改的时间
System.out.println(f1.lastModified());
//把long类型时间转为Data对象
System.out.println(new Date(1709810667163l));
//获取文件名字
System.out.println(f1.getName());
//获取到的是文件的字节数 一个英文字母占一个字节,在utf-8编码表中一个汉字需要3个字节
System.out.println(f1.length());
}
}
运行
代码
获取到指定目录下一级所有文件/目录的名字(String[])
package com.ffyc.javaIO.file;
import java.io.File;
public class FileDemo3 {
public static void main(String[] args) throws IOException {
File f = new File("D:/a");
String[] strings = f.list();
for(String s:strings){
System.out.println(s);
}
}
}
运行
代码
获取到指定目录下一级所有文件/目录的名字,返回的是文件对象
package com.ffyc.javaIO.file;
import java.io.File;
import java.io.IOException;
public class FileDemo3 {
public static void main(String[] args) throws IOException {
File[] files = f.listFiles();
for(File file : files){
if(!file.isFile()){
System.out.println(file);
}
}
}
}
运行
输入及输出的概念
输入和输出是对于程序而言的
Java中还提供了许多的类,一些负责从硬盘上读文件(输入),一些负责将程序中的数据写(输出)到目标位置。这些类形象的称为流(管道)。
输入流与输出流
流按着数据的传输方向分为:
输入流:往程序中读叫输入流。
输出流:从程序中往外写叫输出流。
字节流与字符流
字节:
计算机最小存储单位是字节,电脑上所有的文件最终都是以字节的形式存储到硬盘的,例如图片,视频,音频......
字符:
文字,底层还是字节,例如:中--->20013--->3个字节
字符流 以字符为单位进行写操作 底层会将原始的字节转为字符
字符流只能读取纯文本文件(只能写字符,不能有其他内容)
字节流:
一次读写操作以字节为单位
输入流 InputStream
字节输入流 FileInputStream
输出流 OutputStream
字节输出流 FileOutputStream
字符流:
一次读写操作以字符为单位(一个汉字占3个字节 一次可以直接读到一个字符)
输入流 Reader
字符输入流 FileReader
输出流 Writer
字符输出流 FileWriter
输入输出节点字节流
节点流
FileInputStream FileOutputStream
读取
代码
package com.ffyc.javaIO.stream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class StreamDemo1 {
public static void main(String[] args) throws IOException {
//创建一个输入流对象
FileInputStream in = new FileInputStream("D:/a.txt");
//输出流会自动创建文件
FileOutputStream out = new FileOutputStream("D:/b.txt");
//每read一次 返回一个字节编码
System.out.println(in.read());//97
System.out.println(in.read());//98
System.out.println(in.read());//99
System.out.println(in.read());//100
//当文件内容读完以后 返回-1
System.out.println(in.read());//-1
}
}
运行
循环读取(小量字节)
代码
package com.ffyc.javaIO.stream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class StreamDemo2 {
public static void main(String[] args) throws IOException {
//创建一个输入流对象
FileInputStream in = new FileInputStream("D:/a.txt");
//输出流会自动创建文件
FileOutputStream out = new FileOutputStream("D:/b.txt");
int t = 0;
while ((t = in.read()) != -1){
System.out.println(t);
out.write(t);
}
//关闭流对文件的占用
in.close();
out.close();
}
}
运行
循环读取(大量字节)
int read() 默认一次读一个字节,返回的是读到的字节的编码 效率低
int read(byte b[]) 默认一次读一个指定大小的byte数组个字节,返回的是数组中一次实际装入的字节个数
两个方法相同之处都是读完后返回-1;
代码
package com.ffyc.javaIO.stream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class StreamDemo3 {
public static void main(String[] args) throws IOException {
//创建一个输入流对象
FileInputStream in = new FileInputStream("D:/yuzi.png");
//输出流会自动创建文件
FileOutputStream out = new FileOutputStream("D:/myYuzi.png");
byte[] bytes = new byte[100];
int size = 0;
while ((size = in.read(bytes)) != -1){
out.write(bytes, 0, size);
}
//关闭流对文件的占用
in.close();
out.close();
}
}
运行
处理流
BufferedInputStream BufferedOutputStream
代码
package com.ffyc.javaIO.stream;
import java.io.*;
public class StreamDemo4 {
public static void main(String[] args) throws IOException {
//创建一个输入流对象
//节点流,直接包含文件(数据)
FileInputStream in = new FileInputStream("D:/yuzi.png");
//处理流--->带缓冲功能的流
BufferedInputStream bin = new BufferedInputStream(in);
FileOutputStream out = new FileOutputStream("D:/myYuzi.png");
BufferedOutputStream bout = new BufferedOutputStream(out,2048);
byte[] bytes = new byte[1024];
int size = 0;
while ((size = bin.read(bytes)) != -1){
bout.write(bytes, 0, size);
}
bin.close();
//刷新缓冲区
bout.flush();
bout.close();
}
}
缓冲区源码
DataInputStream DataOutputStream
代码
package com.ffyc.javaIO.stream;
import java.io.*;
public class StreamDemo5 {
public static void main(String[] args) throws IOException {
//数据输入输出流
String s = "你好";
FileOutputStream out = new FileOutputStream("D:/msg.txt");
//实际向外发送时,需要转为byte数组
out.write(s.getBytes());
FileInputStream in = new FileInputStream("D:/msg.txt");
byte[] bytes = new byte[100];
//对方接收到之后,拿到的也是byte数组
int size = in.read(bytes);
String str = new String(bytes, 0, size);
System.out.println(str);
}
}
运行
代码
package com.ffyc.javaIO.stream;
import java.io.*;
public class StreamDemo5 {
public static void main(String[] args) throws IOException {
//数据输入输出流
String s = "你好";
FileOutputStream out = new FileOutputStream("D:/msg.txt");
DataOutputStream dout = new DataOutputStream(out);
//将字符串直接写出,底层转为字节数组
dout.writeUTF(s);
FileInputStream in = new FileInputStream("D:/msg.txt");
DataInputStream din = new DataInputStream(in);
//直接可以读到一个字符串,在底层将读到字节数组转为字符串
String str = din.readUTF();
System.out.println(str);
}
}
节点流与处理流
节点流:
原始的流,直接用来操作文件(数据)
例如FileInputStream
处理流:
在节点流的基础上,对读到的数据进行额外的二次处理
例如BufferedInputStream
BufferedOutputStream
输入输出节点字符流
节点流
FileReader FileWriter
读取
代码
package com.ffyc.javaIO.chardemo;
import java.io.FileReader;
import java.io.IOException;
public class CharDemo1 {
public static void main(String[] args) throws IOException {
FileReader reader = new FileReader("D:/a.txt");
System.out.println((char)reader.read());
System.out.println((char)reader.read());
System.out.println((char)reader.read());
System.out.println((char)reader.read());
System.out.println(reader.read());
}
}
运行
循环读取(小量字节)
代码
package com.ffyc.javaIO.chardemo;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class CharDemo2 {
public static void main(String[] args) throws IOException {
FileReader reader = new FileReader("D:/a.txt");
FileWriter writer = new FileWriter("D:/c.txt");
int t = 0;
while ((t = reader.read()) != -1){
writer.write(t);
}
reader.close();
writer.close();
}
}
运行
循环读取(大量字节)
代码
package com.ffyc.javaIO.chardemo;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class CharDemo3 {
public static void main(String[] args) throws IOException {
FileReader reader = new FileReader("D:/a.txt");
FileWriter writer = new FileWriter("D:/c.txt");
char[] chars = new char[10];
int size = 0;
while ((size = reader.read(chars)) != -1){
writer.write(chars,0,size);
}
reader.close();
writer.close();
}
}
处理流
BufferedReader BufferedWriter
代码
package com.ffyc.javaIO.chardemo;
import java.io.*;
public class CharDemo4 {
public static void main(String[] args) throws IOException {
FileReader reader = new FileReader("D:/a.txt");
BufferedReader bufferedReader = new BufferedReader(reader);
//输出时,保留文件中已经存在内容,将新内容追加到原有内容的后面
FileWriter writer = new FileWriter("D:/b.txt",true);
BufferedWriter bufferedWriter = new BufferedWriter(writer);
//一次可以读入一行数据,读完返回一个null
String line = null;
while ((line = bufferedReader.readLine()) != null){
//一次向外输出一个字符串
bufferedWriter.write(line);
//插入一个换行符
bufferedWriter.newLine();
}
bufferedReader.close();
bufferedWriter.flush();
bufferedWriter.close();
}
}
运行
Print流
PrintWriter
单向的输出,
后面在javaEE(服务器端开发)中,可以使用PrintWriter从后端程序向前端程序响应数据
代码
package com.ffyc.javaIO;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
public class PrintWriterDemo {
public static void main(String[] args) throws FileNotFoundException {
PrintWriter printWriter = new PrintWriter("D:/index.html");
printWriter.write("<h1>一级标题标签</h1>");
printWriter.write("<h1>一级标题标签</h1>");
printWriter.write("<h1>一级标题标签</h1>");
printWriter.close();
}
}
运行
对象输入输出流
对象输入输出流
有时候,需要将运行中的对象信息持久保存起来,因为对象在内存中,程序如果终止,对象信息就不存在了。
将对象信息输出到文件的过程,称为对象序列化,使用ObjectOutputStream完成(处理流)
将对象信息从文件中输入到java程序的过程,称为对象反序列化,使用的是ObjectInputStream
对象的反序列化,会在内存中重新创建新的对象保存数据,所以,也是java中创建对象的一种方式。
代码
package com.ffyc.javaIO;
import java.io.*;
import java.util.Date;
public class ObjectStream1 {
public static void main(String[] args) throws IOException, ClassNotFoundException {
String s = new String("abc");
Date date = new Date();
FileOutputStream out = new FileOutputStream("D:/obj.txt");
ObjectOutputStream outputStream = new ObjectOutputStream(out);
outputStream.writeObject(s);
outputStream.writeObject(date);
outputStream.flush();
outputStream.close();
}
运行
代码
package com.ffyc.javaIO;
import java.io.*;
import java.util.Date;
public class ObjectStream1 {
public static void main(String[] args) throws IOException, ClassNotFoundException {
FileInputStream in = new FileInputStream("D:/obj.txt");
ObjectInputStream objectInputStream = new ObjectInputStream(in);
Object s = (String)objectInputStream.readObject();
Date date = (Date) objectInputStream.readObject();
System.out.println(s);
System.out.println(date);
objectInputStream.close();
}
}
运行
对象序列化
一旦一个类实现Serializable接口,会自动的为每个生成一个序列化编号(唯一的)//1234
虽然实现Serializable接口,可以生成一个序列化id号,但是一旦类信息发生修改,序列化编号就会变 4321
如果重新输入对象,两次的序列化的版本号就不一致了,
解决办法:
显示的在类中生成一个序列化版本号
代码
package com.ffyc.javaIO;
import java.io.Serializable;
public class User implements Serializable {
//类的序列化id
private static final long serialVersionUID = 8402381433702375963L;
private String account;
//添加transient关键字的属性,在序列化时,不会类保存到文件中
private transient String password;
public User(String account, String password) {
this.account = account;
this.password = password;
}
@Override
public String toString() {
return "User{" +
"account='" + account + '\'' +
", password='" + password + '\'' +
'}';
}
}
当我们把一个类的对象用输出流向外输出时,要求这个类必须要实现序列化接口
否则会报错,java.io.NotSerializableException: com.ffyc.javaIO.User
package com.ffyc.javaIO;
import java.io.*;
public class ObjectStream2 {
public static void main(String[] args) throws IOException, ClassNotFoundException {
User user = new User("123456", "654321");
FileOutputStream out = new FileOutputStream("D:/obj.txt");
ObjectOutputStream outputStream = new ObjectOutputStream(out);
outputStream.writeObject(user);
outputStream.flush();
outputStream.close();
FileInputStream in = new FileInputStream("D:/obj.txt");
ObjectInputStream objectInputStream = new ObjectInputStream(in);
User s = (User) objectInputStream.readObject();
System.out.println(s);
objectInputStream.close();
}
}