其他流

转换流

作用:

  • 实现字节流到字符流的转换
  • 解决中文乱码的问题

中文编码:

  • gb2312 (采用两个字节保存字符汉字,英文数字一个字节)
  • GBK (采用两个字节保存字符汉字,英文数字一个字节)
  • GB18030 (英文数字都是一个字节,中文是两个或四个字节)
  • Unicode字符集(包含每个国家的所有字符)国际通用
  • unicode编码 使用两个字节—65536个字符,浪费空间
  • 为了节省空间使用转码形式
  • utf-8 使用 1 、2、3个字节
  • (EF BB BF 记事本添加的BOM(Byte Order Mark)头,编码的标记)
  • utf-16 使用两个字节—65536个字符 (FF FE 小端(尾) FE FF 大端(尾))
  • utf-32 使用4个字节
  • 台湾 big5
  • ANSI:在简体中文Windows操作系统中, ANSI 编码代表 GBK 编码
  • 只有转换流才能指定读取和写入的字符集

InputStreamReader类

  • InputStreamReader:字节字符转换输入流,将字节输入流转换为字符输入流
  • 注意:当一个流的存在的意义是为了实例化另外一个流,则这个流不需要手动进行关闭
  //使用默认的字符集【GBK】进行实例化转换流
  InputStreamReader reader1 = new InputStreamReader(new FileInputStream(new File("file/input1.txt")));
  //使用指定字符集进行实例化转换流
  //字符集一般使用字符串直接传参,不区分大小写,但是,如果字符集书写有误的话,则会跑出java.io.UnsupportedEncodingException
 InputStreamReader reader2 = new InputStreamReader(new FileInputStream(new File("file/input1.txt")),"UTF-8");
 //3.读取
 char[] arr = new char[16];
 int len = 0;
 while((len = reader.read(arr)) != -1) {
      String string = new String(arr, 0, len);
      System.out.println(string);
 }
 reader.close();

OutputStreamWriter类

  • OutputStreamWriter:字符转换输出流,将内存中的字符转成字节保存到硬盘中。
//注意:对于所有的输出流而言,文件可以不存在,在进行写入的过程中可以自动进行创建
//但是,对于所有的输入流而言,文件必须先存在,然后才能操作,否则,会抛出FileNotFounedException
//如果不想覆盖源文件中的内容时,则在传参的时候,设置一个参数为true
OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(file,true), "utf-8");
//3.写入
writer.write("变秃了,也变强了");
//4.刷新
writer.flush();
//5.关闭
writer.close();

缓冲流

作用

  • 主要是为了增强基础流的功能而存在的,提高了流的工作效率【读写效率】
  • 该流自己创建一个缓存区域保存数据。读数据时先读到缓存区,再读到硬盘中。写数据也是如此
  • 注意:如果使用记事本创建的文件,文件是utf-8或者unicode编码,文件的前面有一个BOM(Byte Order Mark)头
  • BOM作用指定文件使用的编码类型。GBK编码没有添加bom头。
  • utf-8:EF BB BF
  • unicode 小端: FF FE 66 00
  • unicode 大端:FE FF 00 66

BufferedInputStream类

BufferedInputStream bis = new BufferedInputStream(new FileInputStream("tt.txt"));
byte[] arr = new byte[8];
int len = 0;
while ((len=bis.read(arr))!=-1){
   String str = new String(arr,0,len);
   System.out.println(str);
}
bis.close();

BufferedOutputStream类

//如果不想覆盖源文件中的内容时,则在传参的时候,设置一个参数为true
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("tt.txt",true));
bos.write("努力".getBytes());
bos.flush();
bos.close();

BufferedReader类

BufferedReader br = new BufferedReader(new >FileReader("tt.txt"));
//读取一行
String str = br.readLine();
System.out.println(str);

BufferedWriter类

BufferedWriter bw = new BufferedWriter(new FileWriter("tt.txt",true));
bw.write("\r\n努力");
// 作用:主要就是为了换行
bw.newLine();
bw.flush();
bw.close();

内存流

作用

  • 输入和输出都是从文件中来的,当然,也可将输出输入的位置设置在内存上,这就需要ByteArrayInputStreamByteArrayOutputStream
  • ByteArrayInputStream:将内容写入到内存中,是Inputstream的子类
  • ByteArrayOutputStream:将内存中数据输出,是OutputStream的子类
  • 此时的操作应该以内存为操作点
  • 注意:内存操作流的操作对象,一定是以内存为主准,不要以硬盘为准。
  • 完成一个字母大小写转换的程序:
//定义一个字符串,全部由大写字母组成
String string = "HELLOWORLD";
//内存输入流
//向内存中输出内容,注意:跟文件读取不一样,不设置文件路径
ByteArrayInputStream bis  = new ByteArrayInputStream(string.getBytes());
//内存输出流
//准备从内存中读取内容,注意:跟文件读取不一样,不设置文件路径
ByteArrayOutputStream bos = new ByteArrayOutputStream();
int temp = 0;
//read()方法每次只读取一个字符
while((temp = bis.read()) != -1) {
  //将读取的数字转为字符
  char c = (char)temp;
  //将字符变为大写
  bos.write(Character.toLowerCase(c));
}
//循环结束之后,所有的数据都在ByteArrayOutputStream中
//取出内容,将缓冲区内容转换为字符串
String newString = bos.toString();
//关闭流
bis.close();
bos.close();
System.out.println(newString);

标准输入输出流

  • Java的标准输入/输出分别通过System.in和System.out实现,默认情况下分别代表是键盘和显示器
  • PrintStream类:PrintStream为其他输出流添加了功能,使它们能够方便地打印各种数据值表示形式。
  • PrintWriter类:向文本输出流打印对象的格式化表示形式。此类实现在 PrintStream中的所有 print方法。它不包含用于写入原始字节的方法。
  //PrintStream ps = new PrintStream("tt.txt");
  PrintWriter pw = new PrintWriter("tt.txt");
  pw.println(true);
  pw.println(3.14);
  pw.println(100);
  pw.println("奋斗123");
  pw.flush();
  pw.close();
//注意:默认打印到控制台,但是,如果采用setOut方法进行重定向之后,将输出到指定的文件中
PrintStream print = new PrintStream(new FileOutputStream(new File("test33.txt")));
/*static void setErr(PrintStream err) 
重新分配“标准”错误输出流。 
static void setIn(InputStream in) 
重新分配“标准”输入流。 
static void setOut(PrintStream out) 
重新分配“标准”输出流。 */
//将标准输出重定向到print的输出流
System.setOut(print);
System.out.println("hello world");
FileInputStream inputStream = new FileInputStream(new File("test33.txt"));
//setIn
System.setIn(inputStream);
//System.out.println("请输入内容:");
//默认情况下是从控制台进行获取内容
//但是如果使用setIn方法设置了重定向之后,将从指定文件中获取内容
Scanner sc = new Scanner(System.in);
String string = sc.next();
System.out.println(string);

对象流

流中流动的数据是对象

  • 将一个对象写入到本地文件中,被称为对象的序列化
  • 将一个本地文件中的对象读取出来,被称为对象的反序列化

使用对象流

  • ObjectInputStream: 对象输出流
  • ObjectOutputStream:对象输入流

注意:

  • 序列化对象的类型必须实现Serializable接口。否则不能序列化。
  • 如果向将多个对象序列化到本地,可以借助于集合,【思路:将多个对象添加到集合中,将集合的对象写入到本地文件中,再次读出来,获取到的仍然是集合对象,遍历集合】。
  • 对象中那些字段可以不序列化:
    • transient 修饰属性,被修饰的属性无法序列化
    • 静态的字段
    • 在要序列化类中添加字段,保证序列化和反序列化是同一个类
    • private static final long serialVersionUID = 100L;
      注意:在使用对象流的时候,用于初始化对象流的参数只能是字节流(将对象转换为二进制的形式,然后再把二进制写入文件)
//user对象必须实现序列化,否则报错
User user = new User(1,"sdh");
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(new File("tt.txt")));
oos.writeObject(user);
oos.flush();
oos.close();
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(new File("tt.txt")));
User user = (User) ois.readObject();
System.out.println(user);

RandomAccessFile类

  • RandomAccessFile是用来访问那些保存数据记录的文件的,你就可以用seek()方法来访问记录,并进行读写了。这些记录的大小不必相同;但是其大小和位置必须是可知的。但是该类仅限于操作文件。
RandomAccessFile file = new RandomAccessFile("file.txt", "rw");
// 以下向file文件中写数据
file.writeInt(20);// 占4个字节
file.writeDouble(8.236598);// 占8个字节
//这个长度写在当前文件指针的前两个字节处,可用readShort()读取
file.writeUTF("这是一个UTF字符串");
//把文件指针位置设置到文件起始处,从0开始
file.seek(0);
//将文件指针跳过3个字节,从当前位置
//file.skipBytes(3);
System.out.println(file.readInt());
System.out.println(file.readDouble());
System.out.println(file.readUTF());
//注意readDouble()方法会移动文件指针,所以不用写2。
//file.skipBytes(file.readDouble()); 
/* 文件复制案例 */
RandomAccessFile fileCopy = new RandomAccessFile("fileCopy.txt", "rw");
int len = (int) file.length();// 取得文件长度(字节数)
byte[] b = new byte[len];
//全部读取
file.readFully(b);
fileCopy.write(b);
System.out.println("复制完成!");

Properties类

  • 这个其实是一个集合,放着这里是为了通过io流来学习它的使用
  • Map接口的一个实现类,并且是Hashtable的子类
  • Properties集合中元素也是以键值对的形式存在的
  • Properties特点:
    1. 存储属性名和属性值
    2. 属性名和属性值都是字符串
    3. 和流有关系
    4. 没有泛型
Properties properties = new Properties();
//设置键、值
properties.setProperty("name","xxx");
Set<String> strings = properties.stringPropertyNames();
for (String key : strings) {
    System.out.println(key+"  "+properties.getProperty(key));
}
//把上面信息填充到该文件中
properties.list(new PrintStream("prop.properties"));
//list也可以打印,输出到控制台,不保存到文件中
properties.list(System.out);
//去该文件中加载内容,打印出来
properties.load(new FileReader("prop.properties"));
properties.list(System.out);
//保存到该文件中
properties.store(new FileWriter("prop.properties"),"xxx");
//读取系统信息
Properties properties1 = System.getProperties();
properties1.list(System.out);


转载请注明:Memory的博客 » 点击阅读原文

打赏一个呗

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦