做网站免费搭建,企业网站建设主要类型及选择,莱芜在线人才网,wordpress我爱水煮鱼io流#xff1a;存储和读取数据的解决方案
I:input O:output
io流的作用#xff1a;用于读写数据#xff08;本地文件,网络#xff09;
io流按照流向可以分为#xff1a;
输出流#xff1a;程序-文件
输入流#xff1a;文件-程序
io流按照操作文件…io流存储和读取数据的解决方案
I:input O:output
io流的作用用于读写数据本地文件,网络
io流按照流向可以分为
输出流程序-文件
输入流文件-程序
io流按照操作文件的类型可分类为
字节流可以操作所有类型的文件
字符流只能操作纯文本文件能用电脑自带记事本打开并且能读懂的文件 File表示系统中的文件或者文件夹的路径
获取文件信息大小文件名修改时间 判断文件的类型
创建文件/文件夹 删除文件/文件夹
注意File类只能对文件本身进行操作不能读写文件里面存储的数据 字节流
FileOutputStream
操作本地文件的字节输出流可以把程序中的数据写在本地文件中
步骤
1.创建字节输出流对象
2.写数据
3.释放资源 FileOutputStream原理
通过创建对象 传入路径 使程序和文件产生数据传输通道 FileOutputStream fos new FileOutputStream(D:\\ideaProject\\study\\AdvancedJava3\\src\\itemIO\\a.txt);
通过调用write方法写入数据
fos.write(97);
调用close方法释放资源断开程序和文件之间的连接 fos.close(); FileOutputStream书写细节
创建字节输出流对象
细节1参数可以是字符串表示的路径或者是File对象
细节2如果文件不存在会创建一个新的文件但是要保证父级路径是存在的
细节3如果文件已经存在则会清空文件
写出数据
细节write方法的参数是整数但是实际上写到本地文件中的是整数在ASCII上对应的字符
释放资源
每次使用完流之后都要释放资源 FileOutputStream写数据的3种方式 一次写一个字节数组数据
public class ByteStreamDemo2 {public static void main(String[] args) throws IOException {FileOutputStream fos new FileOutputStream(D:\\ideaProject\\study\\AdvancedJava3\\src\\itemIO\\a.txt);//一次写一个字节数组数据byte[] bytes {97,98,99,100,101,102};//调用write方法将数组写入文件fos.write(bytes);//释放资源fos.close();}
}
一次写一个字节数组的部分数据
public class ByteStreamDemo3 {public static void main(String[] args) throws IOException {FileOutputStream fos new FileOutputStream(D:\\ideaProject\\study\\AdvancedJava3\\src\\itemIO\\a.txt);/*void write(byte[] b,int off,int len)参数一数组 参数二起始索引 参数三个数一次写一个字节数组的部分数据*/byte[] bytes {97,98,99,100,101,102};//调用write方法将数组写入文件fos.write(bytes,2,2); //cd//释放资源fos.close();}
}
FileOutputStream写数据的两个小问题
换行写
public class ByteStreamDemo4 {public static void main(String[] args) throws IOException {/*换行写写出一个换行符Windows: \r\nLinux: \nMac: \r*/FileOutputStream fos new FileOutputStream(D:\\ideaProject\\study\\AdvancedJava3\\src\\itemIO\\a.txt);//写出数据 huluyazhenshuaiString str huluyazhenshuai;//调用getBytes方法把字符串变成字节数组byte[] bytes str.getBytes();
// System.out.println(Arrays.toString(bytes));/*变成字节数组[104, 117, 108, 117, 121, 97, 122, 104, 101, 110, 115, 104, 117, 97, 105]*///调用write方法写入数据fos.write(bytes);String str2 \r\n; //写出换行符fos.write(str2.getBytes());String str3 666;fos.write(str3.getBytes());/*文件中的数据huluyazhenshuai666*///释放资源fos.close();}
}
续写
如果想要续写打开续写开关即可
开关位置创建对象的第二个参数
默认false表示续写此时创建对象就可以清空文件
手动传递true表示打开续写此时创建对象不会清空文件 FileOutputStream fos new FileOutputStream(D:\\ideaProject\\study\\AdvancedJava3\\src\\itemIO\\a.txt,true);
FileOutputStream小结
作用可以把程序中的数据写到本地文件中是字节流的基本流
书写步骤创建对象 写出数据 释放资源
三步操作的细节
创建对象 文件存在清空文件 文件不存在创建文件 追加写入true
写出数据写出整数 写出字节数组 换行写
释放资源关闭通道 字节输入流的基本用法
FileInputStream
操作本地文件的字节输入流可以把本地文件中的数据读取到程序中来
书写步骤
1.创建对象
2.读数据
3.释放资源 FileInputStream书写细节
1.创建对象
细节1如果文件不存在就直接报错
2.读数据
细节1一次读一个字节读出来的是数据在ASCII上对应的数字
细节2读到文件末尾read方法返回-1
3.释放资源 FileInputStream循环读取
public class FileInputStreamDemo2 {public static void main(String[] args) throws IOException {//字节输入流循环读取FileInputStream fis new FileInputStream(D:\\ideaProject\\study\\AdvancedJava3\\src\\itemIO\\a.txt);//循环读取int b;while ((b fis.read()) ! -1) { //read:表示读取数据 并且读取一次数据就会移动一次指针System.out.println((char) b);}//释放资源fis.close();}
} 文件拷贝
public class FileInputStreamDemo3 {public static void main(String[] args) throws IOException {/*练习:文件拷贝*///创建对象FileInputStream fis new FileInputStream(D:\\ideaProject\\study\\AdvancedJava3\\src\\itemIO\\a.txt);FileOutputStream fos new FileOutputStream(D:\\ideaProject\\study\\AdvancedJava3\\src\\itemIO\\copy.txt);//拷贝 边读边写int b;while ((b fis.read()) ! -1){ fos.write(b);}//释放资源fos.close();fis.close();}
} FileInputStream读取的问题
一次读写一个字节 public class FileInputStreamDemo4 {public static void main(String[] args) throws IOException {//一次读一个字节数组数据//创建对象FileInputStream fis new FileInputStream(D:\\ideaProject\\study\\AdvancedJava3\\src\\itemIO\\a.txt);//创建数组//表示一次读两个数据byte [] bytes new byte[2];//返回值len表示本次读取到了多少个字节数据int len1 fis.read(bytes);System.out.println(len1); //2String str1 new String(bytes,0,len1);System.out.println(str1);int len2 fis.read(bytes);System.out.println(len2); //2String str2 new String(bytes,0,len2);System.out.println(str2);int len3 fis.read(bytes);System.out.println(len3); //1String str3 new String(bytes,0,len3);System.out.println(str3);fis.close();}
}
GBK和Unicode GBK在GBK字符集中每个中文字符占据两个字节。 UnicodeUnicode字符集中在UTF-8字符集中中文字符通常占用3个字节的空间。UTF-8是一种可变长度的编码方案用于表示Unicode字符集中的字符。对于常见的汉字UTF-8编码通常占用3个字节但对于罕见的汉字也可能会占用更多的字节。
public class CharSetDemo1 {public static void main(String[] args) throws UnsupportedEncodingException {/*java中编码的方法public byte[] getBytes() 默认方式进行编码public byte[] getBytes(String charsetName) 指定方式进行编码java中解码的方法String (byte[] bytes) 默认方式进行解码String (byte[] bytes,String charsetName) 指定方式进行解码*///1.编码String str1 ai你哟;byte[] bytes1 str1.getBytes();System.out.println(Arrays.toString(bytes1)); //[97, 105, -28, -67, -96, -27, -109, -97]byte[] bytes2 str1.getBytes(GBK);System.out.println(Arrays.toString(bytes2)); //[97, 105, -60, -29, -45, -76]//解码String str2 new String(bytes1);System.out.println(str2); //ai你哟String str3 new String(bytes1,GBK);System.out.println(str3); //ai浣犲摕}
} 字符流
FileReader
import java.io.FileReader;
import java.io.IOException;/*** author hyk~*/
public class FileReaderDemo1 {public static void main(String[] args) throws IOException {//创建对象并关联本地文件FileReader fr new FileReader(D:\\ideaProject\\study\\AdvancedJava3\\src\\itemIO\\a.txt);//读取数据read()//字符流的底层也是字节流默认也是一个字节一个字节的读取//但是遇到中文会一次读多个字节 GBK读2个 utf-8读3个int ch;while((ch fr.read()) ! -1){System.out.print((char) ch);/*read () 细节:1.read():默认也是一个字节一个字节的读取的,如果遇到中文就会一次读取多个2.在读取之后方法的底层还会进行解码并转成十进制。最终把这个十进制作为返回值 这个十进制的数据也表示在字符集上的数字英文: 文件里面二进制数据 0110 0001read方法进行读取解码并转成十进制97中文: 文件里面的二进制数据 11100110 10110001 1001001read方法进行读取解码并转成十进制27721如果想看到中文汉字就把这些十进制数据再进行强转就可以了 (char) ch*/}//释放资源fr.close();}
}
FileWriter
1.创建字符输出流对象
细节1参数是字符串表示的路径或者File对象都是可以的
细节2如果文件不存在会创建一个新的文件但是要保证父级路径是存在的
细节3如果文件已存在则会清空文件如果不想清空可以打开续写开
2.写数据
细节如果write方法的参数是整数但是实际上写到本地文件中的是整数在字符集上对应的字符
3.释放资源
细节每次使用完流后都要释放资源
public class FileReaderDemo3 {public static void main(String[] args) throws IOException {FileWriter fw new FileWriter(D:\\ideaProject\\study\\AdvancedJava3\\src\\itemIO\\a.txt);fw.write(大家好我是学生);fw.close();}
} 字节流和字符流使用场景
字节流
拷贝任意类型的文件
package itemIO;import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;/*** author hyk~*/
public class Test1 {public static void main(String[] args) throws IOException {//拷贝一个文件夹考虑子文件夹//创建对象表示数据源File src new File(D:\\ideaProject\\src);//创建对象表示目的地File dest new File(D:\\ideaProject\\src10086);//调用方法开始拷贝copyDir(src,dest);}/*作用拷贝文件夹参数一数据源参数二目的地*/private static void copyDir(File src, File dest) throws IOException {dest.mkdirs();//递归//进入数据源File[] files src.listFiles();//遍历数组for (File file : files) {//判断文件拷贝if (file.isFile()) {FileInputStream fis new FileInputStream(file);//要拷贝的文件FileOutputStream fos new FileOutputStream(new File(dest,file.getName()));//文件目的地byte[] bytes new byte[1024];int len;while ((len fis.read(bytes)) ! -1) {fos.write(bytes, 0, len);//bytes数组中从0索引开始一共len个元素拷贝}fos.close();fis.close();}else {//判断文件夹递归copyDir(file,new File(dest,file.getName())); //要拷贝的文件夹目的地}}}
}文件加密
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;/*** author hyk~*/
public class Test2 {/*为了保证文件的安全性就需要对原始文件进行加密存储再使用的时候再对其进行解密处理加密原理:对原始文件中的每一个字节数据进行更改然后将更改以后的数据存储到新的文件中解密原理:读取加密之后的文件按照加密的规则反向操作变成原始文件*/public static void main(String[] args) throws IOException {//创建对象关联原始文件FileInputStream fis new FileInputStream(D:\\ideaProject\\study\\AdvancedJava3\\src\\itemIO\\1.png);//创建对象关联加密文件FileOutputStream fos new FileOutputStream(D:\\ideaProject\\study\\AdvancedJava3\\src\\itemIO\\ency.png);//加密处理int b;while((b fis.read()) ! -1){fos.write(b ^ 10);}fos.close();fis.close();}
}
解密操作 修改文件中的数据
package itemIO;import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;/*** author hyk~*/
public class Test3 {/*文本文件中有以下的数据:2-1-9-4-7-8将文件中的数据进行排序变成以下的数据:1-2-4-7-8-9*/public static void main(String[] args) throws IOException {//读取数据FileReader fr new FileReader(D:\\ideaProject\\study\\AdvancedJava3\\src\\itemIO\\a.txt);StringBuilder sb new StringBuilder();int ch;while((ch fr.read()) ! -1){sb.append((char) ch);}fr.close();//排序String str sb.toString();String [] arr str.split(-);ArrayList list new ArrayList();for (String s : arr) {int i Integer.parseInt(s);list.add(i);}Collections.sort(list);//写出FileWriter fw new FileWriter(D:\\ideaProject\\study\\AdvancedJava3\\src\\itemIO\\a.txt);for (int i 0; i list.size(); i){if (i list.size() -1){fw.write(list.get(i) );}else {fw.write(list.get(i)-);}}fw.close();}
}字节缓冲流
import java.io.*;/*** author hyk~*/
public class BufferedStreamDemo2 {public static void main(String[] args) throws IOException {/*需求:利用字节缓冲流拷贝文件字节缓冲输入流的构造方法:public BufferedInputStream(Inputstream is)字节缓冲输出流的构造方法:public BufferedOutputstream(Outputstream os)*///创建缓冲流的对象BufferedInputStream bis new BufferedInputStream(new FileInputStream(D:\\ideaProject\\study\\AdvancedJava3\\src\\itemIO\\a.txt));BufferedOutputStream bos new BufferedOutputStream(new FileOutputStream(D:\\ideaProject\\study\\AdvancedJava3\\src\\itemIO\\copy.txt));//拷贝 一次读写多个字节byte[] bytes new byte[1024];int len;while ((len bis.read(bytes))! -1){bos.write(bytes,0,len);}bos.close();bis.close();}
} 字符缓冲流
public class BufferedStreamDemo3 {public static void main(String[] args) throws IOException {/*字符缓冲输入流:构造方法:public BufferedReader(Reader r)特有方法:public String readLine()读一整行*///创建字符缓冲流的对象BufferedReader br new BufferedReader(new FileReader(D:\\ideaProject\\study\\AdvancedJava3\\src\\itemIO\\a.txt));//读取数据String line;while (((line br.readLine()) ! null)){System.out.println(line);}//释放资源br.close();}
} 字符流
读取纯文本文件中的数据
往纯文本文件中写出数据 转换流
转换流主要有两种类型InputStreamReader 和 OutputStreamWriter。
它们的作用是在字节流和字符流之间建立桥梁使得字节流能够以字符流的形式被读取或者字符流能够以字节流的形式被写入。
创建转换流
1. 创建 InputStreamReader
FileInputStream fis new FileInputStream(input.txt); // 创建字节输入流
InputStreamReader isr new InputStreamReader(fis); // 创建转换流2. 创建 OutputStreamWriter
FileOutputStream fos new FileOutputStream(output.txt); // 创建字节输出流
OutputStreamWriter osw new OutputStreamWriter(fos); // 创建转换流在创建转换流时你可以选择是否指定字符集。如果不指定字符集将会使用系统默认的字符集。例如可以这样指定字符集
InputStreamReader isr new InputStreamReader(fis, UTF-8); // 指定字符集为UTF-8
OutputStreamWriter osw new OutputStreamWriter(fos, UTF-8); // 指定字符集为UTF-8使用转换流
1. 使用 InputStreamReader 读取文件内容
BufferedReader br new BufferedReader(isr); // 创建缓冲字符流
String line;
while ((line br.readLine()) ! null) {System.out.println(line); // 输出每一行内容
}2. 使用 OutputStreamWriter 写入数据
BufferedWriter bw new BufferedWriter(osw); // 创建缓冲字符流
bw.write(Hello, world!); // 写入字符串
bw.newLine(); // 写入换行符
bw.close(); // 关闭流序列化流 序列化流在Java中是用来将对象转换为字节流的一种方式。主要用于对象的持久化存储或网络传输。Java提供了两种序列化流ObjectOutputStream 用于将对象写入到流中ObjectInputStream 用于从流中读取对象。
创建序列化流
1. 创建 ObjectOutputStream
FileOutputStream fos new FileOutputStream(object.dat); // 创建字节输出流
ObjectOutputStream oos new ObjectOutputStream(fos); // 创建序列化流2. 创建 ObjectInputStream
FileInputStream fis new FileInputStream(object.dat); // 创建字节输入流
ObjectInputStream ois new ObjectInputStream(fis); // 创建反序列化流
使用序列化流
1. 使用 ObjectOutputStream 写入对象
MyObject obj new MyObject(); // 创建一个自定义对象
oos.writeObject(obj); // 将对象写入流中2. 使用 ObjectInputStream 读取对象
MyObject obj (MyObject) ois.readObject(); // 从流中读取对象并进行类型转换注意事项
被写入流中的对象必须实现 Serializable 接口否则会抛出 java.io.NotSerializableException 异常。对象中的静态变量不会被序列化因为静态变量属于类而不是对象。有时候需要对某些敏感信息进行序列化时可以使用 transient 关键字来标记不需要序列化的字段。序列化的版本号可以通过 serialVersionUID 显式声明以控制序列化对象的版本。
import java.io.*;class MyObject implements Serializable {private static final long serialVersionUID 1L;private String name;public MyObject(String name) {this.name name;}public String getName() {return name;}
}public class Main {public static void main(String[] args) {try {// 创建对象输出流FileOutputStream fos new FileOutputStream(object.dat);ObjectOutputStream oos new ObjectOutputStream(fos);// 写入对象MyObject obj1 new MyObject(Object 1);oos.writeObject(obj1);// 关闭对象输出流oos.close();// 创建对象输入流FileInputStream fis new FileInputStream(object.dat);ObjectInputStream ois new ObjectInputStream(fis);// 读取对象MyObject obj2 (MyObject) ois.readObject();System.out.println(Name: obj2.getName());// 关闭对象输入流ois.close();} catch (IOException | ClassNotFoundException e) {e.printStackTrace();}}
}这段代码演示了如何创建和使用序列化流来序列化和反序列化对象。请确保在处理异常时进行适当的处理比如打印错误信息或者进行其他的异常处理操作。