TwentyTwoDay-java File的常用方法、序列化与反序列化、 创建线程

1、java.io.File的常用方法

public static void main(String[] args) {
  //创建一个File对象
  File file=new File("D:\\word文档/file01");
  //判断文件是否存在
  System.out.println(file.exists());//false 不存在
  //若不存在,以文件形式新建一个
  /*if(!file.exists()){
      try {
          file.createNewFile();
      } catch (IOException e) {
          e.printStackTrace();
      }
  }
    */
  //若不存在,以目录形式新建
  /*if(!file.exists()){
      file.mkdir();
  }*/
  //新建多重目录
  File file1=new File("D:\\word文档/file01/A/B");
  if(!file1.exists()){
      file1.mkdirs();

  }
  //获取父文件的路径 返回String类型
  String parentPath=file1.getParent();
  System.out.println(parentPath);//D:\word文档\file01\A
  //获取父文件的路径,返回File类型
  File parentP=file1.getParentFile();
  System.out.println(parentP);//D:\word文档\file01\A
  //获取父文件的绝对路径
  System.out.println(parentP.getAbsolutePath());//D:\word文档\file01\A
  //获取文件的绝对路径
  System.out.println(file1.getAbsolutePath());//D:\word文档\file01\A\B
  //获取文件名
  System.out.println("文件名:"+file1.getName());//文件名:B
  //判断是不是一个文件
  System.out.println(file1.isFile());//false
  //判断是不是一个目录
  System.out.println(file1.isDirectory());//true
  //获取最后一次的修改时间
  long l = file1.lastModified();//返回的是从1970年到现在的毫秒数
  Date date=new Date(l);//转化成日期
  SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd hh:mm:ss SSS");//格式化日期
  String dateTime = sdf.format(date);
  System.out.println(dateTime);//2021-07-14 09:42:06 545
  //获取文件大小
  System.out.println(file1.length());//0 没放东西


}

*File类的File[] listFiles() 方法 返回当前目录下的所有子文件

public static void main(String[] args) {
  File file=new File("D:/word文档");
  File[] files = file.listFiles();
  //遍历输出file里的子文件名
  for (File file1 : files) {
      System.out.println(file1.getAbsolutePath());
  }
}

2、序列化与反序列化

序列化serialize java对象存储到文件中,将Java对象的状态保存下来的过程(ObjectOutputStream)

反序列化Deserialize 将硬盘上的数据重新恢复到内存当中,恢复成Java对象(ObjectInputStream)

需要序列化与反序列化的对象必须实现Serializable接口 这个接口是一个标志性接口,无任何方法和属性,不然会报NotSerializableException错,不支持序列化

这个接口的作用? 起到标识的作用,java虚拟机看到这个类实现了这个接口,可能会对这个类进行特殊待遇。会对这个类自动形成一个序列化版本号

//student类

public class student implements Serializable  {

      int sno;
      String sName;

      public student(int sno, String sName) {
          this.sno = sno;
          this.sName = sName;
      }

      public int getSno() {
          return sno;
      }

      public void setSno(int sno) {
          this.sno = sno;
      }

      public String getsName() {
          return sName;
      }

      public void setsName(String sName) {
          this.sName = sName;
      }

      @Override
      public String toString() {
          return "student{" +
                  "sno=" + sno +
                  ", sName='" + sName + '\'' +
                  '}';
      }
  }

//序列化student

public static void main(String[] args) throws Exception {
  student stu=new student(18010,"zhangsan");
  ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("student"));
  //序列化
  oos.writeObject(stu);
  oos.flush();
  oos.close();
}

序列化结果 生成一个保存student对象的文件

//反序列化student

public static void main(String[] args) throws Exception {
  ObjectInputStream ois=new ObjectInputStream(new FileInputStream("student"));
  //反序列化
  Object o = ois.readObject();
  //调用student的toString方法
  System.out.println(o);
  ois.close();
}

反序列运行结果

student{sno=18010, sName='zhangsan'}

3、序列化多个对象

//User类

public class User implements Serializable {
  int uno;
  String name;

  public User(int uno, String name) {
      this.uno = uno;
      this.name = name;
  }

  public int getUno() {
      return uno;
  }

  public void setUno(int uno) {
      this.uno = uno;
  }

  public String getName() {
      return name;
  }

  public void setName(String name) {
      this.name = name;
  }

  @Override
  public String toString() {
      return "User{" +
              "uno=" + uno +
              ", name='" + name + '\'' +
              '}';
  }
}

//序列化User

以把多个对象放进一个List集合中,序列化集合 注意:User与List集合都必须实现java.io.Serializable

public static void main(String[] args) throws Exception {
  List<User> Users=new ArrayList<>();
  //把User对象放进List集合中
  Users.add(new User(12,"mary"));
  Users.add(new User(13,"jack"));
  Users.add(new User(14,"dawei"));
  ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("user"));
  oos.writeObject(Users);

  oos.flush();
  oos.close();

}

运行结果 生成保存User对象的文件

//反序列化User

public static void main(String[] args) throws Exception{
      ObjectInputStream ois=new ObjectInputStream(new FileInputStream("user"));
      Object o = ois.readObject();
//       System.out.println(o instanceof List); true
      List<User> UserList=(List<User>)o;
      for (User user : UserList) {
          System.out.println(user);
      }
      ois.close();
  }

运行结果

User{uno=12, name='mary'}

User{uno=13, name='jack'}

User{uno=14, name='dawei'}

注意:有一个transient关键字,表示游离的,不参与序列化(transient int uno;)反序列化后运行结果为 User{uno=0, name='mary'}

 

4、序列化版本号的用途?

java语言中采用什么机制来区分类的?

第一:首先对比类名,类名不一样,就是两个类

第二:类名一样,则通过序列化版本号进行比较

当有两个类名相同的类,都实现了Serializable接口,则在编译的时候,两个类有不同的序列化版本号(这是序列化版本号的优点)

缺点:一旦代码确定后,不能进行后续修改,只要修改,必然重新编译,此时会生成一个新的序列化版本号。

综上所述:序列化版本号需要固定不变,故手写!如在student类里加上”private static final long serialVersionUID = 7826354836987L;“

 

5、IO+Properties的联合使用

设计理念: 经常改变的数据,可以单独写到一个文件里,使用程序动态读取

将来只需要改变文件的内容,java代码不需要改变,不需要重新编译,服务器也不需要重新启动

类似于这样的文件称为配置文件。

当配置文件内容格式为:

key1=123

key2=890 的时候,我们把这种配置文件叫做属性配置文件

java规范中有要求:属性配置文件建议以.properties结尾,但是不必须。

Properties是专门存放属性配置文件内容的一个类

public static void main(String[] args) throws Exception {
  /*
  把文件tempfile02里的数据传入Map集合
    */
  //创建一个输入流对象
  FileReader file=new FileReader("java基础语法/tempfile02");
  //创建一个集合
  Properties properties=new Properties();
  properties.load(file);
  String user = properties.getProperty("user");
  System.out.println(user);//root
}

6、线程的理解

进程:就是一个应用程序(两个进程内存独立不共享)

线程就是一个进程中的执行场景/执行单元(两个线程堆内存和方法区共享,栈内存独立,一个线程一个栈,多线程并发机制,目的提高程序的处理效率 )

思考:使用多线程机制,main方法结束,是不是有可能程序不会结束。

main结束只是主线程结束,其它栈并未结束。

多线程并发:线程之间互不影响,各自执行各自的。

对于单核的cpu来说,可以做到多线程并发吗?不能够,但是可以做到给人一种多线程并发的感觉。其实它是多个线程频繁切换执行的,速度很快,但在某一时间点只能处理一件事情。

 

7、线程状态图(图为b站老师所画)

 

 

 

8、实现线程的第一种方式:

编写一个类,直接继承Thread,重写run()方法

怎样创建线程对象?new线程 

怎样启动线程? 调用线程对象的start()方法

//编写一个MyThread类

class MyThread extends Thread{
  @Override
  public void run() {
      //编写程序,这段程序运行在分支栈中
      for (int i = 0; i < 100; i++) {
          System.out.println("分支线程-->"+i);
      }
  }
}

//线程的创建

public static void main(String[] args) {
  //新建一个分支线程对象
  MyThread myTread=new MyThread();
  //若直接调用run方法:myTread.run(),则没有开辟新的栈空间只有一个主线程(这种方式就是单线程)
  //启动分支线程
  myTread.start();//作用:在Jvm中开辟一个新的栈空间,任务完成之后,瞬间结束,启动成功后自动调用run方法
  //run与main方法都在底部,run在分支栈底部,main在主栈底部
  //主线程代码运行
  for(int i=0;i<100;i++){
      System.out.println("主线程--》"+i);
  }

}

9、第二种方式

编写一个类实现java.lang.Runnable接口

接口的方式比继承的方式好,因为实现了接口还能继承其他的类

//创建一个MyRunnable类

class MyRunnable implements Runnable{

  @Override
  public void run() {
      for (int i = 0; i < 100; i++) {
          System.out.println("分支线程-->"+i);
  }
}
}

//线程的实现

public static void main(String[] args) {
  /* //创建一个可运行的对象
  MyRunnable myRunnable=new MyRunnable();
  //把可运行对象封装为线程对象
  Thread tread=new Thread(myRunnable);
  把两行合并
  */
  Thread thread=new Thread(new MyRunnable());
  //启动分支线程
  thread.start();
  for(int i=0;i<100;i++){
      System.out.println("主线程--》"+i);
  }

}

注:可以用内部类的方式

public static void main(String[] args) {
  Thread t=new Thread(new Runnable() {
      @Override
      public void run() {
          for (int i = 0; i < 100; i++) {
              System.out.println("分支"+i);
          }
      }
  });
  t.start();
  for (int i = 0; i < 100; i++) {
      System.out.println("主线程"+i);
  }
}

10、

1>、怎样获取当前线程对象? 使用static Thread currentThread()静态方法

2>、获取线程对象的名字 :String name=t.getName();

3>、修改线程对象的名字:t.setName("修改后的名字");

4>、当线程没有设置名字的时候 默认 Thread-0,Thread-1...

//创建MyThread类

class MyThread extends Thread{
  @Override
  public void run() {
      //获取当前线程
      Thread currentThread=Thread.currentThread();
      System.out.println("当前线程的名字:"+currentThread.getName());//当前线程的名字:t
  }
}

//线程的实现

public static void main(String[] args) {
    //获取当前线程的名字(当前线程在现在是主线程)
    Thread currentThread=Thread.currentThread();
    System.out.println(currentThread.getName());//main
    MyThread myThread=new MyThread();
    //修改线程的名字
    myThread.setName("t");
    //获取线程的名字
    String name=myThread.getName();
    System.out.println(name);//t
    myThread.start();
}
posted @ 2021-07-15 17:40  别不开心,过得去  阅读(64)  评论(0)    收藏  举报