JAVA I/O基本操作

本文主要借鉴以下博客和网站:
how2j.cn
深入理解java中的I/O


JAVA文件操作

JAVA描述和管理文件的类是java.io.File类,通过File生成的对象file,可以通过以下指令对文件进行操作:

  1. file.exists() – 判断文件是否存在
  2. file.isDirectory() – 判断文件是否为文件夹
  3. file.isFile() – 判断是否是普通文件(不是文件夹)
  4. file.length() – 获取文件的长度
  5. file.lastModified() – 获取文件最后修改的时间
  6. file.getAbsolutePath() – 获取文件的绝对路径
  7. file.list() – 返回当前文件夹的所有子文件的文件名(深度为1),返回类型为字符串数组
  8. file.listFiles() – 返回当前文件夹的所有子文件(深度为1),返回类型为文件数组
  9. file.getParent() – 返回当前文件的父文件夹的名字
  10. file.getParentFile() – 返回当前文件的父文件夹
  11. file.mkdir() – 创建文件夹(如果父类文件夹不存在,则创建无效)
  12. file.mkdirs() – 创建文件夹(如果父类文件夹不存在,则连同父文件夹一同创建)
  13. file.getParentFile().mkdirs()常用,创建一个文件前,常把父类目录都创好
  14. file.delete() – 删除文件


以下将展示几种流的使用方法(只展示读,写文件类似)

JAVA字节流

操作数据类型是字节,也就是JAVA数据类型中的byte,所有字节流的父类是InputStreamOutputStream(两个都是的抽象类)在这里插入代码片
在这里插入图片描述
直接上代码:

import java.io.*;
public class Main {
	public static void main(String[] args) {
		//文件中内容是 aAbB
		File file = new File("src/blog/test.txt");
		//对于文件操作,采用字节输入流子类FileInputStream
		//建议采用在try括号内使用流的声明,即使在异常时也能关闭流,减少资源损耗
		try(InputStream fi = new FileInputStream(file)){
			byte[] bytes = new byte[(int) file.length()];
			//将文件中的数据以字节流形式读入到bytes中
			fi.read(bytes);
			for(byte b : bytes) {
				System.out.println(b);//打印ASCII码的十进制形式
			}
		}catch (FileNotFoundException fe) {
			fe.printStackTrace();
		} catch (IOException e) {		
			e.printStackTrace();
		}
	}
}

结果为(“aAbB”的ASCII码的十进制):

97
65
98
66



JAVA字符流

与字节流不同,字符流操作的数据对象的最小单元是字符,比较符合我们的日常读文本的习惯,所以在读文本时用的很多,具体的字符输入流和字符输出流为ReaderWriter,专门用于字符的形式读取和写入数据。
具体代码如下:

import java.io.*;
public class Main {
	public static void main(String[] args) {
		//文件中内容是 aAbB
		//				cCdD
		File file = new File("src/blog/test.txt");
		//对于文件操作,采用字符输入流FileReader
		//建议采用在try括号内使用流的声明,即使在异常时也能关闭流,减少资源损耗
		try(Reader fr = new FileReader(file)){
			char[] chs = new char[(int) file.length()];
			fr.read(chs);
			for(char c : chs) {
				System.out.print(c);
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

}

运行结果如下(输出文本内容aAbBcCdD):

aAbB
cCdD

有时我们要对文本进行逐行处理,但以上的方法都是“一口将文件吃掉“,一次性读完所有的内容,这时我们需要一个新的流来帮我们一步步做,这时缓存流就登上了舞台。


JAVA缓存流

JAVA缓存流读取数据用的是BufferedReader,写入数据用的是BufferedWriter。这里用到了设计模式中的装饰者模式,在此不过多赘述,我们直接看缓存流是如何”装饰“字符流来实现逐行读取的。
代码如下:

import java.io.*;
public class Main {
	public static void main(String[] args) {
		//文件中内容是 aAbB
		//				cCdD
		File file = new File("src/blog/test.txt");
		//逐行读取,采用缓存流BufferedReader
		//建议采用在try括号内使用流的声明,即使在异常时也能关闭流,减少资源损耗
		try(
				Reader fr = new FileReader(file);
				BufferedReader br = new BufferedReader(fr);
			)
		{
			String line = "";
			while((line = br.readLine()) != null) {//读取一行
				System.out.println(line.toUpperCase());//全部转化为大写
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

}

输出处理后的结果:

AABB
CCDD



JAVA对象流

对象流指的是可以直接把一个对象以流的形式传输给其他的介质,但是,把一个对象序列化有一个前提是:这个对象的类,必须实现了Serializable接口。
注意,写入到文本时,对象以序列化后的二进制形式存放,用文本查看时会乱码
代码如下:

import java.io.*;
class Student implements Serializable{
	//表示这个类当前的版本,如果有了变化,比如新设计了属性,就应该修改这个版本号
    private static final long serialVersionUID = 1L;
	String name;
	int id;
	public Student(String name, int id) {
		this.name = name;
		this.id = id;
	}
	@Override
	public String toString() {
		return "Student [name=" + name + ", id=" + id + "]";
	}
	
}


public class Main {
	public static void main(String[] args) {
		File file = new File("src/blog/test.txt");
		write(file);
		read(file);
	}
	
	//写入对象
	static void write(File file) {
		try(
				OutputStream out = new FileOutputStream(file);
				ObjectOutputStream objout = new ObjectOutputStream(out);//对象输出流
			)
		{
			Student[] students = new Student[2];
			students[0]= new Student("xsy", 123456);
			students[1] = new Student("theory", 654321);
			objout.writeObject(students);//只能写一次
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	
	//读取对象
	static void read(File file) {
		try(
				InputStream in = new FileInputStream(file);
				ObjectInputStream objin = new ObjectInputStream(in);//对象输入流
			)
		{
			Student[] students = (Student[]) objin.readObject(); // 读取文件中的所有对象
			for (Student s : students) {
				System.out.println(s);
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
	}
}

对象读取的运行结果为:

Student [name=xsy, id=123456]
Student [name=theory, id=654321]



JAVA数据流

数据流的目的在于对文本数据进行格式化读写,以下代码先写入一个整型int和字符串String,然后按顺序readInt和readUTF读取。

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
      
public class Main {
      
    public static void main(String[] args) {
        write();
        read();
    }
 
    private static void read() {
        File f =new File("src\\blog\\test.txt");
        try (
                FileInputStream fis  = new FileInputStream(f);
                DataInputStream dis =new DataInputStream(fis);
        ){
            int i = dis.readInt();
            String str = dis.readUTF();

            System.out.println(i);
            System.out.println(str);
 
        } catch (IOException e) {
            e.printStackTrace();
        }
         
    }
 
    private static void write() {
        File f =new File("src\\blog\\test.txt");
        try (
                FileOutputStream fos  = new FileOutputStream(f);
                DataOutputStream dos =new DataOutputStream(fos);
        ){
            dos.writeInt(1);
            dos.writeUTF("xsy");
        } catch (IOException e) {
            e.printStackTrace();
        }
         
    }
}

运行结果如下:

1
xsy

posted @ 2019-10-15 20:53  衍射  阅读(171)  评论(0编辑  收藏  举报