Java中的io流

文章详细介绍了Java中的File类,包括其各种方法,如获取文件信息、判断文件属性、文件操作等。接着,讲解了字节流(InputStream、OutputStream)和字符流(Reader、Writer)的基本操作,如读写文件、文件复制。还涉及到了缓冲流(BufferedInputStream、BufferedReader)提高效率的作用,以及转换流(InputStreamReader、OutputStreamWriter)在不同字符集之间的转换。最后提到了对象流(ObjectOutputStream、ObjectInputStream)的序列化和反序列化功能。
摘要由CSDN通过智能技术生成

File文件类
1.访问文件名相关的方法
String getName():返回此File对象所表示的文件名或路径名(如果是路径,则返回最后一级子路径名)。
String getPath():返回此File对象所对应的路径名。File getAbsoluteFile():返回此 File对象的绝对路径。
String getAbsolutePath(:返回此File对象所对应的绝对路径名。
String getParent():返回此File对象所对应目录(最后一级子目录)的父目录名。
boolean renameTo(File newName):重命名此File对象所对应的文件或目录,如果重命名成功,则返回true;否则返回false。
2.文件检测相关的方法
boolean exists():判断File对象所对应的文件或目录是否存在。
boolean can Write():判断File对象所对应的文件和目录是否可写。
boolean canRead():判断File对象所对应的文件和目录是否可读。
boolean isFile():判断File对象所对应的是否是文件,而不是目录。
boolean isDirectory():判断File对象所对应的是否是目录,而不是文件。
boolean isAbsolute():判断File对象所对应的文件或目录是否是绝对路径。
3.获取常规文件信息
long lastModified():返回文件的最后修改时间。
long length():返回文件内容的长度。
4.文件操作相关的方法
boolean createNewFile():当此File对象所对应的文件不存在时,该方法将新建一个该File对象所指定的新文件,如果创建成功则返回true;否则返回false。
boolean delete():删除File对象所对应的文件或路径。
5.目录操作相关的方法
boolean mkdir():试图创建一个File对象所对应的目录,如果创建成功,则返回 true;否则返回false。调用该方法时File对象必须对应一个路径,而不是一个文件。
String[]list():列出 File对象的所有子文件名和路径名,返回String 数组。
File[] listFiles():列出 File对象的所有子文件和路径,返回File数组。
static File[] listRoots():列出系统所有的根路径。这是一个静态方法,可以直接通过File类来调用。
 

import java.io.File;
import java.io.IOException;
//文件常见基础操作
public class FileMain {
	public static void main(String[] args) throws IOException {
		// 可以是目录 可以是文件
		// 1、如何构建文件对象 提供文件路径
		File file1 = new File("D:\\GZ2204\\0217");
		// 提供父路径
		String path = "D:\\GZ2204\\0217";
		File file2 = new File(path, "test.txt");
 
		// 提供父文件对象
		File parent = new File("D:\\GZ2204\\0217");
		File file3 = new File(parent, "test.txt");
 
		// 2、获取文件信息
		// System.out.println("文件的绝对路径:"+file1.getAbsolutePath());
		// System.out.println("文件的构建路径:"+file1.getPath());
		// System.out.println("文件名:"+file1.getName());
		// System.out.println("文件的内存大小:"+file1.length()+"字节");//1G=1024MB
 
		// 3、判断文件属性
		// System.out.println("文件是否存在:"+file2.exists());
		// System.out.println("file是否为目录:"+file1.isDirectory());
		// System.out.println("file是否为文件:"+file1.isFile());
 
		// 4、文件操作方法【添加、删除】
		// System.out.println(file2.createNewFile());//当文件不存在则创建、否则返回false
		// System.out.println(file1.delete());//
		// System.out.println(file1.mkdir());//只能创建单层目录,多层是不可以的
		// System.out.println(file1.mkdirs());//能创建多层目录
 
		// 5、文件的遍历两个方法
		// String[] files = file1.list(); //获取文件名列表
		// for (String string : files) {
		// System.out.println(string);
		// }
 
		// File[] files = file1.listFiles();//获取文件对象列表
		// for (File file : files) {
		// System.out.println(file.getName());
		// }
 
 
	}
}

遍历例子

如何遍历0217下的所有文件、包括子目录的文件

import java.io.File;
import java.io.IOException;	
public class FileMain {
	public static void main(String[] args) throws IOException {
		// 可以是目录 可以是文件
		// 1、如何构建文件对象 提供文件路径
		File file1 = new File("D:\\GZ2204\\0217");
		// 提供父路径
		String path = "D:\\GZ2204\\0217";
		File file2 = new File(path, "test.txt");
 
		// 提供父文件对象
		File parent = new File("D:\\GZ2204\\0217");
		File file3 = new File(parent, "test.txt");
		//如何遍历0217下的所有文件、包括子目录的文件
		printFile(file1);
	}
}
	// 定义一个递归方法遍历文件
	public static void printFile(File file) {
		//
		if(file.isDirectory()) {
			System.out.println(file.getPath());
		}
		// 1\出口 这是一个文件
		if (file.isFile()) {
			System.out.println(file.getName());
			return;
		}
		// 2\迭代的规律 目录
		// 获取文件列表
		File[] files = file.listFiles();
		// 遍历---printFile(File file)
		for (File file2 : files) {
			printFile(file2);
		}
	}

6.文件过滤器操作(文件过滤,文件名过滤)


import java.io.File;
import java.io.FilenameFilter;
 
//定义一个类来实现文件名过滤器和定义过滤规则,实现filenameFilter接口
public class FileFilterDemo implements FilenameFilter{
 
	//File pathname 是调用者的文件对象   name是过滤器遍历到的文件名
	@Override
	public boolean accept(File pathname,String name) {
		// System.out.println("accept--"+pathname.getAbsolutePath());
		// System.out.println(name);
		// 提取文件名中包含、的文件
		if(name.contains("、")) {
			return true;
		}
		// 
		return false;
	}
 

}


//测试
import java.io.File;
public class FileFilterMain{
public static void main(String[] args}{
	File  file1=new File("D:\\kk\\022");
	String[] files=file1.list(new FileFilterDemo());
    System.out.println("符合要求的");
    for(String file:files){
    System.out.println(file);
}
} 

IO流的理解

JAVA的IO流是实现数据输入/输出的基础,在Java中把不同的输入、输出源(键盘、文件、网络连接等) 抽象地表述为流,使用流来访问数据;

 流的分类
按照流向
--输入流、InputStream\Reader
--输出流、OutputStream\Writer
按照类型
-- 字节流、数据单元为8位的字节
-- 字符流、数据单元为16位的字节
按照角色
-- 节点流、针对某个特定的IO设备、比如磁盘、网络(低级流)
 

按照角色

-- 节点流、针对某个特定的IO设备、比如磁盘、网络(低级流).

 

--处理流、针对已存在的流进行封装,进行高级的操作(高级流)

 

字节流(字节操作,用于文件的复制)
字节输入流、InputStream
--API:
read()方法:读取一个字节的数据,到文件的 结尾就为-1,在读取的时候,read方法会阻塞线程
read(byte[] b)方法:读取多个字节的数据到字节数组中
 1、读取单个字节数据
字节流(字节操作,用于文件的复制)
字节输入流、InputStream
--API:
read()方法:读取一个字节的数据,到文件的 结尾就为-1,在读取的时候,read方法会阻塞线程
read(byte[] b)方法:读取多个字节的数据到字节数组中


 1、读取单个字节数据

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
 
字符的输入流
public class FileInputDemo {
 
	public static void main(String[] args) throws IOException {
		// 从硬盘中服读取文件数据 \
		// InputStream in = new FileInputStream(new File("D:\\GZ2204\\0217\\test.txt"));
		InputStream in = new FileInputStream("D:\\GZ2204\\0217\\test.txt");
		int res = in.read();// 读取一个字节的数据 一个byte,当数据读取完之后返回是-1
		System.out.println("读取到数据:" + (char) res);
 
		// int res =0;
		// //当数据流没有读取完,则一直读取
		// while((res=in.read())!=-1) {
		// System.out.print((char)res);
		// }
		// 关闭资源
		in.close();
	}
 
}

2、数据存储在字节数组中】一次性读取多个字节

方法一:字节数组

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
 
字符的输入流
public class FileInputDemo {
 
	public static void main(String[] args) throws IOException {
 
		InputStream in = new FileInputStream("D:\\GZ2204\\0217\\test.txt");
		byte[] buff = new byte[100];
		// 存放的数组 ,偏移量【数组存放的位置偏移量】,读取到的个数
		int res = in.read(buff, 2, 10);// 从流中读取多个个字节的数据存放到字节数组中,当数据读取完之后返回是-1
		System.out.println("读取个数:" + res);
		for (int i = 0; i < res; i++) {
		System.out.print((char) buff[i]);
		 }
		System.out.println();
		System.out.println(Arrays.toString(buff));
		System.out.println((char) (32));
		in.close();
	}
 
}

字节输出流、OutputStream

--API:

write(int i)方法:写出一个字节的数据;(true表示为追加模式,默认为false【覆盖】)

write(byte[] b)方法:写出多个字节的数

//字节流--File输出字节流
public class FileOutputDemo {
 
	public static void main(String[] args) throws IOException {
		// 创建输出流的对象
		// OutputStream out = new FileOutputStream(new.0
		// File("D:\\GZ2204\\0217\\test.txt"));
		OutputStream out = new FileOutputStream("D:\\GZ2204\\0217\\test.txt", true);
        
		// 1、写出一个字节的数据,默认是覆盖原来文件中的数据
		// out.write((int)'中');//如果超过byte的范围则无法正确编解码
 
		// 2、写出多个字节的数据,默认是覆盖原来文件中的数据
		out.write("多个字节".getBytes());//getBytes() 翻译成字节数组
        
		//系统中的换行:
			// Windows系统里,每行结尾是 回车+换行 ,即\r\n;
			// Unix系统里【linux】,每行结尾只有 换行 ,即\n;
			// Mac系统里,每行结尾是 回车 ,即\r。
		out.write("\r\n".getBytes());
		out.write("123".getBytes());
        
		// 3、写出多个字节的数据,默认是覆盖原来文件中的数据,有偏移量
		// out.write("abc".getBytes(), 1, 2);getBytes数组长度为3,若偏移1,再加上取3个数据则越界
        //1,2偏移量和个数
 
		// 关闭资源
		out.close();
 
	}
 
}

例子

使用字节流实现文件复制

操作一:一个个读取(时长比较长)

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
 
//使用字节流实现文件复制
public class FIieCopyDemo {
 
	public static void main(String[] args) throws IOException {
		// 文件复制:
		// 把D:\GZ2204\0217\img.png 复制到 D:\GZ2204\0217\demo\img.png
		// 1、 从来源读取数据【输入流】
		FileInputStream in = new FileInputStream("D:\\软件\\mysql-5.7.34-winx64.zip");
		// 2、把数据写出目标【输出流】
		FileOutputStream out = new FileOutputStream("D:\\GZ2204\\0217\\demo\\mysql-5.7.34-winx1.zip");
		// 3、复制:不断的读、不断的写【直到写完为止】
		int len = 0;
		while((len = in.read())!=-1) {//读取
			//写出
			out.write(len);
		}
		//关闭资源
		in.close();
		out.close();
		System.out.println("复制成功");
	}
 
}

操作二:多个读取(时长比较短,但要注意数组大小)


import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
 
//使用字节流实现文件复制
public class FIieCopyDemo {
 
	public static void main(String[] args) throws IOException {
		// 文件复制:
		// 把D:\GZ2204\0217\img.png 复制到 D:\GZ2204\0217\demo\img.png
		// 1、 从来源读取数据【输入流】
		FileInputStream in = new FileInputStream("D:\\软件\\mysql-5.7.34-winx64.zip");
		// 2、把数据写出目标【输出流】
		FileOutputStream out = new FileOutputStream("D:\\GZ2204\\0217\\demo\\mysql-5.7.34-winx1.zip");
		//操作二:多个字节操作   
        //10000byte --  635ms     5000000byte       --468ms     500000000byte  ---  1316ms
	//long start = System.currentTimeMillis();//时间测试
		byte[] buff = new byte[500000000];//数组大小并不是越大越快,要适当大小才能达到最快
		int len = 0;
		while((len = in.read(buff))!=-1) {//读取len个字节
			//写出len个字节
			out.write(buff,0,len);
		}
	//	long end = System.currentTimeMillis();//时间测试
	//	System.out.println(end-start);//时间测试
        
		//关闭资源
		in.close();
		out.close();
		System.out.println("复制成功");
	}
 
}

字符流(字符操作,用于文本)【字节流+编码表】

字符输入流、Reader

--API:

read(char[] c)方法:读取多个字符的数据到字符数组中


import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
 
//字符流--操作与字节流类似,只是一个字符大小为两个字节;
public class FileReaderDemo {
 
	public static void main(String[] args) throws IOException {
		// 从硬盘中服读取文件数据 \
		// InputStream in = new FileInputStream(new File("D:\\GZ2204\\0217\\test.txt"));
		FileReader in = new FileReader("D:\\GZ2204\\0217\\test.txt");
		// 1、读取单个字符数据
		// int res = in.read();//读取一个字节的数据 一个字符,当数据读取完之后返回是-1
		// System.out.println("读取到数据:"+(char)res);
 
		// int res =0;
		// //当数据流没有读取完,则一直读取
		// while((res=in.read())!=-1) {
		// System.out.print((char)res);
		// }
 
		// 2、数据存储在字节数组中一次性读取多个字符
		char[] buff = new char[100];
		int res = in.read(buff);// 从流中读取多个字符的数据存放到字符数组中,当数据读取完之后返回是-1
		System.out.println(res);
		// 将字符数组中的数据展示出来
		for (int i = 0; i < res; i++) {
			System.out.print((char) buff[i]);
		}
 
		// 3、数据存储在字节数组中一次性读取多个字节,可以设定偏移量和个数
 
		// 关闭资源
		in.close();
	}
 
}

字符输出流、Writer
--API:
write(String str)方法:写出一个字符串数据
注意:输出流写出数据数据时,默认会覆盖之前的数据,可以使用构造器将append设置为true,即为追加模式
(字符流应用在与文本相关一些操作,字节流应用于文件复制等操作)


import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
 
//字符的输出流   
public class FileWriteDemo {
 
	//字符:字节+编码 	
	public static void main(String[] args) throws IOException {
		//
		Writer out = new FileWriter("D:\\GZ2204\\0217\\test.txt");
		// 1、写出单个字节数据
		// out.write(int c);
		// out.write(char[] c);
		out.write("你好!admin111!");
		// 使用flush方法将内置缓冲区中的数据刷新,持久化
		// out.flush();//若数据量没达到阈值,不会写出可以用flush刷新
		out.close();//会默认调用flush(),然后在关闭资源
	}
 
}

缓冲流【字节缓冲流,字符缓冲流】

 具备一个 内置的缓冲区,默认的大小为8192,所以比普通字节流的操作速率要高;
字符缓冲流【字符输入流有readLine方法、字符输出流有newLine方法】
API:
readLine方法//输入流BufferStream
newLine方法//输出流:BufferReader
字符输入缓冲流
BufferedInputStream 和InputStream的速度对比
//一个字节与多个字节是速度比较;像是搬砖,从A地到B地,拿车搬和一块块搬速度有很大差别;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
 
public class BufferStreamDemo {public static void main(String[] args) throws IOException {
	 //缓冲流--包装流--处理流
	 FileInputStream fin = new FileInputStream("D:\\GZ2204\\0217\\5、文件过滤器.wmv");
	 FileOutputStream fout = new FileOutputStream("D:\\GZ2204\\0218\\文件过滤器.wmv");
	 // 创建一个缓冲字节输入流 -- 提供一个字节流的对象
	 BufferedInputStream in = new BufferedInputStream(fin);
	 BufferedOutputStream out = new BufferedOutputStream(fout);
	 //
	 long start = System.currentTimeMillis();
	 //一个字节操作
	 int data = 0;
	 while((data=fin.read())!=-1) {
	 fout.write(data);
	 }
	 //
	 fin.close();
	 fout.close();
	 //
	 long end = System.currentTimeMillis();//BufferedInputStream 527 InputStream161103
	 System.out.println(end-start);
	 }
 }
字符输出缓冲流
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
 
//缓冲流:特点:缓冲区
public class BufferReaderDemo {
 
	public static void main(String[] args) throws IOException {
		// 使用字符缓冲流来读取数据
		BufferedReader reader = new BufferedReader(new FileReader("D:\\GZ2204\\0218\\test.txt"));
		//
		//int res = reader.read();
		//
		//System.out.println((char)res);
		
		//当reader读取完数据流之后readLine()则返回null,test.txt共有4行数据
		System.out.println(reader.readLine());
		System.out.println(reader.readLine());
		System.out.println(reader.readLine());
		System.out.println(reader.readLine());
		System.out.println(reader.readLine());		
		//字符输出缓冲流  [注意:写出数据时,要刷新数据]
		 BufferedWriter writer = new BufferedWriter(new
		 FileWriter("D:\\GZ2204\\0218\\test.txt", true));//true为追加数据
	
		 writer.write("a");
		// writer.close();//close之后就添加不了数据了
		 writer.newLine();//创建新的一行【换行】
		 writer.write("b");
		 writer.close();
		 //把在缓冲区的数据写出到流中
		// writer.flush();
		// writer.close();
	}
 
}

 

字符集定义
也叫编码表。是一个系统支持的所有字符的集合,包括各国家文字、标点符号、图形符号、数字等。
ASCII字符集 :
ASCII(American Standard Code for Information Interchange,美国信息交换标准代码)是基于拉丁字母的一套电脑编码系统,用于显示现代英语,主要包括控制字符(回车键、退格、换行键等)和可显示字符(英文大小写字符、阿拉伯数字和西文符号)。
基本的ASCII字符集,使用7位(bits)表示一个字符,共128字符。ASCII的扩展字符集使用8位(bits)表示一个字符,共256字符,方便支持欧洲常用字符。
ISO-8859-1字符集:
拉丁码表,别名Latin-1,用于显示欧洲使用的语言,包括荷兰、丹麦、德语、意大利语、西班牙语等。
ISO-8859-1使用单字节编码,兼容ASCII编码。
GBxxx字符集:
GB就是国标的意思,是为了显示中文而设计的一套字符集。
GB2312:简体中文码表。一个小于127的字符的意义与原来相同。但两个大于127的字符连在一起时,就表示一个汉字,这样大约可以组合了包含7000多个简体汉字,此外数学符号、罗马希腊的字母、日文的假名们都编进去了,连在ASCII里本来就有的数字、标点、字母都统统重新编了两个字节长的编码,这就是常说的"全角"字符,而原来在127号以下的那些就叫"半角"字符了。
GBK:最常用的中文码表。是在GB2312标准基础上的扩展规范,使用了双字节编码方案,共收录了21003个汉字,完全兼容GB2312标准,同时支持繁体汉字以及日韩汉字等。
GB18030:最新的中文码表。收录汉字70244个,采用多字节编码,每个字可以由1个、2个或4个字节组成。支持中国国内少数民族的文字,同时支持繁体汉字以及日韩汉字等。
Unicode字符集 :
Unicode编码系统为表达任意语言的任意字符而设计,是业界的一种标准,也称为统一码、标准万国码。
它最多使用4个字节的数字来表达每个字母、符号,或者文字。有三种编码方案,UTF-8、UTF-16和UTF-32。最为常用的UTF-8编码。
UTF-8编码,可以用来表示Unicode标准中任何字符,它是电子邮件、网页及其他存储或传送文字的应用中,优先采用的编码。互联网工程工作小组(IETF)要求所有互联网协议都必须支持UTF-8编码。所以,我们开发Web应用,也要使用UTF-8编码。它使用一至四个字节为每个字符编码,编码规则:
128个US-ASCII字符,只需一个字节编码。
拉丁文等字符,需要二个字节编码。
大部分常用字(含中文),使用三个字节编码。
其他极少使用的Unicode辅助字符,使用四字节编码。
 

 

处理流(包装流)

在已有的流的基础上进行包装,实现高级操作【可以设定字符集编码】

转换流

包括InputStreamReader、OutputStreamWriter--在构建转换流时, 可以封装节点流, 并指定编码集

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
 
//使用转换流读取数出数据     可以指定字符集编码
public class TransformDemo {
 
public static void main(String[] args) throws IOException, FileNotFoundException {
		// Reader  转换流--包装流
		InputStreamReader in = new InputStreamReader(new FileInputStream("D:\\GZ2204\\0218\\data2.txt"), "GBK");
		//
		int len = 0;
		//
		char[] buff = new char[1024];
		//
		while((len=in.read(buff))!=-1) {
			System.out.println(new String(buff,0,len));
		}
		in.close();
	}
}
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
 
//使用转换流写出数据   可以指定字符集编码
public class TransformDemo {
    public static void main(String[] args) throws IOException, FileNotFoundException {
		// Reader  转换流--包装流  可以指定字符集编码
		OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream("D:\\GZ2204\\0218\\data3.txt"), "UTF-8");
		//
		out.write("转换流--包装流");
		//
		out.close();
	}
	}

例子

1.把一个GBK编码的文档数据   转换到一个UTF-8


import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
 
public class TransformDemo {
	public static void main(String[] args) throws IOException, FileNotFoundException {
	// Reader  转换流--包装流
	InputStreamReader in = new InputStreamReader(new FileInputStream("D:\\GZ2204\\0218\\data1.txt"), "GBK");
	// Reader  转换流--包装流
	OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream("D:\\GZ2204\\0218\\data2.txt"), "UTF-8");
	//
	int len = 0;
	//
	char[] buff = new char[1024];
	//
	while((len=in.read(buff))!=-1) {
		String data = new String(buff,0,len);
		System.out.println(data);
		out.write(data);//写出
	}
	//
	out.close();
	in.close();
}
 
}

2.键盘输入数据,在控制台中输出, 当键盘中输入exit时退出

public static void test() throws IOException{
        //包装流-转换流将系统输入字节流封装到转换流中System.in
        InputStreamReader reader=new InputStreamReader(System.in);
        //数据读取操作
        char[] c=new char[1024];
        int len;
        while((len=reader.read(c))!=-1){
        String input=new String(c,0,len);
        System.out.println(input);
        if(input.equals("exit\r\n"){
        break;
}}}

打印流 (PrintStream,PrintWriter)
1.输出语句中的out对象就是PrintStream
2.可以使用构造器给打印流设置字符集编码
3.PrintStream 设置编码的构造器
PrintStream ps = new PrintStream(file, csn);
PrintStream ps = new PrintStream(fileName, csn);
PrintStream ps = new PrintStream(out, autoFlush, encoding);
 


import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintWriter;
 
//打印流,只有输出流,没有输入流  System.out.println()中的out是PrintStream的对象
public class PrintDemo {
 
	 public static void main(String[] args) throws IOException,
	 FileNotFoundException {
	 //
	 PrintStream printStream = new PrintStream(new
	 FileOutputStream("D:\\GZ2204\\0218\\data3.txt"), true, "GBK");
	 //
	 printStream.print("你好");
	 printStream.println("不好");
	 printStream.println("吧");
	 printStream.printf("我的名字是%s,性别是%s", "小王","男");
	 //
	 printStream.close();
	 }
}

4.PrintWriter设置编码的构造器
PrintWriter pw = new PrintWriter(file, csn);
PrintWriter pw = new PrintWriter(fileName, csn);
 

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintWriter;
public class PrintDemo {
	public static void main(String[] args) throws IOException, FileNotFoundException {
		//
		PrintWriter printWriter = new PrintWriter("D:\\GZ2204\\0218\\data3.txt", "GBK");
		//
		printWriter.print("你好!");
		printWriter.println("不好");
		printWriter.println("吧!");
		printWriter.printf("我的名字是%s,性别是%s", "小王", "男");
		//使用PrintWriter,要注意flush
		printWriter.flush();
		//
		printWriter.close();
	}
 
}

5.API:
print()方法:各种类型数据的打印方法,没有换行
printf()方法:安照字符串格式进行打印输出的方法
println()方法:各种类型数据的打印方法,有换行的
RandomAccessFile(随机访问类,针对文件)
"r":以只读方式打开指定文件。如果试图对该RandomAccessFile执行写入方法,都将抛出IOException异常。
"rw":以读、写方式打开指定文件。如果该文件尚不存在,则尝试创建该文件。
"rws":以读、写方式打开指定文件。相对于"rw"模式,还要求对文件的内容或元数据的每个更新都同步写入到底层存储设备。
"rwd":以读、写方式打开指定文件。相对于"rw"模式,还要求对文件内容的每个更新都同步写入到底层存储设备。
API:

readLine():读取一行
seek():设置读取或写出数据操作的偏移量
skipBytes():跳过多少个字节
注意:readUTF方法和writeUTF方法的编码和标准的UTF-8的编码是不一样的,所以在进行文本操作的时候要注意编码和解码一致
 

public class RandomAccessFileDemo {
 
	public static void main(String[] args) throws IOException {
		// 创建RandomAccessFile
		RandomAccessFile ranfile = new RandomAccessFile("D:\\GZ2204\\0221\\test.txt", "rw");
		//写出操作
		System.out.println(ranfile.length());
		// seek方法设置设定下次读取或者写出的位置
	    ranfile.seek(ranfile.length());
		ranfile.write("-abc".getBytes());			
		ranfile.close();
	}
}

读取操作

public class RandomAccessFileDemo {
 
	public static void main(String[] args) throws IOException {
		// 创建RandomAccessFile
		RandomAccessFile ranfile = new RandomAccessFile("D:\\GZ2204\\0221\\test.txt", "rw");=
		//		String line = ranfile.readLine();//读取一行
        //		ranfile.skipBytes(1);//跳过多少个字节(跳过1个字节)
		char line = (char) ranfile.readByte();//读取单个
        System.out.println(line);
		ranfile.close();
	}
 
}

特殊操作


import java.io.IOException;
import java.io.RandomAccessFile;
public class RandomAccessFileDemo {
 
	public static void main(String[] args) throws IOException {
		// 创建RandomAccessFile
		RandomAccessFile ranfile = new RandomAccessFile("D:\\GZ2204\\0221\\test.txt", "rw");
		 
		//特殊操作  针对utf的字符进行操作,建议使用本身读写方法
//		ranfile.writeUTF("电饭锅电饭锅");
		String line = ranfile.readUTF();
		System.out.println(line);
		
		ranfile.close();
	}
 
}

对象流(对象序列化)
定义
序列化(将对象序列化为字节序列,可以保存在磁盘中或者通过网络进行传输)、反序列化(字节序列解析为对象)例子:可以应用于网络传输、比如写qq聊天室
API:
writeObject();
readObject();

import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
 
public class ObjectStreamTest {
 
	public static void main(String[] args) throws IOException, ClassNotFoundException {
//		// 对象输出流  --  序列化操作
//		ObjectOutputStream obs = new ObjectOutputStream(new FileOutputStream("D:\\GZ2204\\0221\\test.txt"));
//		//创建一个对象
//		Person p = new Person(1, "zhang", "male", 35);
//		//写出    //NotSerializableException  
//		obs.writeObject(p);
		
		
		// 对象输入流  --  反序列化操作
		ObjectInputStream ois = new ObjectInputStream(new FileInputStream("D:\\GZ2204\\0221\\test.txt"));
		//
		Object obj = ois.readObject();
		//
		System.out.println(obj);
	}
 
}

注意
1.读写的 对象类型必须要实现可序列化的接口Serializable
2.当类中有 某一个类的引用时,则该引用类型也要实现 可序列化接口
3. 同一个对象 只序列化一次,所以当对象数据修改后,再输出也是同样的数据(序列号相同,则不再序列化)
4.在 类实现序列化时,建议生成序列化版本号, 用于辨识当前类,即使类被修改之后,也能将字节序列反序列 化为正确类型的对象。(即在写类时,加上版本号,以便于在修改后也能识别当前类)

import java.io.Serializable;
 
//人类
public class Person implements Serializable {
 
	/**
	 * 序列化的版本id 是在类进行升级改造之后,可以通过id去反序列化数据回来,解决兼容性问题
	 * 比如:  Person [id、name、sex、age]  把对象数据存储在文档中
	 * 后面升级改造  Person [id、name、sex、age、address]
	 * 由于版本id的存在,即使类修改结构之后,都会认定为同一个版本,则可以进行反序列化
	 */
	private static final long serialVersionUID = 1L;
 
	private int id;
	private String name;
	private String sex;
	private int age;
 
	private String address;
 
	public int getId() {
		return id;
	}
 
	public void setId(int id) {
		this.id = id;
	}
 
	public String getName() {
		return name;
	}
 
	public void setName(String name) {
		this.name = name;
	}
 
	public String getSex() {
		return sex;
	}
 
	public void setSex(String sex) {
		this.sex = sex;
	}
 
	public int getAge() {
		return age;
	}
 
	public void setAge(int age) {
		this.age = age;
	}
 
	public String getAddress() {
		return address;
	}
 
	public void setAddress(String address) {
		this.address = address;
	}
 
	public Person(int id, String name, String sex, int age, String address) {
		super();
		this.id = id;
		this.name = name;
		this.sex = sex;
		this.age = age;
		this.address = address;
	}
 
	public Person() {
		super();
	}
 
	//
	@Override
	public String toString() {
		return "Person [id=" + id + ", name=" + name + ", sex=" + sex + ", age=" + age + ", address=" + address + "]";
	}
 
	public Person(int id, String name, String sex, int age) {
		super();
		this.id = id;
		this.name = name;
		this.sex = sex;
		this.age = age;
	}
 
}
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
 
public class ObjectStreamTest2 {
 
	public static void main(String[] args) throws IOException, ClassNotFoundException {
//		// 对象输出流  --  序列化操作
		ObjectOutputStream obs = new ObjectOutputStream(new FileOutputStream("D:\\GZ2204\\0221\\test.txt"));
		//创建一个对象
		Person p = new Person(1, "li", "fmale", 35,"haizhu");
		//修改了对象数据
		//写出    //NotSerializableException  
		obs.writeObject(p);
		//
		obs.close();
		
//		 对象输入流  --  反序列化操作
		ObjectInputStream ois = new ObjectInputStream(new FileInputStream("D:\\GZ2204\\0221\\test.txt"));
		//1
		Object obj = ois.readObject();
		//
		System.out.println(obj);
	}
 
}

Properties属性类

一般结合io流,读取配置文件来配置环境

常用操作

--properties.setProperty("name", "张三");//设置

--properties.getProperty("name")//获取

public static void main(String[] args) throws FileNotFoundException, IOException {
//		// Properties   	//类似map集合操作
		Properties properties = new Properties();
		//set、get
		properties.setProperty("name", "张三");
		properties.setProperty("sex", "男");
		properties.setProperty("age", "15");
		//
		System.out.println(properties);
       //获取操作
		System.out.println(properties.getProperty("name"));
		
		//遍历properties
		Set<String> names = properties.stringPropertyNames();
		for (String string : names) {
			System.out.println(string+"=="+properties.getProperty(string));
		}

--properties.load(new FileInputStream("D:\\GZ2204\\0221\\system.txt"));

--获取key集合properties.stringPropertyNames();

public class PropertiesDemo {
	public static void main(String[] args) throws FileNotFoundException, IOException {
		
		//在框架中会看见
		Properties properties = new Properties();
		//加载文件
		properties.load(new FileInputStream("D:\\GZ2204\\0221\\system.properties"));
		//遍历properties
		Set<String> names = properties.stringPropertyNames();
		for (String string : names) {
			System.out.println(string+"=="+properties.getProperty(string));
		}
		
		
	}
 
}

IO流总结
字节流[字节]
lnputStream --> FilelnputStream[单个字节、多个字节、偏移量]OutputStream --> FileOutputStream
字符流[字符]==》字节+编码{GBK两个字节UTF-8两个或者三字节}
Reader-->FileReader[单个字符、多个字符、偏移量]
Writer--> FileWriter
缓冲流:[缓冲区]【默认缓冲区长度8192】【io交互次数少,操作性能高】【封装了低级流】
BufferedInputStream
BufferedOutputStream
BufferedReader
BufferedWriter[注意: flush]特有方法
readLine();newLine();
文件复制:BufferedInputStream和BufferedOutputStream再外加一个存储数组
文本操作:BufferedReader和BufferedWriter
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值