JavaAndroid知识Java学习笔记

Java文件IO常用归纳

2017-01-15  本文已影响226人  androidjp

我们常说的标准IO操作,包含了本篇所述的文件IO。我们知道,IO无非是输入输出,数据在动的时候以流形式存在(Byte or Bit 为单位),而在静的时候则以文件形式存在(因为我们知道文件就是若干Byte等单位的数据或数据集合)。

前言:关于文件的编码


  1. 在windows 下,eclipse等IDE的默认项目编码是GBKGBK编码:中文占用2byte,英文占用1byte。
  2. utf-8编码中:中文占用3byte,英文占用1byte。
  3. 如何把单个字节转换为int以16进制的方式显示:
String ch = "A";
byte[] bytes = ch.getBytes();
System.out.println(Integer.toHexString(bytes[0] & 0xff));///为了将变成int类型后(8bit->32bit)的值,除去前30位的值,只留下最低2位。
  1. Java是双字节编码(utf-16be),utf-16be编码:中文和英文都占用2byte。
  2. Java中字符串与字节序列之间的转换示例:
String str = "你好1234";
byte[] bytes = str.getBytes("utf-16be");
String str2 = new String(bytes, "utf-16be");
  1. 文本文件(.txt)就是字节序列(可以是任意编码的字节序列)
  2. 中文机器上(比如我们的PC)直接创建文本文件,那么该文件只认识ansi编码
  3. 创建的Java项目设定是utf-8编码,那么, 它创建的文本文件编码格式就是utf-8编码。将此文本文件拷贝到其他不是utf-8编码的项目目录下,就会乱码。但是将此文本文件拷贝到我们PC的任何其他目录下,都不会有乱码。(注意是拷贝,不是新建,这是由于:文本文件本身就是识别任意编码格式的字节序列)

Java IO示例与注意点


(一)File类

  1. 创建/获取文件对象,使用File.separator分隔符:
File file = new File("E:\\test");///一般windows下用(双斜杠)
//File file0 = new File("e:\\", "diary.txt");
File file2 = new File("E:/test");///一般linux和macos下用(反斜杠)
File file3 = new File("E:" + File.separator +"test");///系统间通用
  1. 创建的文件对象是一个多级目录时,需要File.mkdirs()而不是File.mkdir()
if(!file.exists())
    file.mkdirs();
  1. 打印File.toString(),默认打印文件的目录:
System.out.println(file);/// output: e://test

(二)文件读写IO

  1. 关于RandomAccessFile:RandomAccessFile类支持随机访问文件并可以访问文件的任意位置:read()write()就是这个类的其他方法的基础原理。
RandomAccessFile raf = new RandomAccessFile(file, "rw");//两个模式:rw表示读写,r表示只读。
raf.write(int);//只写一个字节(后8位),同时指针后移一个位置,准备再次写入。
int b = raf.read();//读一个字节
int max = 0x7ffffff;
raf.write(max>>>24);//最高8位
raf.write(max>>>16);//8位
raf.write(max>>>8);//8位
raf.write(max);///最低8位
  1. IO流基础

(三)对象读写 与 序列化

  1. 序列化:Object转byte序列的过程。
  2. 序列化流:ObjectOutputStream/ObjectInputStream,对于方法:writeObject()、readObject()
  3. JVM在对象内部调用的默认序列化方法:
///成员方法writeObject()
public void writeObject(ObjectOutputStream s) throws IOException{
  s.defaultWriteObject();
}
  1. 如果想要自己做某个元素的序列化操作:
public void writeObject(ObjectOutputStream s) throws IOException{
  s.defaultWriteObject();
  s.writeInt(age);///如这个age变量,就被我们自行序列化写入了
}
  1. Serializable接口是一个标准,是序列化的前提。
  2. transient关键字:被标注的成员不会被jvm进行默认序列化。【有时可以提高性能】
  3. ArrayList内部维护着Object[]类型的数组对象,这个对象是被transient修饰的,但是ArrayList并不是不想进行序列化操作,而是想自己去实现序列化的方式而不去给JVM默认进行序列化,这样一来即可提高效率。
  4. 序列化时:一个类实现了Serializable接口,其子类都能够被需序列化。
  5. 反序列化时:对子类对象进行反序列化,如果其父类没有实现Serializable接口,则其父类的构造方法会被调用。
上一篇下一篇

猜你喜欢

热点阅读