Java IO流
1、类图结构
2、FileInputStream
FileInputStream的构造方法
1、 FileInputStream(File file): 通过打开与实际文件的连接来创建一个 FileInputStream ,该文件由文件系统中的 File对象 file命名。 2、 FileInputStream(String name): 通过打开与实际文件的连接来创建一个 FileInputStream ,该文件由文件系统中的路径名name命名。
推荐第二种构造方法,当你创建一个流对象时,必须传入一个文件路径。该路径下,如果没有该文件,会抛出FileNotFoundException
。
FileInputStream读取字节数据
1、 public int read(): 从输入流读取数据的下一个字节。
2、 public int read(byte[] b): 该方法返回的int值代表的是读取了多少个字节,读到几个返回几,读取不到返回-1
public int read(byte[] b)的一般用法
byte[] buffer = new byte[1024];
int len;
while ((len = fis.read(buffer)) != -1) { //如果没有更多的数据,返回-1
fos.write(buffer, 0, len);
}
在开发中一般强烈推荐使用数组读取文件,代码如下:
package io;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class input2 {
public static void main(String args[]){
FileInputStream inputStream = null;
try {
inputStream = new FileInputStream("a.txt");
int len = 0 ;
byte[] bys = new byte[1024];
while ((len = inputStream.read(bys)) != -1) {
System.out.println(new String(bys,0,len));
}
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
字节流FileInputstream复制图片
public class Copy {
public static void main(String[] args) throws IOException {
String sourcePath = "D:\\1.PNG";
String destPath = "E:\\1.PNG";
FileInputStream fis = null;
FileOutputStream fos = null;
byte[] buffer = new byte[1024];
int len;
try {
fis = new FileInputStream(sourcePath);
fos = new FileOutputStream(destPath);
while((len=fis.read(buffer))!=-1){
fos.write(buffer,0,len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
fis.close();
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
3、FileOutputStream
FileOutputStream的构造方法
1、 public FileOutputStream(File file) 根据File对象为参数创建对象。 2、 public FileOutputStream(String name) 根据名称字符串为参数创建对象。 3、 public FileOutputStream(File file, boolean append) 4、 public FileOutputStream(String name, boolean append) 3和4中第二个参数中都需要传入一个boolean类型的值,true 表示追加数据,false 表示不追加也就是清空原有数据。
推荐第二种构造方法
FileOutputStream写出字节数据
public void write(int b) public void write(byte[] b) public void write(byte[] b,int off,int len) //从
off
索引开始,len
个字节
public class IoWrite {
public static void main(String[] args) throws IOException {
// 使用文件名称创建流对象
FileOutputStream fos = new FileOutputStream("fos.txt");
// 写出数据
fos.write(97); // 写出第1个字节
fos.write(98); // 写出第2个字节
fos.write(99); // 写出第3个字节
byte[] b = " 麻麻我想吃烤山药".getBytes();
// 写出字节数组数据
fos.write(b);
byte[] b = "ab cde".getBytes();
// 写出从索引2开始,2个字节。索引2是c,两个字节,也就是cd。
fos.write(b,2,2);
// 关闭资源
fos.close();
}
}
输出结果:
abc 麻麻我想吃烤山药 c
4、FileReader
字符流本质其实就是基于字节流读取时,去查了指定的码表,而字节流直接读取数据会有乱码的问题
字符流 = 字节流 + 编码表
FileReader的构造方法
1、
FileReader(File file)
: 创建一个新的 FileReader ,给定要读取的File对象。 2、FileReader(String fileName)
: 创建一个新的 FileReader ,给定要读取的文件的字符串名称。
FileReader读取字符数据
1、
public int read()
: 从输入流读取一个字符,返回该字符。如果已经达到流的结尾,则为-1 2、public int read(char[] cbuf, int offset, int length)
: 从输入流中读取一些字符,并将它们存储到字符数组cbuf
中。如果已经达到流的结尾,则为-1
5、FileWriter
FileWriter的构造方法
1、
FileWriter(File file)
: 创建一个新的 FileWriter,给定要读取的File对象。 2、FileWriter(String fileName)
: 创建一个新的 FileWriter,给定要读取的文件的名称。3、
FileWriter(File file,boolean append)
: 创建一个新的 FileWriter,给定要读取的File对象。 4、FileWriter(String fileName,boolean append)
: 创建一个新的 FileWriter,给定要读取的文件的名称。3和4中第二个参数中都需要传入一个boolean类型的值,true 表示追加数据,false 表示不追加也就是清空原有数据。
FileWriter的方法
1、void write(int c) 写入单个字符。 2、void write(char[] cbuf)写入字符数组。 3、 abstract void write(char[] cbuf, int off, int len)写入字符数组的某一部分,off数组的开始索引,len写的字符个数。 4、 void write(String str)写入字符串。 5、void write(String str, int off, int len) 写入字符串的某一部分,off字符串的开始索引,len写的字符个数。 6、void flush()刷新该流的缓冲。 7、void close() 关闭此流,但要先刷新它。
//一个一个读
public static void copyMethod1(FileReader fr, FileWriter fw) throws IOException {
int ch;
while((ch=fr.read())!=-1) {//读数据
fw.write(ch);//写数据
}
fw.flush();
}
//多个一起读
public static void copyMethod2(FileReader fr, FileWriter fw) throws IOException {
char chs[]=new char[1024];
int len=0;
while((len=fr.read(chs))!=-1) {//读数据
fw.write(chs,0,len);//写数据
}
fw.flush();
}
关闭close和刷新flush
flush
:刷新缓冲区,流对象可以继续使用。close
:先刷新缓冲区,然后通知系统释放资源。流对象不可以再被使用了。
** 关闭资源时,与FileOutputStream不同。 如果流对象不关闭,数据只是保存到缓冲区,并未保存到文件。**
字符流,只能操作文本文件
字符流,只能操作文本文件,不能操作图片,视频等非文本文件。当我们单纯读或者写文本文件时 使用字符流 其他情况使用字节流
6、节点流和处理流
节点流和处理流的区别和联系
处理流的功能主要体现在以下两个方面:
7、缓冲流
缓冲流的基本原理:
1、使用了底层流对象从具体设备上获取数据,并将数据存储到缓冲区的数组内。 2、通过缓冲区的read()方法从缓冲区获取具体的字符数据,这样就提高了效率。 3、如果用read方法读取字符数据,并存储到另一个容器中,直到读取到了换行符时,将另一个容器临时存储的数据转成字符串返回,就形成了readLine()功能。 也就是说在创建流对象时,会创建一个内置的默认大小的缓冲区数组,通过缓冲区读写,减少系统IO次数,从而提高读写的效率。
字节缓冲流
构造方法
1、 public BufferedInputStream(InputStream in) :创建一个新的缓冲输入流,注意参数类型为InputStream。 2、public BufferedOutputStream(OutputStream out): 创建一个新的缓冲输出流,注意参数类型为OutputStream。
读写方法
缓冲流读写方法与基本的流是一致的,效率高
字符缓冲流
构造方法
public BufferedReader(Reader in)
:创建一个新的缓冲输入流,注意参数类型为Reader。
public BufferedWriter(Writer out)
: 创建一个新的缓冲输出流,注意参数类型为Writer。
字符缓冲流特有方法
字符缓冲流的基本方法与普通字符流调用方式一致,特有方法如下:
BufferedReader:
public String readLine()
: 读一行数据。 读取到最后返回nullBufferedWriter:
public void newLine()
: 换行,由系统属性定义符号。
8、序列化
序列化和反序列化
Java 提供了一种对象序列化的机制。用一个字节序列可以表示一个对象,该字节序列包含该对象的数据、对象的类型和对象中存储的属性等信息。字节序列写出到文件之后,相当于文件中持久保存了一个对象的信息。
反之,该字节序列还可以从文件中读取回来,重构对象,对它进行反序列化。对象的数据、对象的类型和对象中存储的数据信息,都可以用来在内存中创建对象。
ObjectOutputStream 提供序列化功能
public class ObjectOutStream_ {
public static void main(String[] args) throws IOException {
String filePath = "e:\\data.dat";
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(filePath));
//序列化数据到e:\data.dat
oos.writeInt(100);// int -> Integer (实现了Serializable)
oos.writeBoolean(true);// boolean -> Boolean (实现了Serializable)
oos.writeChar('a');// char -> Character (实现了Serializable)
oos.writeDouble(9.5);// double -> Double (实现了Serializable)
oos.writeUTF("韩顺平教育");//String
//保存一个dog 对象
oos.writeObject(new Dog("旺财", 10));
oos.close();
}
}
class Dog implements Serializable {
String name;
int age;
transient int id; // transient瞬态修饰成员,不会被序列化
public Dog(String name, int age){
this.name = name;
this.age =age
}
}
ObjectInputStream 提供反序列化功能
public class ObjectOutStream_ {
public static void main(String[] args) throws IOException {
// 1.创建流对象
String filePath = "e:\\data.dat";
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("filePath"));
// 2.读取, 注意顺序
System.out.println(ois.readInt());
System.out.println(ois.readBoolean());
System.out.println(ois.readChar());
System.out.println(ois.readDouble());
System.out.println(ois.readUTF());
System.out.println(ois.readObject());
// 3.关闭
ois.close();
}
}
9、标准输入输出流
public class InputAndOutput {
public static void main(String[] args) {
//System 类 的 public final static InputStream in = null;
// System.in 编译类型 InputStream
// System.in 运行类型 BufferedInputStream
// 表示的是标准输入 键盘
System.out.println(System.in.getClass());
//老韩解读
//1. System.out public final static PrintStream out = null;
//2. 编译类型 PrintStream
//3. 运行类型 PrintStream
//4. 表示标准输出 显示器
System.out.println(System.out.getClass());
System.out.println("hello");
Scanner scanner = new Scanner(System.in);
System.out.println("输入内容");
String next = scanner.next();
System.out.println("next=" + next);
}
}
10、转换流
InputStreamReader
构造方法
InputStreamReader(InputStream in)
: 创建一个使用默认字符集的字符流。InputStreamReader(InputStream in, String charsetName)
: 创建一个指定字符集的字符流。
使用转换流解决编码问题
public class ReaderDemo2 {
public static void main(String[] args) throws IOException {
// 定义文件路径,文件为gbk编码
String FileName = "C:\\A.txt";
// 创建流对象,默认UTF-8编码
InputStreamReader isr = new InputStreamReader(new FileInputStream(FileName));
// 创建流对象,指定GBK编码
InputStreamReader isr2 = new InputStreamReader(new FileInputStream(FileName) , "GBK");
// 定义变量,保存字符
int read;
// 使用默认编码字符流读取,乱码
while ((read = isr.read()) != -1) {
System.out.print((char)read); // 输出乱码
}
isr.close();
// 使用指定编码字符流读取,正常解析
while ((read = isr2.read()) != -1) {
System.out.print((char)read);// 正常输出
}
isr2.close();
}
}
<font color=red>Windows默认编码方式是GBK,使用UTF-8会出现乱码
OutputStreamWriter
构造方法
OutputStreamWriter(OutputStream in)
: 创建一个使用默认字符集的字符流。OutputStreamWriter(OutputStream in, String charsetName)
: 创建一个指定字符集的字符流
指定编码构造代码
public class OutputDemo {
public static void main(String[] args) throws IOException {
// 定义文件路径
String FileName = "C:\\s.txt";
// 创建流对象,默认UTF8编码
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(FileName));
// 写出数据
osw.write("我是"); // 保存为6个字节
osw.close();
// 定义文件路径
String FileName2 = "D:\\A.txt";
// 创建流对象,指定GBK编码
OutputStreamWriter osw2 = new OutputStreamWriter(new FileOutputStream(FileName2),"GBK");
// 写出数据
osw2.write("大神");// 保存为4个字节
osw2.close();
}
}
11、打印流
PrintStream
//复制文本
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintStream;
public class PrintStreamDemo {
public static void main(String[] args) throws IOException {
BufferedReader br=new BufferedReader(new FileReader("copy.txt"));
PrintStream ps=new PrintStream("printcopy.txt");
String line;
while((line=br.readLine())!=null) {
ps.println(line);
}
br.close();
ps.close();
}
}
//复制文本
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
/**
* 使用打印流复制文本文件
*/
public class PrintWriterDemo {
public static void main(String[] args) throws IOException {
BufferedReader br=new BufferedReader(new FileReader("aa.txt"));
PrintWriter pw=new PrintWriter("printcopyaa.txt");
String line;
while((line=br.readLine())!=null) {
pw.println(line);
}
br.close();
pw.close();
}
}
12、Properties属性类
(1)是一个集合类,Hashtable的子类 (2)特有功能 A:public Object setProperty(String key,String value) B:public String getProperty(String key) C:public Set stringPropertyNames() (3)和IO流结合的方法 把键值对形式的文本文件内容加载到集合中 public void load(Reader reader) public void load(InputStream inStream) 把集合中的数据存储到文本文件中 public void store(Writer writer,String comments) public void store(OutputStream out,String comments)
Properties
继承于Hashtable
,来表示一个持久的属性集。它使用键值结构存储数据,每个键及其对应值都是一个字符串。该类也被许多Java类使用,比如获取系统属性时,System.getProperties
方法就是返回一个Properties
对象
构造方法
public Properties()
:创建一个空的属性列表
基本的存储方法
public Object setProperty(String key, String value) : 保存一对属性。 public String getProperty(String key) :使用此属性列表中指定的键搜索属性值。 public Set<String> stringPropertyNames() :所有键的名称的集合。
public class ProDemo {
public static void main(String[] args) throws FileNotFoundException {
// 创建属性集对象
Properties properties = new Properties();
// 添加键值对元素
properties.setProperty("filename", "a.txt");
properties.setProperty("length", "209385038");
properties.setProperty("location", "D:\\a.txt");
// 打印属性集对象
System.out.println(properties);
// 通过键,获取属性值
System.out.println(properties.getProperty("filename"));
System.out.println(properties.getProperty("length"));
System.out.println(properties.getProperty("location"));
// 遍历属性集,获取所有键的集合
Set<String> strings = properties.stringPropertyNames();
// 打印键值对
for (String key : strings ) {
System.out.println(key+" -- "+properties.getProperty(key));
}
}
}
输出结果:
{filename=a.txt, length=209385038, location=D:\a.txt}
a.txt
209385038
D:\a.txt
filename -- a.txt
length -- 209385038
location -- D:\a.txt
与流相关的方法
public void load(InputStream inStream)
: 从字节输入流中读取键值对。
public class ProDemo {
public static void main(String[] args) throws FileNotFoundException {
// 创建属性集对象
Properties pro = new Properties();
// 加载文本中信息到属性集
pro.load(new FileInputStream("Properties.txt"));
// 遍历集合并打印
Set<String> strings = pro.stringPropertyNames();
for (String key : strings ) {
System.out.println(key+" -- "+pro.getProperty(key));
}
}
}
输出结果:
filename -- Properties.txt
length -- 123
location -- C:\Properties.txt
参考:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律