输入流:从硬盘读到内存中,或者叫输入,读(Read)、输入(Input)、输入流(InputStream)。
输出流:从内存写到硬盘中,或者叫输出,写(Write)、输出(Output)、输出流(OutputStream)。
字节流:按照字节读取数据,一次读取1个字节Byte,等同于一次读取8个二进制。这种流是万能的,什么类型文件都可以读取。包括:文本文件、图片、声音文件等。
字符流:按照字符读取数据,一次读取一个字符,这种流方便读取普通文本。只能读取纯文本文件,无法读取word文件,因为word文件有格式。
Java中所有流都在:java.io.*;
Java中的IO流(都是抽象类):
字节输入流(万能的):java.io.InputStream
字节输出流(万能的):java.io.OutputStream
字符输入流(只能处理纯文本文件):java.io.Reader
字符输出流(只能处理纯文本文件):java.io.Writer
类名以“Stream”结尾是字节流,以“Reader/Writer”结尾是字符流。
Java中所有流都实现了java.io.Closeable接口,都是可关闭的,都有close()方法。流是内存和硬盘之间的通道,用完之后要关闭,否则会占用资源。
所有的输出流都实现了java.io.Flushable接口,都是可刷新的,都有flush()方法。输出流在最终输出后,一定要用flush()刷新一下,清空管道。如果没有flush可能会丢失数据。
常用java.io包下的16个流:
文件专属:java.io.FileInputStream、java.io.FileOutputStream、java.io.FileReader、java.io.FileWriter
转换流(字节流转换成字符流):java.io.InputStreamReader、java.io.OutputStreamWriter
缓冲流专属:java.io.BufferedReader、java.io.BufferedWriter、java.io.BufferedInputStream、java.io.BufferedOutputStream
数据流专属:java.io.DataInputStream、java.io.DataOutputStream
标准输出流:java.io.PrintWriter、java.io.PrintStream
对象专属流:java.io.ObjectInputStream、java.io.ObjectOutputStream
FileInputStream:文件字节输入流,万能的,任何类型的文件都可以采用这个流来读。
字节方式:从硬盘到内存完成输入操作,完成读操作。
在D/study路径下创建了temp.txt文件,文件中内容:abcdef
public class FileInputStreamTest {
public static void main(String[] args) {
FileInputStream fis = null;
//创建文件字节输入流对象
try {
//采用绝对路径方式
fis = new FileInputStream("D:\\study\\temp.txt");
//FileInputStream有抛出异常,所以要try/catch
//FileInputStream fis = new FileInputStream("D:/study/temp"); 写成"/"也可以
int readData = -1;
while ((readData = fis.read()) != -1){
//读取一次指针指向下一个字符
System.out.printf(readData + " "); //97 98 99 100 101 102
}
System.out.println();
System.out.println(fis.read()); //读取不到字符返回-1
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
//在finally语句块中,确保流一定关闭
if (fis != null) {
//流是null时没必要关闭。
try {
fis.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
}
public class FileInputStreamTest {
public static void main(String[] args) {
FileInputStream fis = null;
try {
fis = new FileInputStream("D:\\study\\temp.txt");
//开始读,采取byte数组,一次读取多个字节,最多读取“数组.length”个字节
byte[] bytes = new byte[4];//准备一个4个长度的byte数组
//int read(byte[] b) 返回的是读取到的字节数量,不是字节本身。
int readCount = fis.read(bytes);
System.out.println(readCount); //第一次读到了4个字节,返回:4
//String(byte[] bytes) 能够将byte数组转成字符串
System.out.println(new String(bytes)); //abcd
//String(byte[] bytes,int offset,int length) 能够将byte数组中起始位置为offset,长度为length转为字符串
System.out.println(new String(bytes,0,readCount)); //abcd
readCount = fis.read(bytes);
System.out.println(readCount); //第二次继续读,只读到2个字节,返回:2
//第二次读取的时候,读取到两个字节,只覆盖了前面两个字节
System.out.println(new String(bytes)); //efcd
System.out.println(new String(bytes,0,readCount));//ef
readCount = fis.read(bytes);
System.out.println(readCount); //第三次继续读,没读到字节,返回:-1
//第三次读取的时候,没有覆盖任何字节
System.out.println(new String(bytes)); //efcd
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
}
public class FileInputStreamTest {
public static void main(String[] args) {
FileInputStream fis = null;
try {
fis = new FileInputStream("D:\\study\\temp.txt");
//开始读,采取byte数组,一次读取多个字节,最多读取“数组.length”个字节
byte[] bytes = new byte[4];//准备一个4个长度的byte数组
int readCount = 0;
while ((readCount= fis.read(bytes)) != -1){
System.out.print(new String(bytes,0,readCount)); //abcdef
}
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
}
FileInputStream其他常用方法:
返回流当中剩余还没读到的字节数:int avaiable()
跳过几个字节不读:long skip(long n)
public class FileInputStreamTest03 {
public static void main(String[] args) {
FileInputStream fis = null;
try {
fis = new FileInputStream("D:\\study\\study4\\study4\\tempfile");
//总字节数量
System.out.println("总字节数量:" + fis.available()); //总字节数量:6
//读一个字节
//int readCount = fis.read();
//System.out.println("剩下多少个字节没有读:" + fis.available()); 剩下多少个字节没有读:5
//byte[] bytes = new byte[fis.available()]; //这种方式不适用于大文件,因为byte数组不能太大。
//int readCount = fis.read(bytes);//6
//System.out.println(new String(bytes)); //abcdef
fis.skip(3); //跳过3个字节
System.out.println(fis.read()); //100
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
}
public class FileOutputStreamTest {
public static void main(String[] args) {
FileOutputStream fos = null;
try {
//temptest文件不存在时会新建,有文件时会清空文件重新写。
fos = new FileOutputStream("D:\\study\\study4\\study4\\temptest");
//开始写
byte[] bytes = {97,98,99,100};
//将byte数组全部写出
fos.write(bytes); //abcd
fos.write(bytes,0,2); //在写入ab
//写完之后一定要刷新
fos.flush();
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
}finally {
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
}
public class FileOutputStreamTest01 {
public static void main(String[] args) {
FileOutputStream fos = null;
try {
//在路径后面加true表示在文件末尾写入数据
fos = new FileOutputStream("D:\\study\\study4\\study4\\temptest",true);
//开始写
//写入一个String字符串
String s = "来杯冰美式";
byte[] bs = s.getBytes();
fos.write(bs);
//写完之后一定要刷新
fos.flush();
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
}finally {
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
}
public class CopyTest {
public static void main(String[] args) {
FileInputStream fis = null;
FileOutputStream fos = null;
try {
//新建一个字节输入流
fis = new FileInputStream("C:\\Users\\Administrator\\Desktop\\谢沛民\\JAVA零基础\\2面向对象—匿名内部类.md");
//新建一个字节输出流
fos = new FileOutputStream("C:\\Users\\Administrator\\Desktop\\2面向对象—匿名内部类.md");
//核心的一边读一边写
byte[] bytes = new byte[1024 * 1024]; //1024字节=1KB 1024*1024字节=1MB
int readCount = 0;
while ((readCount= fis.read(bytes)) != -1){
fos.write(bytes,0,readCount);
}
//输出流最后要刷新
fos.flush();
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
//两个try/catch分开,否则有一个出现异常会影响另一个流关闭
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
if(fos != null){
try {
fos.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
}
public class FileReaderTest01 {
public static void main(String[] args) {
FileReader reader = null;
try {
//创建文件字符输入流
reader = new FileReader("D:\\study\\study4\\study4\\tempfile");
//开始读
char[] chars = new char[4]; //一次读取4个字符
int readCount = 0;
while((readCount=reader.read(chars)) !=-1){
System.out.printf(new String(chars,0,readCount) + " "); //abcd ef
}
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
}
public class FileWriterTest {
public static void main(String[] args) {
FileWriter out = null;
try {
//创建文件字符输出流对象
out = new FileWriter("D:\\study\\study4\\study4\\file");
//开始写
char[] chars = {'来','杯','冰','美','式'};
out.write(chars);
out.write(chars,2,3);
out.write("\n"); //这是插入一个换行符“\n”
out.write("这是咖啡加点ice的学习笔记");
out.flush();
} catch (IOException e) {
throw new RuntimeException(e);
}finally {
if (out != null) {
try {
out.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
}
public class CopyTest {
public static void main(String[] args) {
FileReader frer = null;
FileWriter fwer = null;
try {
frer = new FileReader("D:\\study\\study4\\study4\\file");
fwer = new FileWriter("C:\\Users\\Administrator\\Desktop\\file");
int readCount = 0;
char[] chars = new char[1024];
while((readCount= frer.read(chars))!=-1){
fwer.write(chars,0,readCount);
}
fwer.flush();
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
if (frer != null) {
try {
frer.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
if (fwer != null){
try {
fwer.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
}
BufferedReader:带有缓冲区的字符输入流。使用这个流不需要自定义char数组或byte数组,自带缓冲。
BufferedReader构造方法:BufferedReader(Reader in)
这个构造方法需要一个流,被传递进来的流叫做:节点流。
外部负责包装的流叫做:包装流/处理流。
读一行方法(不带换行符):readLine()
public class BufferedReaderTest {
public static void main(String[] args) throws IOException {
//这里的FileReader作为一个节点流
FileReader reader = new FileReader("D:\\study\\study4\\study4\\file");
//BufferedReader作为包装流/处理流
BufferedReader br = new BufferedReader(reader);
//读一行方法(不带换行符):readLine()
String s = null;
while ((s=br.readLine()) != null){
System.out.println(s);
}
//关闭流只需要关闭外边的包装流,里边的节点流会自动关闭
br.close();
}
}
public class BufferedReaderTest {
public static void main(String[] args) throws IOException {
//字节流
//FileInputStream in = new FileInputStream("D:\\study\\study4\\study4\\file");
//通过转换流将字符流转换为字符流
// InputStreamReader reader = new InputStreamReader(in);
//BufferedReader只能传一个字符流,不能传字节流。
// BufferedReader br = new BufferedReader(reader);
//将以上合并
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("D:\\study\\study4\\study4\\file")));
String line = null;
while((line=br.readLine())!=null){
System.out.println(line);
}
//只需要关闭最外层
br.close();
}
}
public class BufferedWriterTest {
public static void main(String[] args) throws IOException {
//BufferedWriter out = new BufferedWriter(new FileWriter("D:\\study\\study4\\study4\\file"));
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("D:\\study\\study4\\study4\\file")));
out.write("咖啡哪有生活苦");
out.write("\n");
out.write("来杯冰美式");
out.write("\n");
out.write("这是咖啡加点ice的学习笔记");
//刷新
out.flush();
//关闭最外层流
out.close();
}
}
DataOutputStream:数据专属得流,这个流可以将数据连同数据类型一并写入文件。
注意:这个文件不是普通的文本文档,用记事本打不开
public class DataOutputStreamTest {
public static void main(String[] args) throws Exception{
//创建数据专属字节输出流
DataOutputStream dos = new DataOutputStream(new FileOutputStream("D:\\study\\study4\\study4\\dataout"));
//写数据
byte b = 100;
short s = 200;
int i = 300;
long l = 400l;
float f = 3.0f;
double d = 3.14;
boolean sex = false;
char c = 'a';
//写入
dos.writeByte(b); //把数据以及数据的类型一并写入文件当中
dos.writeShort(s);
dos.writeInt(i);
dos.writeLong(l);
dos.writeFloat(f);
dos.writeDouble(d);
dos.writeBoolean(sex);
dos.writeChar(c);
//刷新
dos.flush();
//关闭流
dos.close();
}
}
public class DataInputStreamTest {
public static void main(String[] args) throws Exception{
DataInputStream dis = new DataInputStream(new FileInputStream("D:\\study\\study4\\study4\\dataout"));
//开始读
//如果读的顺序不一样,会发生乱码
System.out.println(dis.readByte());
System.out.println(dis.readShort());
System.out.println(dis.readInt() + 1000);
System.out.println(dis.readLong());
System.out.println(dis.readFloat());
System.out.println(dis.readDouble());
System.out.println(dis.readBoolean());
System.out.println(dis.readChar());
}
}
public class PrintStreamTest {
public static void main(String[] args) throws Exception{
//联合起来写
System.out.println("咖啡加ice"); //咖啡加ice
//分开写
PrintStream ps = System.out;
ps.println("生活哪有咖啡苦"); //生活哪有咖啡苦
//标准输出流不需要手动close关闭
//改变标准输出流的输出方向
//标准输出流不再指向控制台,指向log文件,修改输出方向为log文件。
System.setOut(new PrintStream(new FileOutputStream("log",true)));
System.out.println("来杯冰美式");
System.out.println("咖啡哪有生活苦");
}
}
public class logger {
public static void log(String msg){
try {
PrintStream out = new PrintStream(new FileOutputStream("log.txt",true));
//改变输出方向
System.setOut(out);
//设置日期
Date now = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");
String strTime = sdf.format(now);
//打印日志
System.out.println(strTime + ":" +msg);
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
}
}
}
public class LogTest {
public static void main(String[] args) {
logger.log("测试一下打印日志工具类");
}
}
//log.txt文件下内容:
//2024-01-18 11:00:05 644:测试一下打印日志工具类
——本章节为个人学习笔记。学习视频为动力节点Java零基础教程视频:动力节点—JAVA零基础教程视频