JAVA_IO流四大家族体系:
JAVA_IO流四大家族(1)
JAVA_IO流四大家族(2)
文章目录
这里主要跟FileInputStream和FileOutputStream用法一样,这里就不在多多赘述,详情请看 JAVA_IO流四大家族,直接上代码
FileReader
实现代码
package FileReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
public class FileReaderTest01 {
public static void main(String[] args) {
FileReader reader=null;
try {
//创建文件
reader=new FileReader("src//tempfile");
//开始读
char [] chars=new char[4];//一次性读取4个字符
int readCount=0;
while((readCount=reader.read(chars))!=-1){
System.out.print(new String(chars,0,readCount));
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if(reader!=null){
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
查看一下读取出来的每个字符输出:
package FileReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
public class FileReaderTest01 {
public static void main(String[] args) {
FileReader reader=null;
try {
//创建文件
reader=new FileReader("src//tempfile");
//准备一个char数组
char [] chars=new char[4];
//往char数组中读取
reader.read(chars);
for(char c:chars){
System.out.println(c);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if(reader!=null){
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
FileWriter
FileWriter
: 文件字符输出流,写只能输出普通文本
package FileWriter;
import java.io.FileWriter;
import java.io.IOException;
public class FileWriterTest {
public static void main(String[] args) {
FileWriter out=null;
try {
out=new FileWriter("src//tempfile");
//开始写
char[]chars={
'中','国','最','棒'};
out.write(chars);
//刷新
out.flush();
} catch (IOException e) {
e.printStackTrace();
}finally {
if(out!=null){
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
直接写入字符串:
package FileWriter;
import java.io.FileWriter;
import java.io.IOException;
/*
* FileWriter:
* 文件字符输出流,写
* 只能输出普通文本
* */
public class FileWriterTest {
public static void main(String[] args) {
FileWriter out=null;
try {
out=new FileWriter("src//tempfile");
//开始写
out.write("我是一名大学生,冲冲冲");
//刷新
out.flush();
} catch (IOException e) {
e.printStackTrace();
}finally {
if(out!=null){
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
换行:
out.write("\n");
FileReader
和FileWriter
只能没办法读声音,图片,视频等这些流媒体文件,只能读普通文本,切记:Word不是普通文本
FileReader和FileWriter实现普通文本文件拷贝
java文件是普通文本文件(能用记事本编辑的都是普通文本文件),普通文本文件和后缀无关
package Filecopy01;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class copy02 {
public static void main(String[] args) {
FileReader in=null;
FileWriter out=null;
try {
in=new FileReader("src//tempfile");
out=new FileWriter("tempfile");
//一边读一边写:
char []chars=new char[1024*512];//1MB
int readCount=0;
while((readCount=in.read(chars))!=-1){
out.write(chars,0,readCount);
}
//刷新
out.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
if(in!=null){
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(out!=null){
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
执行前:
执行后:
BufferedReader
第一种(直接塞入字符流,不需转换)
简介
BufferedReader:
带有缓冲区的字符输入流,使用这个流的时候不需要自定义char数组,或者说不需要自定义byte数组。自带缓冲区
构造方法
代码
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
public class BufferedReaderTest01 {
public static void main(String[] args) throws Exception {
FileReader reader=new FileReader("src//Filecopy01//copy02.java");
BufferedReader br=new BufferedReader(reader);
//读一行
String line=null;
while((line=br.readLine())!=null){
//当读到最后一行的下一行时,返回值为null(即读不到数据就返回为null)
System.out.println(line);//记住,读出来的时候,并没有把换行符读取出来
}
br.close();
//关闭流
//对于包装流来说,只需要关闭最外层流就行,里面的节点流会自动关闭(可以自己看源代码)
}
}
BufferedReader br=new BufferedReader(reader);
这个reader被bufferedReader
当做一个成员变量
注意:因为Reader是一个抽象类,没办法实例化,所以只能挑选继承了Reader 的类来进行实例化
对于包装流来说,只需要关闭最外层流就行,里面的节点流会自动关闭(可以自己看下图)
常识普及
当一个流的构造方法中需要一个流的时候,这个被传进来的流叫做:节点流,外部负责包装的这个流,叫做包装流,还有一个名字叫做处理流,像当前这个程序来说:FileReader
就是一个节点流,BufferedReader
就是包装流/处理流。
注意点:
- readline读出来的时候,并不会把换行符读取出来
- 当readline读到最后一行的下一行时,返回值为null(即读不到数据就返回为null)
第二种(塞入一个字节流,经过转换成为字符流)
细看构造函数
转换问题
这个构造函数只能传入一个字符流,如果要想传入一个字节流的话,那么有没有办法呢?看下图:
解决转换问题
通过转换流转换,把inputStream字节流转换为字符流
FileInputStream in=new FileInputStream("src//Filecopy01//Copy01.java");
InputStreamReader reader=new InputStreamReader(in);
- 通过转换流转换(InputStreamReader将字节流转换成字符流)
- in是节点流,reader是包装流
InputStreamReader
将字节流转换成字符流
BufferedReader br=new BufferedReader(reader);
- 这个构造方法只能传一个字符流,不能传字节流
- reader是节点流,br是包装流
- 总结:节点流和包装流是相对而言的
实现代码
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStreamReader;
public class BufferedReaderTest02 {
public static void main(String[] args) throws Exception {
//字节流
FileInputStream in=new FileInputStream("src//Filecopy01//Copy01.java");
//通过转换流转换(InputStreamReader将字节流转换成字符流)
//in是节点流,reader是包装流
InputStreamReader reader=new InputStreamReader(in);
BufferedReader br=new BufferedReader(reader);
String line=null;
while((line=br.readLine())!=null){
System.out.println(line);
}
//关闭最外层
br.close();
}
}
转换代码合并
BufferedReader br1=new BufferedReader(new InputStreamReader(new FileInputStream("src//Filecopy01//Copy01.java"))) ;
注意
关闭流时,只需要关闭最外层即可
//关闭最外层
br.close();
BufferedWriter
第一种(直接塞入字符流,不需转换)
import java.io.BufferedWriter;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.OutputStreamWriter;
public class BufferedWriterTest01 {
public static void main(String[] args)throws Exception {
BufferedWriter out=new BufferedWriter(new FileWriter("copy",true));
out.write("hello world");
out.write("\n");
out.write("hello kitty");
//刷新
out.flush();
//关闭最外层
out.close();
}
}
第二种(塞入一个字节流,经过转换成为字符流)
import java.io.BufferedWriter;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.OutputStreamWriter;
public class BufferedWriterTest01 {
public static void main(String[] args)throws Exception {
BufferedWriter out=new BufferedWriter(new OutputStreamWriter(new FileOutputStream("copy",true)));
out.write("hello world");
out.write("\n");
out.write("hello kitty");
//刷新
out.flush();
//关闭最外层
out.close();
}
}
DataOutputStream
简介
java.io.DataOutputStream
:数据专属的流, 这个流可以将数据连同数据的类型一并写入文件, 注意:这个文件不是普通文本文档(用记事本打不开)
需要传入一个OutputStream
,OutputStream是一个抽象类,我们没法new,只能去找继承它的子类,可以new一个FileOutputStream("data")
;
实现代码
import java.io.DataOutputStream;
import java.io.FileOutputStream;
public class DataOutputStreamTest {
public static void main(String[] args)throws Exception {
DataOutputStream dos=new DataOutputStream(new FileOutputStream("data"));
//写数据
byte b=100;
short s=200;
int i=300;
long l=400L;
float f=3.0f;
double d=3.14;
boolean sex=false;
char a='e';
dos.writeByte(b);//把数据以及数据的类型一并写入文件当中
dos.writeShort(s);
dos.writeInt(i);
dos.writeLong(l);
dos.writeFloat(f);
dos.writeDouble(d);
dos.writeBoolean(sex);
dos.writeChar(a);
//刷新
dos.flush();
//关闭
dos.close();
}
}
用记事本打开之后,显示如下
印证了:这个文件不是普通文本文档(用记事本打不开) ,读取出来的话,需要借助DataInputStream
DataInputStream
简介
java.io.DataOutputStream
:数据专属的流,这个流可以将数据连同数据的类型一并写入文件,注意:这个文件不是普通文本文档(用记事本打不开)
注意
使用DataInputStream
时,DataOutputStream
这个流的存储顺序必须已知,否则没法读取,存储顺序如下:
dos.writeByte(b);//把数据以及数据的类型一并写入文件当中
dos.writeShort(s);
dos.writeInt(i);
dos.writeLong(l);
dos.writeFloat(f);
dos.writeDouble(d);
dos.writeBoolean(sex);
dos.writeChar(a);
读取代码
import java.io.DataInputStream;
import java.io.FileInputStream;
public class DataInputStreamTest01 {
public static void main(String[] args)throws Exception {
DataInputStream dis=new DataInputStream(new FileInputStream("data"));
//开始读
byte b=dis.readByte();
short s=dis.readShort();
int i=dis.readInt();
long l=dis.readLong();
float f=dis.readFloat();
double d=dis.readDouble();
boolean sex=dis.readBoolean();
char a=dis.readChar();
dis.close();
System.out.println(b);
System.out.println(s);
System.out.println(i);
System.out.println(l);
System.out.println(f);
System.out.println(d);
System.out.println(sex);
System.out.println(a);
}
}
PrintStream
输出控制台如何实现的呢?
联合写:
System.out.println("hello biaobiao");
分开写:
PrintStream ps=System.out;
ps.println("hello liu");
ps.println("hello world");
注意:
标准输出流不需要手动close
改变标准输出流的输出方向
import java.io.FileOutputStream;
import java.io.PrintStream;
public class PrintStreamTest01 {
public static void main(String[] args)throws Exception {
//标准输出流不再指向控制台,指向“log”文件
PrintStream psm=new PrintStream(new FileOutputStream("log"));
//修改输出方向,将输出方向修改到log文件
System.setOut(psm);
//再输出
System.out.println("hello world66666666");
}
}
如何写一个日志
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.text.SimpleDateFormat;
import java.util.Date;
public class LogUtil {
public static void log(String msg){
/*
* 记录日志的方法
* */
try {
//指向一个日志文件
PrintStream out =new PrintStream(new FileOutputStream("log.txt",true));
//改变输出方向
System.setOut(out);
//日期当前时间
Date nowTime=new Date();
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");
String strTime=sdf.format(nowTime);
System.out.println(strTime+":"+msg);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
main方法:
public class LogTest {
public static void main(String[] args) {
//测试工具类是否好用
LogUtil.log("调用了System类的gc()方法,建议启动垃圾回收");
LogUtil.log("调用了UserService的dosome()方法");
LogUtil.log("用户尝试进行登录,验证失败");
}
}