java基础七 文件io体系

计算机信息编码规则
按照以下原理将数据写读计算机中
在这里插入图片描述以阿拉伯数字9为例,写入的过程,先将其由asc2码表转化为“数”,再将其转化为二进制数存入文件中,则读取的过程,则为上述过程的逆过程。

最常用的字节是八位的字节,即它包含八位的二进制数,即把八个二进制符号称为一个字节
GBK 英文字母1个byte一个汉字两个byte
UTF-8 对全世界大部分语言友好,英文字母1个byte,大部分中文3个byte

一般按照这周机制存储文本及其数据

对文件的操作

创建一个文件夹

File f = new File("f:/xx");
		boolean mkdir = f.mkdir(); // 不能创建多级目录
		System.out.println(mkdir);

创建一个文件夹

File fs = new File("f:/xx1/yy1");
boolean mkdirs = fs.mkdirs();
System.out.println(mkdirs);

创建文件

	File file3 = new File("d:/xx/yy/cls.avi");
	boolean createNewFile = file3.createNewFile();
	System.out.println(createNewFile);

判断该file是否文件

File file = new File("f:/xx/yy/124.txt");
		boolean ifFile = file.isFile();
		System.out.println(ifFile);  // false

判断该file是否文件夹

boolean directory = f.isDirectory();
	System.out.println(directory);   

获取文件的绝对路径

String absolutePath = f.getAbsolutePath();
		System.out.println(absolutePath);
		System.out.println("----------------------------------------");

获取文件的名字

	String fName = file.getName();
System.out.println(fName);  // false

获取上一级目录的file对象

File parentFile = file.getParentFile();
System.out.println(parentFile.getAbsolutePath());

获取上一级目录的路径字符串

String parent = file.getParent();
System.out.println(parent);

获取文件长度 字节(8个bit-- 二进制位)

long length = file.length();
	System.out.println(length);

获取指定目录下的子节点的的字符串

File f2 = new File(c);
String[] listFilesString = f2.list();
for(String f1:listFilesString) {
	System.out.println(f1);
}

获取指定目录下的子节点的File描述对象

File[] listFiles = f2.listFiles();
for(File f1:listFiles) {
	System.out.println(f1.getAbsolutePath());

创建文件

	File file3 = new File("d:/xx/yy/cls.avi");
	boolean createNewFile = file3.createNewFile();
	System.out.println(createNewFile);

重命名文件:其实可以把路径都给改了

	file3.renameTo(new File("d:/xx/yy/bdls.avi"));

删除文件

boolean delete = file3.delete();
	System.out.println(delete);

流的概念和作用

流的概念
流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象。即数据在两设备间的传输称为流,流的本质是数据传输,根据数据传输特性将流抽象为各种类,方便更直观的进行数据操作。
IO流的分类

根据处理数据类型的不同分为:字符流和字节流

根据数据流向不同分为:输入流和输出流
字符流和字节流

字符流的由来: 因为数据编码的不同,而有了对字符进行高效操作的流对象。本质其实就是基于字节流读取时,去查了指定的码表。字节流和字符流的区别:

(1)读写单位不同:字节流以字节(8bit)为单位,字符流以字符为单位,根据码表映射字符,一次可能读多个字节。

(2)处理对象不同:字节流能处理所有类型的数据(如图片、avi等),而字符流只能处理字符类型的数据。

(3)字节流在操作的时候本身是不会用到缓冲区的,是文件本身的直接操作的;而字符流在操作的时候下后是会用到缓冲区的,是通过缓冲区来操作文件,我们将在下面验证这一点。

结论:优先选用字节流。首先因为硬盘上的所有文件都是以字节的形式进行传输或者保存的,包括图片等内容。但是字符只是在内存中才会形成的,所以在开发中,字节流使用广泛。
输入流和输出流

对输入流只能进行读操作,对输出流只能进行写操作,程序中需要根据待传输数据的不同特性而使用不同的流。

这么庞大的体系里面,常用的就那么几个,我们把它们抽取出来,如下图在这里插入图片描述

用FileInputStream读写文件

FileInputStream是一个字节流,一个字节一个字节读取

  //		先构造一个fileinputstream的对象
		FileInputStream fis =new FileInputStream( "f:/a.txt");

//	是一个字节流,一个字节一个字节读取
//		用int声明则表示读出的是编译表中的数字,当读的字节读出的int是-1时,则表示读到文件的末尾
		int read=fis.read();
		System.out.println(read);
//		若想得到是实际数据,则应该根据编码规则对其进行转码,用char声明,char代表一个英文字符
		char read1=(char)fis.read();
		System.out.println(read1);

用FileInputStream和FileOutputStream和byte数组读写文件

byte[] buf=new byte[9];   //指的是byte数组即字节数组,可以装入6个字节

//	fis.read(buf)	一次读取部分长度的数据,并且读到的数据直接填入buf数组中,返回值是真实读到的字节数量

int num =fis.read(buf);   //返回值num是真实读到的字节数量,当读到文件末尾时候读到的是-1,可用该性质写while循环,不包括换行和空格
String string =new String(buf,0,num);  //将读出的数据转为字符串格式,String(buf,2,4)参数分别为要转为字符串的数组,初始位置,和结束位置
System.out.println(string);
System.out.println(num);
		
//-------------用byte数组和while反复读取------------------------------------------------
/*		byte[] buf=new byte[8];  
		int num=0;
		while( (num=fis.read(buf))!=-1){             //返回值num是真实读到的字节数量,当读到文件末尾时候读到的是-1,可用该性质写while循环,不包括换行和空格
    	String string =new String(buf,0,num);                          //打印的东西包括换行和空格
    	System.out.println(string);
    }
    

    fis.close();

FileOutputStream fos=new FileOutputStream("f:/a.txt",true); //加个参数true,则覆盖变为追加
	String string="a你好";
	byte[] bytes=string.getBytes();       //将字符串按指定编码规则--》将信息转化为指定字符串,默认gbk编码
		fos.write(bytes);
		fos.close();

dataoutputstream和datainputstream的读写文件

DataOutputStream是一个包装流,它可以将各种类型的数据在内部转成byte字节,然后利用
DataInputStream可以从字节流中直接转换出具体的数据类型

写文件
FileOutputStream写入文件中

DataOutputStream dos = new DataOutputStream(new FileOutputStream("d:/o.txt"));
		
		// 写入一个整数  4个字节
		int age = 18;
		//dos.writeInt(age);
		
		// 写一个long   8个字节
		//dos.writeLong(19929);
		
		// 写一个float数据  4个字节
		//dos.writeFloat(18.8f);
		
		// 写一个double数据  8个字节
		//dos.writeDouble(18.8);
		
		// 写一个boolean值,true其实写入了一个1 ,false其实写入了一个0
		//dos.writeBoolean(true);
		
		// writeutf在写真正的数据的同时,会在前面加上2个字节的长度记录
		dos.writeUTF("张铁林");
		dos.writeInt(48);
		
		dos.close();
		

读文件
DataInputStream可以从字节流中直接转换出具体的数据类型
DataInputStream dis = new DataInputStream(new FileInputStream(“d:/o.txt”));

	//int age = dis.readInt();
	//long readLong = dis.readLong();
	//float readFloat = dis.readFloat();
	
	//double readDouble = dis.readDouble();
	
	//boolean readBoolean = dis.readBoolean();
	
	//String readUTF = dis.readUTF();
	
	String name = dis.readUTF();
	int age = dis.readInt();
	System.out.println(name);
	System.out.println(age);
	Integer.parseInt("1"); 

用BufferedWriter和BufferedRead读写文件

为了提高字符流读写的效率,引入了缓冲机制,进行字符批量的读写,提高了单个字符读写的效率。BufferedReader用于加快读取字符的速度,BufferedWriter用于加快写入的速度

BufferedWriter

例`

public class BufferedWriterDemo {
public static void main(String[] args) throws Exception {
	 BufferedWriter bfwWriter=new BufferedWriter(new OutputStreamWriter(new FileOutputStream("f:/c.txt",true)));   
	 //自动识别是不是UTF-8
	 //加true参数则是追加,不加则是覆盖
	 bfwWriter.write("66666牛\n呀D!w!!");            //写入字符串
		 bfwWriter.close();            //操作完毕后记住要将流关闭
	
}
}

BufferedRead

`public class BufferedReadDemo {
	public static void main(String[] args) throws Exception {
		

BufferedReader fls= new BufferedReader(new InputStreamReader(new FileInputStream("f:/a.txt"),"UTF-8")); //如果文本包含中文记得加多个参数UTF-8,否则按默认GBK编码格式
//UTF-8对中英文友好,gbk对中文不友好
//BufferedReader包装了字节流,可以将指定的编码集将字节转成字符

//读取第一行
//String line=fls.readLine(); //将文本信息按行填入文件  
//System.out.println(line);    

//读取第二行
//line=fls.readLine();
//System.out.println(line);

while (true) {											//用循环的方式按行读取文件
	String line=fls.readLine();
	if (line==null){break;}
	System.out.println(line);

		
}
fls.close();                         //将流关闭

}`

做一个单词计数器

package ioProject;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Map.Entry;
import java.util.Set;

public class Wordcount {public static void main(String[] args) throws Exception, FileNotFoundException {
	BufferedReader fls= new BufferedReader(new InputStreamReader(new FileInputStream("f:/a.txt"),"UTF-8")); //如果文本包含中文记得加多个参数UTF-8,否则按默认GBK编码格式
	HashMap<String,Integer> Wordcount=new HashMap<>();

	while (true) {											//将文本信息按行填入文件,用循环的方式
		String line=fls.readLine();
		if (line==null){break;}
		String[] wordList=line.split(" ");          
		for (String i:wordList){
			if(Wordcount.containsKey(i)){
				Integer count =Wordcount.get(i);
				Wordcount.put(i,count+1);}
			else{Wordcount.put(i,1);}
		}
		
	}
		fls.close();         
	
		Set<Entry<String,Integer>> entrySet =	 Wordcount.entrySet();
		for (Entry x:entrySet){			
			System.out.println("key="+x.getKey()+"&&value="+x.getValue());
			}

		
		
}
}

Java序列化与反序列化

Java序列化是指把Java对象转换为字节序列的过程;而Java反序列化是指把字节序列恢复为Java对象的过程。

import java.io.Serializable;
//implements Serializable 告诉jdk,这个类的对象是可被序列化的

public class User  implements Serializable {
	
	
	
	String name;
	int age;
	float salary;
	long hairNum;
	
	
	public User(String name, int age, float salary, long hairNum) {
		super();
		this.name = name;
		this.age = age;
		this.salary = salary;
		this.hairNum = hairNum;
	}
	


	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public float getSalary() {
		return salary;
	}
	public void setSalary(float salary) {
		this.salary = salary;
	}
	public long getHairNum() {
		return hairNum;
	}
	public void setHairNum(long hairNum) {
		this.hairNum = hairNum;
	}

	@Override
	public String toString() {
		return "[name=" + name + ", age=" + age + ", salary=" + salary + ", hairNum=" + hairNum + "]";
	}
	


}

实现序列化接口的类

若将类实现了Serializable接口,则可以对类的对象进行序列化和反序列化
类似以下操作,implements Serializable 告诉jdk,这个类的对象是可被序列化的

public class User implements Serializable {    
private String userName; 
private String password; 
}

用ObjectInputStream和ObjectOutputStream读写对象、ArrayList、HashMap等复杂的数据类型

读写对象

public class ObjectInputStreamDemo {
	public static void main(String[] args) throws FileNotFoundException, IOException {
	ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("d:/u.obj"));
		
		User user1 = new User("慕容复", 38, 2800, 8000);
		User user2 = new User("扫地僧", 58, 3800, 0);
		// writeObject(user)方法,要求user对象是可序列化的 
		oos.writeObject(user1);
		oos.writeObject(user2);
		
		oos.close();
				ObjectInputStream ois = new ObjectInputStream(new FileInputStream("d:/u.obj"));
    
    		User readObject1 = (User) ois.readObject();  //声明为User类
    		User readObject2 = (User) ois.readObject();
    
    		System.out.println(readObject1);
    		System.out.println(readObject2);
    
    		ois.close();
	}

}

读写ArrayList



public class ArrayListObject {
public static void main(String[] args) throws Exception, IOException {
	
	//  将一个list对象直接写入文件
	User user1 = new User("慕容复", 38, 2800, 8000);
	User user2 = new User("扫地僧", 58, 3800, 0);
	
	ArrayList<User> users = new ArrayList<>();
	users.add(user1);
	users.add(user2);
	
	
	ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("d:/users.list"));
	oos.writeObject(users);
	oos.close();
	
	
	// 从文件中读取一个list对象
	ObjectInputStream ois = new ObjectInputStream(new FileInputStream("d:/users.list"));
	ArrayList<User> userList = (ArrayList<User>) ois.readObject();
	System.out.println(userList);
	
	ois.close();

}
}

读写HashMap


	/**
	 * 直接从文件中读取一个map对象
	 */
	@Test
	public void testReadMap() throws Exception {
	//从文件中写入一个对象
HashMap<String, User> users = new HashMap<>();
		
		User user1 = new User("慕容复", 38, 2800, 8000);
		User user2 = new User("扫地僧", 58, 3800, 0);
		users.put(user1.getName(), user1);
		users.put(user2.getName(), user2);
		
		ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("d:/users.map"));
		oos.writeObject(users);
		oos.close();

		// 从文件中读取一个list对象
		ObjectInputStream ois = new ObjectInputStream(new FileInputStream("d:/users.map"));
		HashMap<String, User> userMap = (HashMap<String, User>) ois.readObject();
		System.out.println(userMap);
	}
	
发布了44 篇原创文章 · 获赞 0 · 访问量 875

猜你喜欢

转载自blog.csdn.net/heartless_killer/article/details/97837773