Java.io.File类的使用
计算机操作系统中的文件和文件夹
File类代表与平台无关的文件和目录,File 能新建,删除,重命名文件和目录,
但File不能访问文件内容本身,若要访问,需使用输入/输出流
Java IO原理
IO流:用来处理设备之间的数据传输,java.io包下提供了各种“流"类和接口,用以获取不同种类的数据,并通过标准的方法输入或者输出数据
- IO:输入input【读取外部数据到程序中】、输出output【将程序数据输出到磁盘等存储设备中】
- 流:通过程序把一个图放到某一个文件夹,把图片转换为一个数据集(例如二进制),把这些数据一点一点传到文件夹,这个传递的过程就很类似水的流动,称这个整体的数据集是一个数据流
流的分类:
- 按操作数据单位不同分为:字节流(8 bit)、字符流(16 bit)
- 按数据流的流向不同分为:输入流、输出流
- 按流的角色的不同分为:节点流、处理流
File类的相关功能
public class TestFileFunction {
public static void main(String[] args) {
File f1 = new File("D:/aa/text.txt");//f1表示当前text.txt文件
File f2 = new File("D:/aa");//f2表示当前文件目录
// File f3 = new File("D:"+File.separator+"aa\\text.txt");
// File f4 = new File("D:\\aa","bb:\\text1.txt");
//注意:\在 文件中是路径的分隔符,但是在java编程中一个\的意思是转义符,在java中\\才是文件的分隔符
//也可以用File.separator或者 / 作为文件分隔符
System.out.println(f1.getName());//获取文件名
System.out.println(f2.getName());//获取当前的文件名称
File f5 = new File("src/com/zhang/File/TestFileFunction.java");//使用相对路径来创建file对象
System.out.println(f5.getPath());//获取文件或者文件夹的路径,为new file时写的路径
System.out.println(f5.getAbsolutePath());//获取当前文件夹的绝对路径
System.out.println(f1.exists());//判断文件或者文件夹是否存在 true
System.out.println(f1.canRead()); //判断文件是否可读
System.out.println(f1.canWrite());//判断文件是否可写
System.out.println(f1.isFile());//判断当前的file对象是不是文件
System.out.println(f1.isDirectory());//判断当前的file对象是不是文件夹或者目录
System.out.println(f1.lastModified());//获取文件最后修改时间,返回的是一个毫秒数
System.out.println(f1.length());//返回文件的长度,单位为字节数
File f6 = new File("D:/aa/text3.txt");
if(!f6.exists()){
try {
f6.createNewFile();//创建新的文件
} catch (IOException e) {
throw new RuntimeException(e);
}
}
// f6.delete();//删除文件
File f7 = new File("D:/aa/cc");
f7.mkdir();//创建单层目录,如果用这方法创建多层目录,就得一层一层的执行mkdir()
File f8 = new File("D:/aa/dd/ee");
f8.mkdirs();//创建多层目录
File f9 = new File("D:/aa");
String[] s = f9.list();//返回的是当前文件夹的子集名称,包括目录和文件
for (String s1:s){
System.out.println(s1);
//text.txt
}
File[] fs = f9.listFiles();//返回的是当前文件夹的子集的路径,包括目录和文件
for (File ff:fs){
System.out.println(ff);
//D:\aa\text.txt
}
}
}
文件流:
- 数据流的读写都是基于文件的操作
- FileInputStream / FileOutputStream / FileReader / FileWriter
测试文件字节流
public class TestFileByte {
public static void main(String[] args) {
// TestFileInputStream.testFileInputStream();
// TestFileInputStream.testFileOutputStream();
TestFileByte.copyFile("D:/aa/text1.txt","D:/aa/bb/text1.txt");
}
/**
* 文件流输入流FileInputStream
*/
public static void testFileInputStream(){
try {
FileInputStream in = new FileInputStream("D:/aa/text.txt");//
int len ;//设置一个读取数据的长度
byte[] b = new byte[10];//设置一个byte数组接收读取的文件内容
while((len = in.read(b)) !=-1){
//in.read()方法有一个返回值,返回值为读取的数据长度,当in.read的返回值为-1时整个文件就读取完毕
System.out.println(new String(b,0,len));
//new String(b,0,len),参数1是缓冲数据的数组,参数2是从数组的那个位置开始转化为字符串,参数3是转换的总长度
}
in.close();//流在使用完后一定要关闭
} catch (Exception e) {
throw new RuntimeException(e);
}
}
//文件字节输出流FileOutputStream
public static void testFileOutputStream(){
try {
FileOutputStream out = new FileOutputStream("D:/aa/text1.txt");
String s = "hello world";
out.write(s.getBytes());//把数据写到内容
out.flush();//把内存中的数据刷写到硬盘
out.close();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
//复制文件到指定位置
public static void copyFile(String inPath,String outPath){
try {
FileInputStream in = new FileInputStream(inPath);//读取的源文件
FileOutputStream out = new FileOutputStream(outPath);//复制到哪里
byte[] b =new byte[100];
int len;
while((len = in.read(b))!=-1){
out.write(b,0,len);
}
out.flush();//把写到内存的数据刷到硬盘
out.close();
in.close();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
测试文件字符流
public class TestFileChar {
public static void main(String[] args) {
// TestFileChar.TestFileReader("D:/aa/text.txt");
// TestFileChar.TestFileWriter("你好","D:/aa/text1.txt");
TestFileChar.TestCopy("D:/aa/text1.txt","D:/aa/cc/text1.txt");
}
//文件字符输入流
//在读取文件时,必须保证文件已存在
public static void TestFileReader(String inPath){
try {
FileReader fr = new FileReader(inPath);
char[] c = new char[10];//创建临时存储数据的字符数组
int len=0;
while ((len = fr.read(c))!=-1){
System.out.println(new String(c,0,len));
}
fr.close();//关闭流
} catch (Exception e) {
throw new RuntimeException(e);
}
}
//文件字符输出流
public static void TestFileWriter(String text,String outPath){
try {
FileWriter fw = new FileWriter(outPath);
fw.write(text);//写到内存
fw.flush();
fw.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public static void TestCopy(String inPath,String outPath){
try {
FileReader fr = new FileReader(inPath);
FileWriter fw = new FileWriter(outPath);
char[] c = new char[100];
int len;
while((len = fr.read(c))!=-1){
fw.write(c,0,len);
}
fw.flush();
fr.close();
fw.close();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
缓冲流:
- 数据流的读写都是基于内存的操作
- BufferedInputStream / BufferedOutputStream / BufferedReader / BufferedWriter
- 缓冲流可提高数据读写速度
- 对于输出的缓冲流,写出的数据会先在内存中缓存,使用flush()将会使内存中的数据立刻写出
public class TestBufferedStream {
public static void main(String[] args) {
try {
// TestBufferedStream.testBufferedInputStream();
// TestBufferedStream.TestBufferedOutputStream();
TestBufferedStream.TestCopy();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
//缓冲字节输入流
public static void testBufferedInputStream() throws Exception {
//文件字节输入流对象
FileInputStream in = new FileInputStream("D:/aa/text.txt");
//把文件字节输入流放到缓冲字节输入流对象
BufferedInputStream bi = new BufferedInputStream(in);
byte[] b = new byte[10];
int len;
while ((len = bi.read(b))!=-1){
System.out.println(new String(b,0,len));
}
//关闭时,最晚开的最早关,依次关
bi.close();
in.close();
}
//缓冲字节输出流
public static void TestBufferedOutputStream() throws Exception{
BufferedOutputStream bo = new BufferedOutputStream(new FileOutputStream("D:/aa/text2.txt"));
String s = "hello world";
bo.write(s.getBytes());//写到内存中
bo.flush();//刷到硬盘里
bo.close();
}
//缓冲字符流实现文件的复制
public static void TestCopy() throws Exception{
//缓冲输入、输出流
BufferedReader br = new BufferedReader(new FileReader("D:/aa/text.txt"));
BufferedWriter bw = new BufferedWriter(new FileWriter("D:/aa/text4.txt"));
char[] c =new char[100];
int len = 0;
while ((len=br.read(c))!=-1){
bw.write(c,0,len);
}
bw.flush();
bw.close();
br.close();
}
}
标准输入输出流、数据流
- 标准输入输出流:System.in和System.out分别代表了系统标准的输入输出设备
- System.in的类型是InputStream,System.out的类型是PrintStream,其是OutputStream的子类FileOutputStream的子类
- 数据流:DataOutputStream、DataInputStream
- 方便操作Java语言的基本数据类型的数据
public class TestSystem {
public static void main(String[] args) {
try {
// TestSystem.testSystemIn();
// TestSystem.testDataOutputStream();
TestSystem.testDataInputStream();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
//标准的输入、输出流
public static void testSystemIn() throws Exception{
//创建一个接收键盘数据的流
InputStreamReader in = new InputStreamReader(System.in);
OutputStreamWriter out = new OutputStreamWriter(System.out);
//把输入流放到缓冲流里
BufferedReader br = new BufferedReader(in);
BufferedWriter bw = new BufferedWriter(out);
String str ="";//定义一个临时接收数据的字符串
while ((str = br.readLine())!=null){
System.out.println(str);
}
br.close();
in.close();
}
/**
* 数据流
* 数据输出流
* 用数据输出流写到文件中的基本数据类型的数据,是乱码的,不能之间辨认出来,需要数据输入流来读取
* @throws Exception
*/
public static void testDataOutputStream() throws Exception{
DataOutputStream out = new DataOutputStream(new FileOutputStream("src/com/zhang/File/text2.txt"));
// out.writeBoolean(true);
// out.writeInt(1);
out.writeDouble(1.4444d);
out.flush();
out.close();
}
/**
* 数据输入流
* 用数据输出流写到文件中的基本数据类型是乱码的,不能直接辨认出来
* 用数据输入流读取数据输出流写到文件中的数据时,要保证使用和当时写的数据类型一致来读取
* eg:写的时候是writeDouble,读的时候就是readDouble
* @throws Exception
*/
public static void testDataInputStream() throws Exception{
DataInputStream in = new DataInputStream(new FileInputStream ("src/com/zhang/File/text2.txt"));
System.out.println(in.readDouble());
in.close();
}
}
转换流
- 转换流把字节流转换为字符流
- InputStreamReader、OutputStreamWriter
- 当字节流中的数据都是字符时,使用转换流转为字符流出来效果更高
- 所有的文件都是有编码格式的
- TXT,Java文件一般有三种编码 :IS08859—1 西欧编码,是纯粹英文编码,不适应汉字
- GBK,UTF-8,这两种编码适用于中文和英文
public class TestChangeStream {
public static void main(String[] args) {
try {
// TestChangeStream.TestInputStreamReader();
TestChangeStream.TestOutputStreamWriter();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
//转换输入流InputStreamReader
//注意,在转换字符时,设置的字符集编码要与读取的文件的数据编码一致,否则会出现乱码
public static void TestInputStreamReader() throws Exception{
FileInputStream fs = new FileInputStream("src/com/zhang/File/text.txt");
// FileInputStream fs = new FileInputStream("D:/aa/text.txt");
//把字节流转换为字符流
InputStreamReader in = new InputStreamReader(fs,"UTF-8");//参数1是字节流,参数2是编码
// InputStreamReader in = new InputStreamReader(fs,"GBK");//编码不同会造成乱码
char[] c = new char[100];
int len = 0;
while ((len = in.read(c))!=-1){
System.out.println(new String(c,0,len));
}
in.close();
fs.close();
}
//转换字节输出为字符输出流OutputStreamWriter
public static void TestOutputStreamWriter() throws Exception{
FileOutputStream fo = new FileOutputStream("src/com/zhang/File/text1.txt");
OutputStreamWriter ow = new OutputStreamWriter(fo,"UTF-8");
ow.write("谢谢你");
ow.flush();
ow.close();
fo.close();
}
}
对象流
- 需要做保存对象到硬盘(对象的持久化)和对象的网络传输,就产生了对象的输入和输出流
- ObjectInputStream、ObjectOutputStream
- 用于存储和读取数据的处理流,可把java中的对象写到数据源中,也能把对象从数据源中还原回来
- 序列化(Serialize) :用ObjectOutputStream类将一个Java对象写进IO流中
- 反序列化(Deserialize) :用ObjectInputStream类从IO流中恢复该Java对象
- ObjectInputStream、ObjectOutputStream不能序列化static和transient修饰的成员变量
- 系列化和反序列化对针对的是对象的各种属性,不包括类的属性
对象的序列化
凡是实现Serializable接口的类都有一个表示序列化版本标书符的静态变量
若某一个类实现了Serializable接口,该类的对象就是可序列化的
/**
- 序列化与反序列化
- 注意:对象的序列化和反序列化使用的类要严格一致,类名,包名,类机构等待都要一致
*/
public class TestObjectStream {
public static void main(String[] args) {
try {
// TestObjectStream.testSerialize();
TestObjectStream.testDeserialize();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
//对象的序列化
public static void testSerialize() throws Exception{
//定义对象的输出流,把对象的序列化之后的流放到指定的文件中
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("src/com/zhang/File/text3.txt"));
Person p = new Person(4,"小明");
out.writeObject(p);
out.flush();
out.close();
}
public static void testDeserialize() throws Exception{
//创建对象输入流,从指定的文件中把对象序列化后的流读取出来
ObjectInputStream in = new ObjectInputStream(new FileInputStream("src/com/zhang/File/text3.txt"));
Object obj = in.readObject();
Person p = (Person)obj;
System.out.println(p.age+" "+p.name);
in.close();
}
}
//可以序列化和反序列化的对象
class Person implements Serializable{
/**
* 一个表示序列化版本标识符的静态变量
* 用来表明类的不同版本间的兼容性
*/
private static final long serialVersionUID = 1L;
public int age;
public String name;
public Person() {
}
public Person(int age, String name) {
this.age = age;
this.name = name;
}
}
随机存取文件流
- 程序可以直接跳到文件的任意地方来读写文件
- RandomAccessFile类
public class TestRandomStream {
public static void main(String[] args) {
try {
// TestRandomStream.testRandomAccessFileRead();
TestRandomStream.testRandomAccessFileWrite();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
//随机读文件
public static void testRandomAccessFileRead() throws Exception{
/**
* RandomAccessFile的构造有两个参数,参数1是读写的文件路径,参数2是指定RandomAccessFile的访问模式
* r:以只读方式打开
* rw:打开以便读取和写入
* rwd:打开以便读取和写入,同步文件内容的更新
* rws:打开以便读取和写入,同步文件内容和元数据的更新
*/
RandomAccessFile ra = new RandomAccessFile("src/com/zhang/File/text.txt","r");
// ra.seek(0);
ra.seek(8);//设置读取文件的起始点
byte[] b = new byte[1024];
int len = 0;
while ((len = ra.read(b))!=-1){
System.out.println(new String(b,0,len));
}
ra.close();
}
//随机写
public static void testRandomAccessFileWrite() throws Exception{
RandomAccessFile ra = new RandomAccessFile("src/com/zhang/File/text.txt","rw");
//注意:若在文件开头或中间的某位置写,就会用写的内容覆盖掉等长的原内容
ra.seek(ra.length());//设置写的起点,ra.length()代表从文件的最后结尾写,也就是文件的追加
ra.write("你好啊".getBytes());
ra.close();
}
}