I/O流概述
IO流用来处理设备之间的数据传输
Java对数据的操作是通过流的方式
Java用于操作流的对象都在IO包中
流按流向划分: 输入流,输出流
流按读写数据类型划分: 字节流,字符流
字节流:
可以读写任意类型的文件
输出流
FileOutputStream构造方法:
//文件输出流是用于将数据写入 File
//FileOutputStream(File file)
//创建一个向指定 File 对象表示的文件中写入数据的文件输出流。
//FileOutputStream(File file, boolean append)
//创建一个向指定 File 对象表示的文件中写入数据的文件输出流。
//FileOutputStream(String name)
//创建一个向具有指定名称的文件中写入数据的输出文件流。
//FileOutputStream(String name, boolean append)
//创建一个向具有指定 name 的文件中写入数据的输出文件流。
//FileOutputStream(File file)
//创建一个向指定 File 对象表示的文件中写入数据的文件输出流。
//输出流,所关联的文件,如果不存在,会自动帮你创建一个
File file = new File("a.txt");
FileOutputStream out = new FileOutputStream(file);
//直接传入一个字符串的文件路径,如果这个文件不存在,会自动帮你创建
FileOutputStream out2 = new FileOutputStream("c.txt");
例:创建并写入一个数据的文件
public class Mydemo3 {
public static void main(String[] args) throws IOException {
// 1)创建一个向指定 File 对象表示的文件中写入数据的文件输出流
File file = new File("a.txt");
FileOutputStream out1 = new FileOutputStream(file);
// 2)直接传入一个文件路径,如果该文件不存在则创建
FileOutputStream out2 = new FileOutputStream("D:\\b.txt");
//若下次写入时数据不被覆盖,则添加参数true
FileOutputStream out3 = new FileOutputStream("D:\\c.txt",true);
out1.write(98);
out1.write("Hello World!".getBytes());
//注意:一个汉字占三个字节(平台默认UTF-8编码)
//写入字节数组的一部分 从某个索引开始,写多少个字节
out1.write("爱生活,爱Java".getBytes(),0,9);
//流使用完毕之后,必须释放资源
out1.close();
}
}
不同系统下换行注意:
out1.write("\r\n".getBytes()); //Windows系统换行
out1.write("\n".getBytes()); //Linux系统换行
out1.write("\r".getBytes()); //Mac系统换行
例:流的异常处理
方式一:捕获处理异常
public class MyDemo4 {
public static void main(String[] args) {
FileOutputStream out = null;
try {
out = new FileOutputStream("a.txt");
out.write("java".getBytes());
} catch (IOException e) {
e.printStackTrace();
}finally {
if(out!=null){
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
方式一:向上抛出异常
public class MyDemo5 {
public static void main(String[] args) throws IOException {
FileOutputStream out = new FileOutputStream("a.txt");
out.write("java".getBytes());
out.close();
}
}
输入流
从文件系统中的某个文件中获得输入字节
FileInputStream构造方法:
// FileInputStream 从文件系统中的某个文件中获得输入字节
// FileInputStream(String name)
// 通过打开一个到实际文件的连接来创建一个 FileInputStream,该文件通过文件系统中的路径名 name 指定。
//FileInputStream(File file)
//通过打开一个到实际文件的连接来创建一个 FileInputStream,该文件通过文件系统中的 File 对象 file 指定。
//输入流,所关联的文件如果不存在,就会报错
public class MyDemo6 {
public static void main(String[] args) throws IOException {
FileInputStream in = new FileInputStream("a.txt");
//读取数据方式一: 一次读一个字节,如果读超了则返回-1
in.read();
//读取数据方式二: 一次读一个字节数组 字节数组相当于一个缓冲区
byte[] bytes = new byte[1024];
int len=in.read(bytes);//len返回有效读取长度
//遍历读出的数据
String s = new String(bytes, 0, len);
System.out.println(s);
}
}
例:复制文件
public class MyDemo7 {
public static void main(String[] args) throws IOException {
//方式一:一次读取一个字节,写一个字节来复制,效率低
//方式二:一次读取一个字节数组,写一个字节数组(以下代码采用此种方式)
FileInputStream in = new FileInputStream("a.txt");
FileOutputStream out = new FileOutputStream("b.txt");
//创建一个字节缓冲区
byte[] bytes = new byte[1024];
int len=0;
while ((len=in.read(bytes))!=-1){
out.write(bytes,0,len);
//刷新输出流,使缓存数据被写出来
out.flush();
}
in.close();
out.close();
}
}
例:把这个音乐文件复制两份
public class MyDemo {
public static void main(String[] args) throws IOException {
//把这个音乐文件复制两份
FileInputStream in = new FileInputStream("E:\\我的图片和音乐\\音乐\\烟花易冷Live_林志炫.mp3");
FileOutputStream out1 = new FileOutputStream("D:\\烟花易冷Live_林志炫1.mp3");
FileOutputStream out2 = new FileOutputStream("D:\\烟花易冷Live_林志炫2.mp3");
ArrayList<FileOutputStream> list = new ArrayList<>();
list.add(out1);
list.add(out2);
byte[] bytes = new byte[1024 * 8];
int len = 0;
for (FileOutputStream out : list) {
while ((len = in.read(bytes)) != -1) {
out.write(bytes, 0, len);
out.flush();
}
in= new FileInputStream("E:\\我的图片和音乐\\音乐\\烟花易冷Live_林志炫.mp3");
}
//释放资源
in.close();
out1.close();
out2.close();
}
}
例:高效的输入、出流
BufferedInputStream与BufferedOutputStream
public class MyDemo8 {
public static void main(String[] args) throws IOException {
BufferedInputStream in = new BufferedInputStream(new FileInputStream("a.txt"));
BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream("c.txt"));
byte[] bytes = new byte[1024];
int len = 0;
while ((len = in.read(bytes)) != -1) {
out.write(bytes, 0, len);
out.flush();
}
in.close();
out.close();
}
}
对时间效率差异的解释:
BufferedInputStream比FileInputStream多了一个缓冲区,执行read时先从缓冲区读取,当缓冲区数据读完时再把缓冲区填满。
因此,当每次读取的数据量很小时,FileInputStream每次都是从硬盘读入,而BufferedInputStream大部分是从缓冲区读入。读取内存速度比读取硬盘速度快得多,因此BufferedInputStream效率高。
BufferedInputStream的默认缓冲区大小是8192字节。当每次读取数据量接近或远超这个值时,两者效率就没有明显差别了
字符流:
Writer与Reader
只能读写文本文件
字符流=字节流+编码表
编码:文本=》字节
解码:字节=》文本
public class MyDemo9 {
public static void main(String[] args) {
//编码:
byte[] bytes = "爱生活,爱Java".getBytes();//平台默认编码
for (byte aByte : bytes) {
System.out.println(aByte);
}
//解码:
String str = new String(bytes);
System.out.println(str);
}
}
public class MyDemo9 {
public static void main(String[] args) throws UnsupportedEncodingException {
//指定编码形式,注意编解码要一致
byte[] bytes = "爱生活,爱Java".getBytes("gbk");
String str = new String(bytes, "gbk");
System.out.println(str);
}
}
构造方法:
//创建使用默认字符编码的 OutputStreamWriter
OutputStreamWriter(OutputStream out)
//创建使用给定字符集的 OutputStreamWriter
OutputStreamWriter(OutputStream out, Charset cs)
//创建一个使用默认字符集的 InputStreamReader
//输入流所关联的文件,如果不存在 就会报错
InputStreamReader(InputStream in)
//创建使用给定字符集的 InputStreamReader
InputStreamReader(InputStream in, Charset cs)
例:字符流的文件复制
//方式一:
public class CopyFile {
public static void main(String[] args) throws IOException {
//读取一个字符,写一个字符,来复制文件
InputStreamReader in = new InputStreamReader(new FileInputStream("MyDemo.java"));
OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream("MyDemoCopy.java"));
int len=0;
while ((len=in.read())!=-1){
out.write(len);
out.flush();
}
in.close();
out.close();
}
}
//方式二:
public class CopyFile2 {
public static void main(String[] args) throws IOException {
InputStreamReader in = new InputStreamReader(new FileInputStream("MyDemo.java"));
OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream("MyDemoCopy2.java"));
//创建一个字符缓冲区
char[] chars = new char[100];
int len = 0; //len 是啥意思:记录 你每次读取到的有效的字符个数
while ((len=in.read(chars)) != -1) {
out.write(chars, 0, len);//
out.flush(); //字符流记得刷新一下
}
//释放资源
in.close();
out.close();
}
}
例:高效的字符流
BufferedReader与BufferedWriter
构造方法:
// 创建一个使用默认大小输入缓冲区的缓冲字符输入流
BufferedReader(Reader in)
String readLine () 一次读取一行文本
// 创建一个使用默认大小输出缓冲区的缓冲字符输出流
BufferedWriter(Writer out)
void newLine () 写入一个换行符
//方式一:
public class MyDemo7 {
public static void main(String[] args) throws IOException {
// BufferedReader(Reader in)
// new BufferedReader(new InputStreamReader(""));
BufferedReader in = new BufferedReader(new FileReader("MyDemo5"));
//BufferedWriter(Writer out)
//创建一个使用默认大小输出缓冲区的缓冲字符输出流。
BufferedWriter out = new BufferedWriter(new FileWriter("MyDemo55.java"));
//创建一个字符缓冲区
char[] chars = new char[100]; //
int len = 0; //len 是啥意思:记录 你每次读取到的有效的字符个数
while ((len = in.read(chars)) != -1) {
out.write(chars, 0, len);//
out.flush(); //字符流记得刷新一下
}
//释放资源
in.close();
out.close();
}
}
//方式二:
public class MyDemo2 {
public static void main(String[] args) throws IOException {
//使用高效的字符流,采用读取一行,写入一行的方式来复制文本文件
BufferedReader in = new BufferedReader(new FileReader("MyDemo5"));
//BufferedWriter(Writer out)
//创建一个使用默认大小输出缓冲区的缓冲字符输出流。
BufferedWriter out = new BufferedWriter(new FileWriter("MyDemo56666.java"));
String line=null; //记录每次读取到的一行文本
while ((line=in.readLine())!=null){ //这里注意读取不到返回null
out.write(line);
out.newLine(); //写入一个换行符
out.flush();//刷新
}
//释放资源
out.close();
in.close();
}
}
FileReader与FileWriter类
public class MyDemo {
public static void main(String[] args) throws IOException {
//InputStreamReader in = new InputStreamReader(new FileInputStream("MyDemo.java"));
//OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream("MyDemoCopy2.java"));
// 父类----------------------子类
// InputStreamReader ------- FileReader 便捷类 唯一缺点就是不能指定编码
// OutputStreamWriter ------- FileWriter 便捷类
FileReader in = new FileReader("MyDemo.java");
FileWriter out = new FileWriter(new File("MyDemo5"));
//FileWriter(File file)
//根据给定的 File 对象构造一个 FileWriter 对象。
//
//FileWriter(String fileName)
//根据给定的文件名构造一个 FileWriter 对象。
//创建一个字符缓冲区
char[] chars = new char[100]; //
int len = 0; //len 是啥意思:记录 你每次读取到的有效的字符个数
while ((len = in.read(chars)) != -1) {
out.write(chars, 0, len);
out.flush(); //字符流记得刷新一下
}
//释放资源
in.close();
out.close();
}
}
注意
父类:InputStreamReader 与OutputStreamWriter
||
子类(不能指定编码):FileReader与FileWriter
其它的一些杂七杂八的流
数据输入/出流: DataInputStream与DataOutputStream
public class IODemo {
public static void main(String[] args) throws IOException {
//数据输入数据流:这个流能读写基本数据类型
//怎么写的,怎么读,顺序不要乱
DataInputStream dis = new DataInputStream(new FileInputStream("a.txt"));
boolean b = dis.readBoolean();
double v = dis.readDouble();
char c = dis.readChar();
String s = dis.readUTF();
System.out.println(b);
System.out.println(v);
System.out.println(c);
System.out.println(s);
dis.close();
return;
}
//写方法
private static void writeData() throws IOException {
DataOutputStream dos = new DataOutputStream(new FileOutputStream("a.txt"));
dos.writeBoolean(false);
dos.writeDouble(3.14);
dos.writeChar('A');
dos.writeUTF("陈本豪");
dos.close();
}
}
内存操作流: 不关联文件,所有数据的读写,只在内存中操作,内存流也无须关闭
- 1.操作字节数组
ByteArrayOutputStream
ByteArrayInputStream
public class IODemo2 {
public static void main(String[] args) throws IOException {
//ByteArrayOutputStream
//ByteArrayInputStream
//此流关闭无效,所以无需关闭
ByteArrayOutputStream bos = new ByteArrayOutputStream();
//写入内存操作流的缓冲区里面
bos.write("你好".getBytes());
bos.write("明天".getBytes());
bos.write("未来以来".getBytes());
//取出缓冲区中所有的数据
byte[] allBytes = bos.toByteArray();
String s = new String(allBytes);
System.out.println(s);
//String s = bos.toString(); 把缓存中的数据,转成字符串
//bos.close(); //此流无需关闭
//读取一个字节数组中的数据
ByteArrayInputStream bis = new ByteArrayInputStream(allBytes);
byte[] bytes = new byte[1024];
int len = bis.read(bytes, 0, 6);
System.out.println(new String(bytes,0,len));
}
}
输出:
你好明天未来以来
你好
- 2.操作字符数组
CharArrayWrite
CharArrayReader
public class IODemo3 {
public static void main(String[] args) throws IOException {
//操作字符数组
CharArrayWriter writer = new CharArrayWriter();
writer.write("abc");
writer.write("bbbbb");
writer.write(new char[]{'a','c','你'});
String s = writer.toString();
System.out.println(s);
}
}
输出:
abcbbbbbac你
- 3.操作字符串
StringWriter
StringReader
public class IODemo4 {
public static void main(String[] args) {
//操作字符串
StringWriter writer = new StringWriter();
writer.write("abc");
writer.write("cccc");
writer.write("eeee");
writer.write("boolean");
String s = writer.toString();
System.out.println(s);
}
}
输出:
abccccceeeeboolean
打印流: 不关联源文件,就是不能读取,只能输出
- 1.字节流打印流
创建具有指定文件且不带自动行刷新的新打印流
PrintStream(File file)
public class IODemo {
public static void main(String[] args) throws FileNotFoundException {
//获取字节打印流
//关联屏幕 “标准”输出流。此流已打开并准备接受输出数据。通常,此流对应于显示器输出
PrintStream out2 = new PrintStream(new File("b1.txt")); //关联文件
out2.println(100);
out2.print("abc");
}
}
- 2.字符流打印流
使用指定文件创建不具有自动行刷新的新 PrintWriter
PrintWriter(File file) 字符打印流
public class IODemo2 {
public static void main(String[] args) throws FileNotFoundException {
PrintWriter writer = new PrintWriter(new File("c.txt"));
writer.println("abc");
writer.write("abcddddddd");
writer.println(100);
writer.println(3.14);
writer.flush();//字符流记得刷新
writer.close();
}
}
字符流开启自动刷新:
public class IODemo3 {
public static void main(String[] args) throws FileNotFoundException {
//PrintWriter(OutputStream out, boolean autoFlush)
//通过现有的 OutputStream 创建新的 PrintWriter。
PrintWriter writer = new PrintWriter(new FileOutputStream("e1.txt"), true); //开启自动刷新
//通过以下构造创建对象 能够启动自动刷新 然后调用println、printf 或 format 方法中的一个方法的时候, 会完成自动刷新
writer.println(1001);
writer.close();
}
}
A:
案例演示:
打印流复制文本文件
public class IODemo4 {
public static void main(String[] args) throws IOException {
//找一个能读取的字符流
BufferedReader bfr= new BufferedReader(new FileReader("IODemo.java"));
PrintWriter writer = new PrintWriter(new FileOutputStream("IO.java"),true);
String line=null;
while ((line=bfr.readLine())!=null){
writer.println(line);
}
bfr.close();
writer.close();
}
}
B:
案例演示:
public class IODemo5 {
public static void main(String[] args) throws FileNotFoundException {
//Scanner(File source)
//构造一个新的 Scanner,它生成的值是从指定文件扫描的。
Scanner scanner = new Scanner(new File("IO.java"));
PrintWriter writer = new PrintWriter(new FileOutputStream("IO2.java"), true);
while (scanner.hasNextLine()) {
String s = scanner.nextLine();
writer.println(s);
}
writer.close();
scanner.close();
}
}
public class IODemo {
public static void main(String[] args) throws IOException {
//键盘录入数据
//in 是一个标准的输入流,对应的设备是键盘
//Scanner scanner = new Scanner(System.in);
//InputStream ins= System.in;
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
while (true){
System.out.println("请输入一行数据");
String s = reader.readLine();
//自己定义一个结束标记
if("886".equals(s)){
break;
}
System.out.println(s);
}
}
}
随机访问流RandomAccessFile:
- 最大特点 能读能写
- RandomAccessFile类不属于流,是Object类的子类,但它融合了InputStream和OutputStream的功能,支持对随机访问文件的读取和写入
- 此类的实例支持对随机访问文件的读取和写入,随机访问文件的行为类似存储在文件系统中的一个大型 byte 数组
//参1 你所要关联的文件,参数2 读写模式
RandomAccessFile(File file, String mode)
RandomAccessFile(String name, String mode)
public class MyDemo {
public static void main(String[] args) throws IOException {
RandomAccessFile ra = new RandomAccessFile(new File("f.txt"), "rw");
//ra.writeBoolean(true); //占1字节
//ra.writeDouble(3.14); // 占8字节
//ra.writeInt(100); //占4字节
//ra.writeUTF("你好"); //占6字节
//怎么写的你就怎么读
boolean b = ra.readBoolean();
double v = ra.readDouble();
int i = ra.readInt();
//从这个文件中读取一个字符串
String s = ra.readUTF();
//获取文件指针位置
long pointer = ra.getFilePointer();
System.out.println(pointer);
System.out.println(b);
System.out.println(v);
System.out.println(i);
System.out.println(s);
//设置指针位置
ra.seek(13);
String s1 = ra.readUTF();
System.out.println(s1);
}
}
输出:
21
true
3.14
100
你好
你好
案例:把这个音乐文件复制两份
public class MyDemo {
public static void main(String[] args) throws IOException {
// FileInputStream in = new FileInputStream("E:\\我的图片和音乐\\音乐\\烟花易冷Live_林志炫.mp3");
RandomAccessFile in = new RandomAccessFile(new File("E:\\我的图片和音乐\\音乐\\烟花易冷Live_林志炫.mp3"), "rw");
FileOutputStream out1 = new FileOutputStream("D:\\烟花易冷Live_林志炫1.mp3");
FileOutputStream out2 = new FileOutputStream("D:\\烟花易冷Live_林志炫2.mp3");
ArrayList<FileOutputStream> list = new ArrayList<>();
list.add(out1);
list.add(out2);
byte[] bytes = new byte[1024 * 8];
int len = 0;
for (FileOutputStream out : list) {
while ((len = in.read(bytes)) != -1) {
out.write(bytes, 0, len);
out.flush();
}
//in= new FileInputStream("E:\\我的图片和音乐\\音乐\\烟花易冷Live_林志炫.mp3");
in.seek(0);//设置文件指针位置
}
//释放资源
in.close();
out1.close();
out2.close();
}
}
序列化流与反序列化流: ObjectOutputStream 与 ObjectInputStream
序列化流: 把内存中的数据(对象)存到硬盘中;就是把对象通过流的方式存储到文件中.
注意: 此对象 要重写Serializable 接口才能被序列化
反序列化流: 把硬盘中的数据(对象)读取到内存中;就是把文件中存储的对象以流的方式还原成对象
- 这个对流 最大的特点,能够读写对象
这一对流需要注意以下三个问题:
- 1.要序列化该类对象,要求该类实现一个Serializable 序列化接口
- 2.最好生成一个 private static final long serialVersionUID = 5017795716700497273L;
- 3.transient 不需要将某个成员变量的数据序列化到硬盘上,可以使用这个关键字 来排除他
//将指定的对象写入 ObjectOutputStream
void writeObject (Object obj) 特有的方法
//Serializable 标记接口
//要将一个类的对象,成功序列化到硬盘上,要求此类必须实现一个Serializable 这个标记接口,如果不实现,则无法序列化成功
class Student implements Serializable {
//记着实现完 Serializable 接口 生成一个serialVersionUID
//生成一个序列化ID 确保读写的对象,是同一个对象
private static final long serialVersionUID = 5017795716700497273L;
private String name;
private int age;
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
public class IODemo {
public static void main(String[] args) throws IOException, ClassNotFoundException {
Student student = new Student("张三", 23);
ObjectOutputStream objWriter = new ObjectOutputStream(new FileOutputStream("student.txt"));
objWriter.writeObject(student);
ObjectInputStream objIn = new ObjectInputStream(new FileInputStream("student.txt"));
Student stu = (Student) objIn.readObject();
String name = stu.getName();
int age = stu.getAge();
System.out.println(name);
System.out.println(age);
}
}
输出:
张三
23
public class MyDemo {
public static void main(String[] args) throws Exception {
//写:序列化
Student student = new Student("张三", 23);
Student student2 = new Student("李四", 24);
Student student3 = new Student("王五", 25);
ArrayList<Student> list = new ArrayList<>();
list.add(student);
list.add(student2);
list.add(student3);
ObjectOutputStream objWriter = new ObjectOutputStream(new FileOutputStream("student2.txt"));
objWriter.writeObject(list);
//读:反序列化
ObjectInputStream in = new ObjectInputStream(new FileInputStream("student2.txt"));
ArrayList<Student> list2 = (ArrayList<Student>) in.readObject();
Student student4 = list2.get(2);
System.out.println(student4);
}
}
输出:
Student{name=‘王五’, age=25}
//Serializable 标记接口
//要将一个类的对象,成功序列化到硬盘上,要求此类必须实现一个Serializable 这个标记接口,如果不实现,则无法序列化成功
class Student implements Serializable {
//记着实现完 Serializable 接口 生成一个serialVersionUID
//生成一个序列化ID 确保读写的对象,是同一个对象
private static final long serialVersionUID = 5017795716700497273L;
private String name;
private transient int age; // transient 不需要将age的数据序列化到硬盘上,可以使用这个关键字
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
public class MyDemo3 {
public static void main(String[] args) throws Exception{
//Student student = new Student("赵六", 26);
//ObjectOutputStream objWriter = new ObjectOutputStream(new FileOutputStream("student4.txt"));
//objWriter.writeObject(student);
ObjectInputStream objIn = new ObjectInputStream(new FileInputStream("student4.txt"));
Student stu = (Student) objIn.readObject();
String name = stu.getName();
int age = stu.getAge();
System.out.println(name);
System.out.println(age);
}
}
输出:
赵六
0
集合:Properties
- Properties 继承Hasthtable
- 这个集合键和值的类型,已经规定是 String
public class IODemo {
public static void main(String[] args) {
//集合:属性集合
// Properties 属性集合
// Properties 继承Hasthtable
//这个集合键和值的类型,已经规定是 String
Properties properties = new Properties();
//properties.put("username","zhangsan");
// properties.put("password","123456");
//String username = (String) properties.get("username");
//String password = (String) properties.get("password");
//System.out.println(username);
//System.out.println(password);
//Poperties 他自己特有的存储方法
properties.setProperty("username","zhangsan");
properties.setProperty("password","123456");
//取出数据
String username = properties.getProperty("username");
//参数2 默认值,如果这个键没有找到对应的值,就返回默认值
String pwd = properties.getProperty("password", "654321");
System.out.println(username);
System.out.println(pwd);
}
}
输出:
zhangsan
123456
public class IODemo2 {
public static void main(String[] args) throws IOException {
Properties properties = new Properties();
properties.setProperty("username", "zhangsan");
properties.setProperty("password", "123456");
//可以将集合中的数据保存到文件中去
properties.store(new FileOutputStream("user.properties"),null);
}
}
user.properties文件:
public class IODemo3 {
public static void main(String[] args) throws IOException {
//假如我有了一个文本文件,数据是这种键和值的数据 键值是用等号连接的
//HashMap<String, String> hm = new HashMap<>();
//BufferedReader bfr = new BufferedReader(new FileReader("user.properties"));
//String one = bfr.readLine();
//String[] strings = one.split("=");
//hm.put(strings[0],strings[1]);
//String two = bfr.readLine();
//String[] strings2 = two.split("=");
//hm.put(strings2[0], strings2[1]);
//System.out.println(hm);
Properties properties = new Properties();
properties.load(new FileReader("user.properties"));
System.out.println(properties);
String username = properties.getProperty("username");
System.out.println(username);
String passwrod = properties.getProperty("passwrod", "123");
System.out.println(username);
System.out.println(passwrod);
}
}
A:
案例演示
需求:我有一个文本文件,我知道数据是键值对形式的,但是不知道内容是什么。
请写一个程序判断是否有“lisi”这样的键存在,如果有就改变其值为”100”
public class IODemo4 {
public static void main(String[] args) throws IOException {
Properties properties = new Properties();
properties.load(new FileReader("student.txt"));
//判断这个键存不存在
if (properties.containsKey("lisi")) {
properties.setProperty("lisi", "100");//键相同,值覆盖
}
properties.store(new FileOutputStream("student.txt"), null);
}
}
B:
案例需求:
将a.txt和b.txt两个文本文件的内容合并到c.txt
public class MyTest {
public static void main(String[] args) throws IOException {
File a = new File("a.txt");
File b = new File("b.txt");
File c = new File("c.txt");
FileInputStream in1 = new FileInputStream(a);
FileInputStream in2 = new FileInputStream(b);
FileOutputStream out = new FileOutputStream(c);
ArrayList<FileInputStream> list = new ArrayList<>();
list.add(in1);
list.add(in2);
//遍历集合 写数据
int len = 0;
byte[] bytes = new byte[1024];
for (FileInputStream in : list) {
while ((len = in.read(bytes)) != -1) {
out.write(bytes, 0, len);
out.flush();
}
in.close();
}
out.close();
}
}
SequenceInputStream流
SequenceInputStream: 表示其他输入流的逻辑串联。它从输入流的有序集合开始,并从第一个输入流开始读取,直到到达文件末尾,接着从第二个输入流读取,依次类推,直到到达包含的最后一个输入流的文件末尾为止。
//通过记住这两个参数来初始化新创建的 SequenceInputStream(将按顺序读取这两个参数,先读取 s1,然后读取 s2)
SequenceInputStream(InputStream s1, InputStream s2)
public class MyTest2 {
public static void main(String[] args) throws IOException {
File a = new File("a.txt");
File b = new File("b.txt");
File c = new File("c.txt");
FileInputStream in1 = new FileInputStream(a);
FileInputStream in2 = new FileInputStream(b);
//创建一个顺序流,传入两个输入流
SequenceInputStream in = new SequenceInputStream(in1, in2);
FileOutputStream out = new FileOutputStream(c);
int len = 0;
byte[] bytes = new byte[1024];
while ((len = in.read(bytes)) != -1) {
out.write(bytes, 0, len);
out.flush();
}
in.close();
in1.close();
in2.close();
out.close();
}
}
A:
案例需求:
将三个文件中的内容,合并到一个文件中
用顺序流做
public class MyTest3 {
public static void main(String[] args) throws IOException {
//将三个文件中的内容,合并到一个文件中
File a = new File("a.txt");
File b = new File("b.txt");
File c = new File("c.txt");
FileInputStream in1 = new FileInputStream(a);
FileInputStream in2 = new FileInputStream(b);
FileInputStream in3 = new FileInputStream(c);
//用顺序流做
SequenceInputStream in4 = new SequenceInputStream(in1, in2);
SequenceInputStream in5 = new SequenceInputStream(in4, in3);
}
}
C:
案例需求:
将一个music.mp3文件, 拆分成多个小文件, 再将多个小文件, 合并成一个mp3文件
mp3 4.5M 一份拆成 1M 总共拆分五份 最后一份是0.5M
最后将5份 再合成一份
public class MyTest5 {
public static void main(String[] args) throws IOException {
// 1. 先封装源文件
File file1 = new File("E:\\music");
File[] files = file1.listFiles();
Vector<FileInputStream> v = new Vector<>();
for (File f : files) {
if (f.isFile() && f.getName().endsWith(".mp3")) {
FileInputStream in = new FileInputStream(f);
v.add(in);
}
}
SequenceInputStream sin = new SequenceInputStream(v.elements());
byte[] bytes = new byte[1024 * 1024];
int len = 0;
FileOutputStream out = new FileOutputStream("E:\\夜夜夜夜-齐秦.mp3");
while ((len = sin.read(bytes)) != -1) {
out.write(bytes, 0, len);
out.flush();
}
sin.close();
out.close();
return;
}
private static void chaifen() throws IOException {
File file = new File("夜夜夜夜.mp3");
//2.封装一个文件夹
File file1 = new File("E:\\music");
if (!file1.exists()) {
file1.mkdirs();
}
FileInputStream in = new FileInputStream(file);
//拆分文件
byte[] bytes = new byte[1024 * 1024];
int len = 0;
int i = 1;
while ((len = in.read(bytes)) != -1) {
FileOutputStream out = new FileOutputStream(new File(file1, (i++) + ".mp3"));
out.write(bytes, 0, len);
out.close();
}
in.close();
}
}