字节流/字符流
一、IO
- IO
Java 中的 I/O 操作主要是指使用 java.io 包下的内容,进行输入/输出的操作。输出可以叫读取数据,输出也叫做写出数据
2, IO的分类
根据数据的流向分:
输入流 : 把数据从其他的设备上读取到内存中的流
输出流 : 把数据从 内存中写出到其他设备上的流
根据数据的类型分:
字节流 : 以字节为单位,读写数据的流
字符流 : 义字符为单位,读取数据的流
其流向:
输入:硬盘 →输入→ 内存
输出:内存 →输出→ 硬盘
- 顶级父类
字节流:
输入流: InputStream
输出流: OutputStream
字符流:
输入流: Reader
输出流: Writer
二、字节流
一切文件数据、图片、视频等在储存时,都是以二进制数字i形式保存的,传输时也一样,所以字节流可以传输任意文件数据。
1. 字节流输出(OutputStream)
java.io.OutputStream 抽象类是表示字节输出流所有类的超类,将指定的字节信息写出到目的地,其定义字节输出流的基本方法有:
> close() : 关闭输出流并释放与此流相关的任何系统资源; 当完成流的操作时,必须调用此方法,释放系统资源
> flush() : 刷新此输出流并强制任何缓冲的输出字节被写出
> write(byte[] b) : 将 b.length 字节从指定的字节数组写入此输出流
> write(byte[] b, int off, int len) : 从指定的字节数组写入 len 字节,从偏移量 off 开始输出到此输出流
> write(int b):将指定的字节输出流
2. FileOutputStream类
FileOotpetStream 类是文件输出流,将数据写出到文件
方法:
FileOutputStream(File file) : 创建文件输出流以写入由指定的 File 对象表示的文件
FileOutputStraem(String name) : 创建文件输出流以指定的名称写入文件
当创建一个流对象视,必须传入一个文件路劲,该路径下,如果没有这个文件会创建改文件,如果有这个文件就会清空这个文件的数据
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
public class FileIoDemo {
public static void main(String[] args) throws FileNotFoundException {
//使用File对象创建流对象
File file = new File("ccc.txt");
FileOutputStream fileOst = new FileOutputStream(file);
//使用文件名创建流对象
FileOutputStream fileOutputStream = new FileOutputStream("bbb.java");
}
}
3. 写出字节数据
a. 写出字节 : write(int b) 方法,每次可以写出一个字节数据
import java.io.FileOutputStream;
import java.io.IOException;
public class FileWriteOne {
public static void main(String[] args) throws IOException {
FileOutputStream file = new FileOutputStream("ccc.txt");
//写出数据
file.write(97); //为对应的 ascii 码
file.write(98);
file.write(99);
String
//关闭资源
file.close();
}
}
输出查看文件:
注意:虽然参数为int 类型四个字节,但是只会保留一个字节的信息写出,流操作完毕后,必须释放系统资源,调用 close 方法
b. 写出字节数组 write(byte[ b])
import java.io.FileOutputStream;
import java.io.IOException;
public class OutWriteArray {
public static void main(String[] args) throws IOException {
//使用文件名创建刘对象
FileOutputStream f = new FileOutputStream("aaa.txt");
//字符串转换为字节数组
byte[] bytes = "你好".getBytes();
//写出字节数组
f.write(bytes);
//关闭资源
f.close();
}
}
运行查看文件:
c. 写出指定长度字节数组 write(byte[] b,int off, int len)
import java.io.FileOutputStream;
import java.io.IOException;
public class FileWriteTwo {
public static void main(String[] args) throws IOException {
//使用文件名创建流对象
FileOutputStream ff = new FileOutputStream("G:\\aaa_project\\ccc\\ddd.txt");
//字符串转换为字节数组
byte[] bb = "asdfas".getBytes();
//写出索引从1开始,2个字节,索引为s ,连哥哥字节,结果 sd
ff.write(bb,1,2);
ff.close();
}
}
输出查看文件:
4. 数据追加与续写
添加数据:
FileoutputStream(File file,boolean append) : 创建文件输出流以写入知道你过的File 对象表示的文件
FileOutputStream(String name,boolean append):创建文件输出流以指定的名称写入文件
这两个构造方法,参数中都需要传入一个boolean 类型的值,true 表示追加数据,false 表示清空原有数据
import java.io.FileOutputStream;
import java.io.IOException;
public class FileWriateThree {
public static void main(String[] args) throws IOException {
//使用文件名创建流对象
FileOutputStream ffs = new FileOutputStream("G:\\aaa_project\\ccc\\ddd.txt",true);
//将字符串转换为字节数组
byte[] bbs = " adfafadfadfasfasf".getBytes(); //在原有的ddd.txt 文件中新增了这串字符
//写出数据
ffs.write(bbs);
ffs.close();
}
}
输出:
写出换行
Windows 系统中,换行符号是 \r\n
public class FileWriateThree {
public static void main(String[] args) throws IOException {
//使用文件名创建流对象
FileOutputStream ffs = new FileOutputStream("G:\\aaa_project\\ccc\\ddd.txt",true);
//将字符串转换为字节数组
byte[] bbs = " adfafadfadfasfasf".getBytes();
//换行
ffs.write("\r\n".getBytes());
//写出数据
ffs.write(bbs);
ffs.close();
}
}
输出:
回车符:\r 和 换行符:\n
回车符:回到一行的开头
换行符:下一行
系统中的换行:
Windows系统中是,每行结尾是回车+换行 ,就是 \r\n
Unix系统中: 每行结尾只有 换行,就是 \n
Mac系统中, 每行结尾是回车,就是\r
5. 字节的输入流 InputStream
InputStream 是抽象类表示字节输入流的所有超类,可以读取字节信息到内存中:
close() : 关闭次输入流并释放与此流相关联的任何资源, 再完成输入流操作时,必须调用此方法,释放系统资源
read() : 从此输入流读取数据的下一个字节
read(byte[] b)) : 从输入流中读取一些字节数,并将他们储存到字节数组b中
FileInputStream类
构造方法:
FileInputStream(File file) : 通过打开与实际文件的连接创建一个 FileInputStream, 该文件有文件系统中的File 对象 file命名
FileIputStream(String name) : 通过打开与实际文件的连接来创建一个 FileInputStream,该文件有文件系统中的路径名 name命名
当创建一个流对象时,必须传入一个文件路径,该路径下如果没有该文件,会抛出 FileNotFoundException
如创建方法:
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
public class FileInputDemo {
public static void main(String[] args) throws FileNotFoundException {
//使用 File 对象创建流对象
File file = new File("z.txt");
FileInputStream f = new FileInputStream(file);
//使用文件名称创建流对象
FileInputStream f1 = new FileInputStream("x.txt");
}
}
6. 读取字节数据
- 读取字节: 用 read 方法,每次可以读取一个字节数据,提升为 int 类型,兑取到文件末尾返回 -1
import java.io.FileInputStream;
import java.io.IOException;
public class FileReadDemo {
public static void main(String[] args) throws IOException {
FileInputStream fileInputStream = new FileInputStream("G:\\123\\ggg\\mmm.txt");
//读取数据返回一个字节
int read = fileInputStream.read();
System.out.println((char) read);
read = fileInputStream.read();
System.out.println((char) read);
read = fileInputStream.read();
System.out.println((char) read);
read = fileInputStream.read();
System.out.println((char) read);
read = fileInputStream.read();
System.out.println((char) read);
read = fileInputStream.read();
System.out.println(read);
fileInputStream.close();
}
}
原文件:
输出:
使用循环的方式来读取
import java.io.FileInputStream;
import java.io.IOException;
public class FileReadWhile {
public static void main(String[] args) throws IOException {
FileInputStream fileInputStream = new FileInputStream("G:\\123\\ggg\\mmm.txt");
int b;
while((b = fileInputStream.read()) != -1){
System.out.println((char) b);
}
//关闭资源
fileInputStream.close();
}
}
输出:
2. 使用字节数组读取: read(byte[] b) : 每次读取 b 的长度个字节到数组中,返回读取到的有效字节个数,读取到末尾,返回 -1
import java.io.FileInputStream;
import java.io.IOException;
public class FileArrayRead {
public static void main(String[] args) throws IOException {
FileInputStream ddd = new FileInputStream("G:\\123\\ggg\\mmm.txt");
//设置变量,作为有效个数
int lent;
//定义字节数组,作为装字节容器
byte[] bt = new byte[2];
//循环读取
while ((lent = ddd.read(bt)) != -1){
//每次读取后,把数组的有效字节部分,变成字符串打印
System.out.println(new String(bt,0,lent)); //lent 每次读取的有效字节个数
};
//关闭资源
ddd.close();
}
}
输出:
拷贝文件
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class CopyImageDemo {
public static void main(String[] args) throws IOException {
//指定数据源(被复制文件)
FileInputStream filein = new FileInputStream("G:\\abc.jpg");
//指定位置(粘贴位置)
FileOutputStream fileout = new FileOutputStream("G:\\test.jpg");
//读取数据
byte[] bytes = new byte[1024];
int len;
while ((len = filein.read(bytes)) != -1){
fileout.write(bytes,0,len);
}
filein.close();
fileout.close();
}
}
三、字符流
1. 字符输入流 Reader
Reader 抽象类是表示用于读取字符流的所类的超雷,可以读取字符信息到内存中
close() : 关闭呲溜并释放与此流相关联的任何系统资源
read() : 从输入流读取一个字符
read(char[ cuf]),从输入流中读取一些字符,并将它们储存到字符数组 cbuf 中
2. FileReader类
FileReader类是读取字符文件的便利类, 构造式使用系统默认的字符编码和默认字节缓冲区
1. 构造方法
FileReader(File file) ; 创建一个新的 FileReader,给定要读取的File 对象
FileReader(String filename) : 创建一个新的 FileReader ,给定要读取的文件名称
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
public class FileReaderDemoOne {
public static void main(String[] args) throws IOException {
//使用File 对象创建流对象
File file = new File("G:\\ggg.txt");
FileReader fileReader = new FileReader(file);
//使用Filename 创建流对象
FileReader fileReader1 = new FileReader("G:\\ggg.txt");
}
}
2. 读取字符数据
1. 读取字符:
read方法,每次可以读取一个字符数据,提升为int类型,读取到文件末尾,返回-1
import java.io.FileReader;
import java.io.IOException;
public class FileReaderDemoTwo {
public static void main(String[] args) throws IOException {
//创建流对象
FileReader fr = new FileReader("G:\\ggg.txt");
int b;
while ((b = fr.read()) != -1){
System.out.println((char)b);
}
fr.close();
}
}
输出
2. 使用字符数组读取
import java.io.FileReader;
import java.io.IOException;
public class FileArrayDemoThree {
public static void main(String[] args) throws IOException {
FileReader fileReader = new FileReader("G:\\ggg.txt");
int len;
char[] chars = new char[2];
while ((len = fileReader.read(chars)) != -1) {
System.out.println(new String(chars,0,len));
}
//关闭资源
fileReader.close();
}
}
输出:
2. 字符输出流 writer
writer 抽象类便是用于写出字符流的所有类的超类,将指定的字符信息写出到目的地,他定义了字节输出流的基本共性功能方法
write(int c) 写入单个字符
write(char[] cr) 写入字符数组
write(char[ ] cr, int off, int len) 写入字符数组的某一部分,off 数组的开始索引,len 写的字符个数
write(String str) 写入字符串
write(String str,int off, int len) 写入字符串得某一部分, off 字符串的开始索引, len写的字符个数
flush() 刷新该流的缓冲
close() 关闭该流,但是先刷新它
3. FileWriter 类
FileWriter 类是写出字符到文件的便利类
1. 构造方法
FileWriter(File file) : 创建一个新的 FileWriter,给定要读取的 File 对象
FileWriter(String name) : 创建一个新的 FileWriter.给定要读取的文件的名称
public class FileWriterDemoThree {
public static void main(String[] args) throws IOException {
//使用File 对象创建流对象
File files = new File("G:\\ggg.txt");
FileWriter fw1 = new FileWriter(files);
//使用文件名称创建流对象
FileWriter fw2 = new FileWriter("G:\\ggg.txt");
}
}
2. 写出数据
public class FileWriterDemoFour {
public static void main(String[] args) throws IOException {
//创建流对象
FileWriter fileWriter = new FileWriter("G:\\ggg.txt");
fileWriter.write(97);
fileWriter.write("b");
fileWriter.write("c");
fileWriter.write(22909); //中文编码对照表中 22909 对应一个汉字
fileWriter.close();//如果不关闭的话,数据只保存到缓存区,不会保存到文件的
}
}
3. 关闭与刷新
因为内置缓冲区的援用,如果不关闭输出流,无法写出字符到文件中,但是关闭流对象的话,又无法继续写出数据,如果想写出数据有想继续使用流,就需要 flush 方法
flush : 刷新缓冲区,流对象继续使用
close : 先刷新缓冲区,后通知系统释放资源,路对象不可以再被使用
public class FileWriterDemoFive {
public static void main(String[] args) throws IOException {
//使用文件名创建流对象
FileWriter fws = new FileWriter("G:\\ggg.txt");
//写出数据通过flush
fws.write("包");
fws.flush();
fws.write("子");
fws.flush();
//写出数据使用 close
fws.write("1");
fws.close();//如果使用了close 后,一下不能继续写出数据了
}
}
4. 写出其他数据
写出字符数组: writer(char[] c) 和 writer(char[] c, int off, int len);
public class FileWriterSix {
public static void main(String[] args) throws IOException {
//创建流对象
FileWriter fws = new FileWriter("G:\\123.txt");
//字符串转换为数组
char[] chars = "我们都是好孩子".toCharArray();
//写出字符串
fws.write(chars); //我们都是好孩子
//换行
fws.write("\r\n");
fws.write(chars,2,3); //都是好
fws.close();
}
}
输出:
写出字符串:writer(String s) 和 writer(String s, int off, int len)
public class FileWriterStringDemo {
public static void main(String[] args) throws IOException {
FileWriter fr = new FileWriter("G:\\321.txt");
String a = "我们都是好子";
fr.write(a);
//换行
fr.write("\r\n");
fr.write(a,2,3);
fr.close();
}
}
输出:
注意:字符流只能对文本文件处理,不能操作图片 视频等非文本文件
四、IO异常处理
使用try…catch…finally
如:
import java.io.FileWriter;
import java.io.IOException;
public class FileIOExceptionDemoOne {
public static void main(String[] args){
//声明变量
FileWriter filew = null;
try{
filew = new FileWriter("G:\\vvv.txt");
//写出数据
filew.write("一二三");
}catch(IOException i){
i.printStackTrace();
}finally {
try{
if (filew != null) {
filew.close();
}
}catch(IOException i){
i.printStackTrace();
}
}
}
}
输出:
五、属性集
Properties 继承于 Hashtable,表示一个持久得属性集,它使用键值结构储存数据,每个减及其对应值都是一个字符串,该类被许多java类使用,如获取修通属性时,System.getProperties 方法就是i返回一个 Properties 对象
Properties 类
Properties() 创建一个空的属性列表
setProperty(String key,String value) : 保存一对属性
getProperty(String key): 使用此属性列表中指定的键搜索属性值
Set < String > stringPropertyNames() : 所有键的名称的集合
import java.util.Properties;
import java.util.Set;
public class FileProperDemoOne {
public static void main(String[] args){
//创建集合对象
Properties properties = new Properties();
//添加键值对元素
properties.setProperty("filename","G:\\ggg.txt");
properties.setProperty("length","132456");
//打印属性集对象
System.out.println(properties);
//通过键获取值
System.out.println(properties.getProperty("filename"));
System.out.println(properties.getProperty("length"));
System.out.println("------------------------");
//遍历集合
Set<String> strings = properties.stringPropertyNames();
for(String string : strings){
System.out.println(string +" "+properties.getProperty(string));
}
}
}
输出:
字节流中读取键值对:load(InpuStraem inStream)
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;
import java.util.Set;
public class FilePropertiesDemoTwo{
public static void main(String[] args) throws IOException {
Properties ps = new Properties();
//加载文本中到属性集
ps.load(new FileInputStream("G:\\kv.txt"));
//遍历集合
Set<String> valus = ps.stringPropertyNames();
for (String key : valus){
System.out.println(key + " " + ps.getProperty(key));
}
}
}
输出: