一、File
一、编解码
- GBK 2个字节转换成UTF-8 3个字节,再转换成GBK,乱码。
- 编解码时可指定编解码方式:
public static void main(String[] args) throws UnsupportedEncodingException {
String s = new String("123今天上课了了");
byte[] s1 = s.getBytes();
System.out.println(Arrays.toString(s1));
String s2 = new String(s1, "UTF-8");
System.out.println(s2);
String s4 = new String(s1,"GBK");
System.out.println(s4);
byte[] s5 = s4.getBytes("GBK");
String s6 = new String(s5);
System.out.println(s6);
System.out.println("\nGBK2个字节转换成UTF-8 3个字节,再转换成GBK,乱码");
byte[] s3 = s.getBytes("GBK");
System.out.println(Arrays.toString(s3));
String s7 = new String(s3,"UTF-8");
System.out.println(s7);
byte[] s8 = s7.getBytes();
String s9 = new String(s8,"GBK");
System.out.println(s9);
}
二、File类及相关方法
1.构造方法及常用方法;
public static void main(String[] args) throws IOException {
File f = new File("src/Pointer/File/aa.txt");
if(!f.exists()){
f.createNewFile();//创建
}
boolean a = f.isFile();
boolean b = f.isDirectory();
System.out.println(a + " " + b);
File f1 = new File("bb\\cc\\dd");
if (!f1.exists()){
f1.mkdirs();//创建由此抽象路径名命名的目录,包括任何必需但不存在的父目录。
}
long l = f.length();//文件长度(大小)
String s = f.getAbsolutePath();//获取绝对地址
String n = f.getName();//文件名
System.out.println(l);
System.out.println(s);
System.out.println(n);
long l1 = f.lastModified();//最近一次的修改时间,返回的时long类型的毫秒值
Date d = new Date(l1);
DateFormat d1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String s2 = d1.format(d);
System.out.println(n + "的最近修改时间为:" + s2);
Calendar c = Calendar.getInstance();
c.setTimeInMillis(l1);
Date d2 = c.getTime();//返回Date类型
System.out.println("Calendar实现:"+d1.format(d2));
}
- 删除操作;
System.out.println("以下是删除操作:--------");
//System.out.println("delete删除文件或者空目录,不可逆:" + f.delete());
File f2 = new File("bb");
del(f2);
public static void del(File f){//递归删除文件夹
File[] file = f.listFiles();
for(File ff : file){
if (ff.isDirectory()){
if (ff.listFiles() != null) {
del(ff);
}
}
ff.delete();
}
f.delete();
}
- listFiles及其过滤器;
//FileFilter()
File f3 = new File("src/Set");
File[] file1 = f3.listFiles(new FileFilter() {
@Override
public boolean accept(File f) {
boolean b = f.isFile();
boolean c = !f.getName().endsWith(".java");//保留.java文件
return b&&c;
}
});
for(File ff : file1){
ff.delete();
}
// FilenameFilter()
File[] file2 = f3.listFiles(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
File f = new File(dir,name);//创建文件
boolean c = f.getName().endsWith(".java");
return c;
}
});
for(File ff : file2){
ff.delete();
}
二、IO流
输入流 | 输出流 |
---|---|
Input | Output |
字节流 | 字符流 |
---|---|
InputStream OutputStream | Reader Writer |
FileInputStream FileOutputSttream | FileReader FileWriter |
BufferedInputStream BufferedOutputStream | BufferedReader BufferedWriter |
一、PrintWriter
常用方法就不过多描写了,主要讲PrintWriter及其相关的输入输出类。
PrintWriter 可以指定字符集,也可以自动刷新,那么怎样实现二者兼备,同时支持文件末尾添加数据呢?
引入OutputStreamWriter 和 InputStreamReader 类
FileOutputSttream | true -> 可在文件末尾添加 |
---|---|
OutputStreamWriter | “GBK” -> 指定字符集 |
PrintWriter | true -> println自动刷新 |
FileInputStream | |
---|---|
InputStreamReader | “GBK” -> 指定字符集 |
BufferedReader |
代码如下:
public static void main(String[] args) throws IOException {
File f = new File("src/Pointer/File/IO/a.txt");
//PrintWriter pw = new PrintWriter(f,"GBK");
//pw.println("中国YYDS");
//pw.flush();
/*FileOutputStream fos = new FileOutputStream(f,true);//文尾添加
PrintWriter pw1 = new PrintWriter(fos,true);//自动刷新
pw1.println("今天回家吃饭吗,宝贝");
pw1.close();
fos.close();*/
FileOutputStream fos1 = new FileOutputStream(f,true);
OutputStreamWriter osw = new OutputStreamWriter(fos1,"GBK");//指定字符集
PrintWriter pw2 = new PrintWriter(osw,true);
pw2.println("嘭");
pw2.print(100000);
pw2.close();
osw.close();;
fos1.close();
FileInputStream fis = new FileInputStream(f);
InputStreamReader isr = new InputStreamReader(fis,"GBK");//指定字符集
BufferedReader br = new BufferedReader(isr);
String s;
while ((s = br.readLine()) != null){
System.out.println(s);
}
isr.close();
fis.close();
}
三、对象序列化
序列化操作
- ⼀个对象要想序列化,必须满⾜两个条件:
该类必须实现 java.io.Serializable 接⼝, Serializable 是⼀个标记接⼝,不实现此接⼝的类将不会使任何状态序列化或反序列化,会抛出 NotSerializableException 。
该类的所有属性必须是可序列化的。如果有⼀个属性不需要可序列化的,则该属性必须注明是瞬态的,使⽤ transient 关键字修饰。
public class Employee implements java.io.Serializable {
public String name;
public String address;
public transient int age; // transient瞬态修饰成员,不会被序列化
public void addressCheck() {
System.out.println("Address check : " + name + " -- " + address);
}
}
ObjectOutputStream 和 ObjectInputStream
将对象作为流存入文件
public static void main(String[] args) throws ParseException, IOException, ClassNotFoundException {
Date d1 = new Date();
DateFormat df = new SimpleDateFormat("yy-MM-dd");
String s = "2006-02-15";
d1 = df.parse(s);
Emp p = new Emp("张三",25,"男",5000,d1);
FileOutputStream fos = new FileOutputStream("src/Pointer/File/IO/emp.dat");
ObjectOutputStream oot = new ObjectOutputStream(fos);
oot.writeObject(p);
FileInputStream fis = new FileInputStream("src/Pointer/File/IO/emp.dat");
ObjectInputStream ois = new ObjectInputStream(fis);
Emp pp = (Emp) ois.readObject();
System.out.println(pp);
}
反序列化操作2
另外,当JVM反序列化对象时,能找到class⽂件,但是class⽂件在序列化对象之后发⽣了修改,那么反序列化操作也会失败,抛出⼀个 InvalidClassException InvalidClassException 异常。发⽣这个异常的原因如下:
- 该类的序列版本号与从流中读取的类描述符的版本号不匹配
- 该类包含未知数据类型
- 该类没有可访问的⽆参数构造⽅法
Serializable 接⼝给需要序列化的类,提供了⼀个序列版本号。 serialVersionUID 该版本号的⽬的在于验证序列化的对象和对应类是否版本匹配。
public class Employee implements java.io.Serializable {
// 加⼊序列版本号
private static final long serialVersionUID = 1L;
public String name;
public String address;
// 添加新的属性 ,重新编译, 可以反序列化,该属性赋为默认值.
public int eid;
public void addressCheck() {
System.out.println("Address check : " + name + " -- " + address);
}
}