学习Java之day27

1.对象流的使用

1.ObjectInputStream和ObjectOutputStream 2.作用:用于存储和读取基本数据类型的数据和对象的处理流。它的强大之处就是可以把java中的对象写入到数据源中,也能把对象从数据源中还原回来。 3.要想一个java对象是可序列化的,需要满足相应的条件,见Person.java 4.序列化机制: 对象序列化机制允许把内存中的Java对象转换成平台无关的二进制流,从而允许把这种 二进制流持久地保存在磁盘上,或通过网络将这种二进制流传输到另一个网络节点。 当其它程序获取了这种二进制流,就可以恢复成原来的Java对象。

 

 

/*
Person需要满足以下的要求,才可以进行序列化
1.需要实现接口:实现Serializable
2.当前类提供一个全局常量:serialVersionUID
3.除了当前类需要实现Serializabel接口外,还必须保证其内部所有属性也必须是可序列化的
       (默认情况下,基本数据类型可序列化)


补充:ObjectOutputStream和ObjectInputStream不能序列化static和transient修饰的成员变量
*/
public class Person implements Serializable {
   private int id;
   private int age;
   private String name;

   private Account account;

   public Person(String name, int age) {
       this.name = name;
       this.age = age;
  }

   @Override
   public String toString() {
       return "Person{" +
               "id=" + id +
               ", age=" + age +
               ", name='" + name + '\'' +
               ", account=" + account +
               '}';
  }

   private static final long serialVersionUID = 989439L;

   public Person(){}

   public Person(int id,int age, String name) {
       this.id = id;
       this.age = age;
       this.name = name;
  }

   public Person(String name,int age,int id,   Account account) {
       this.id = id;
       this.age = age;
       this.name = name;
       this.account = account;
  }
}


class Account  implements Serializable {
   public static final long serialVersionUID = 4754534532L;
   private double balance;

   @Override
   public String toString() {
       return "Account{" +
               "balance=" + balance +
               '}';
  }

   public double getBalance() {
       return balance;
  }

   public void setBalance(double balance) {
       this.balance = balance;
  }

   public Account(double balance) {

       this.balance = balance;
  }
}

2.Files工具类的使用:操作文件或目录的工具类

  @Test
   public void test1() throws IOException{
       Path path1 = Paths.get("d:\\nio", "hello.txt");
       Path path2 = Paths.get("bao.txt");

// Path copy(Path src, Path dest, CopyOption … how) : 文件的复制
       //要想复制成功,要求path1对应的物理上的文件存在。path1对应的文件没有要求。
// Files.copy(path1, path2, StandardCopyOption.REPLACE_EXISTING);

// Path createDirectory(Path path, FileAttribute<?> … attr) : 创建一个目录
       //要想执行成功,要求path对应的物理上的文件目录不存在。一旦存在,抛出异常。
       Path path3 = Paths.get("d:\\nio\\nio1");
// Files.createDirectory(path3);

// Path createFile(Path path, FileAttribute<?> … arr) : 创建一个文件
       //要想执行成功,要求path对应的物理上的文件不存在。一旦存在,抛出异常。
       Path path4 = Paths.get("d:\\nio\\hi.txt");
// Files.createFile(path4);

// void delete(Path path) : 删除一个文件/目录,如果不存在,执行报错
// Files.delete(path4);

// void deleteIfExists(Path path) : Path对应的文件/目录如果存在,执行删除.如果不存在,正常执行结束
       Files.deleteIfExists(path3);

// Path move(Path src, Path dest, CopyOption…how) : 将 src 移动到 dest 位置
       //要想执行成功,src对应的物理上的文件需要存在,dest对应的文件没有要求。
// Files.move(path1, path2, StandardCopyOption.ATOMIC_MOVE);

// long size(Path path) : 返回 path 指定文件的大小
       long size = Files.size(path2);
       System.out.println(size);

  }

   @Test
   public void test2() throws IOException{
       Path path1 = Paths.get("d:\\nio", "hello.txt");
       Path path2 = Paths.get("atguigu.txt");
// boolean exists(Path path, LinkOption … opts) : 判断文件是否存在
       System.out.println(Files.exists(path2, LinkOption.NOFOLLOW_LINKS));

// boolean isDirectory(Path path, LinkOption … opts) : 判断是否是目录
       //不要求此path对应的物理文件存在。
       System.out.println(Files.isDirectory(path1, LinkOption.NOFOLLOW_LINKS));

// boolean isRegularFile(Path path, LinkOption … opts) : 判断是否是文件

// boolean isHidden(Path path) : 判断是否是隐藏文件
       //要求此path对应的物理上的文件需要存在。才可判断是否隐藏。否则,抛异常。
// System.out.println(Files.isHidden(path1));

// boolean isReadable(Path path) : 判断文件是否可读
       System.out.println(Files.isReadable(path1));
// boolean isWritable(Path path) : 判断文件是否可写
       System.out.println(Files.isWritable(path1));
// boolean notExists(Path path, LinkOption … opts) : 判断文件是否不存在
       System.out.println(Files.notExists(path1, LinkOption.NOFOLLOW_LINKS));
  }

   /**
    * StandardOpenOption.READ:表示对应的Channel是可读的。
    * StandardOpenOption.WRITE:表示对应的Channel是可写的。
    * StandardOpenOption.CREATE:如果要写出的文件不存在,则创建。如果存在,忽略
    * StandardOpenOption.CREATE_NEW:如果要写出的文件不存在,则创建。如果存在,抛异常
    *
    * @author shkstart 邮箱:shkstart@126.com
    * @throws IOException
    */
   @Test
   public void test3() throws IOException {
       Path path1 = Paths.get("d:\\nio", "hello.txt");

// InputStream newInputStream(Path path, OpenOption…how):获取 InputStream 对象
       InputStream inputStream = Files.newInputStream(path1, StandardOpenOption.READ);

// OutputStream newOutputStream(Path path, OpenOption…how) : 获取 OutputStream 对象
       OutputStream outputStream = Files.newOutputStream(path1, StandardOpenOption.WRITE,StandardOpenOption.CREATE);


// SeekableByteChannel newByteChannel(Path path, OpenOption…how) : 获取与指定文件的连接,how 指定打开方式。
       SeekableByteChannel channel = Files.newByteChannel(path1, StandardOpenOption.READ,StandardOpenOption.WRITE,StandardOpenOption.CREATE);

// DirectoryStream<Path> newDirectoryStream(Path path) : 打开 path 指定的目录
       Path path2 = Paths.get("e:\\teach");
       DirectoryStream<Path> directoryStream = Files.newDirectoryStream(path2);
       Iterator<Path> iterator = directoryStream.iterator();
       while(iterator.hasNext()){
           System.out.println(iterator.next());
      }


  }

3.RandomAccessFile的使用

1.RandomAccessFile直接继承于java.lang.Object类,实现了DataInput和DataOutput接口

  • 2.RandomAccessFile既可以作为一个输入流,又可以作为一个输出流 *

  • 3.如果RandomAccessFile作为输出流时,写出到的文件如果不存在,则在执行过程中自动创建。

  • 如果写出到的文件存在,则会对原有文件内容进行覆盖。(默认情况下,从头覆盖) *

    1. 可以通过相关的操作,实现RandomAccessFile“插入”数据的效果

 @Test
   public void test1() {

       RandomAccessFile raf1 = null;
       RandomAccessFile raf2 = null;
       try {
           //1.
           raf1 = new RandomAccessFile(new File("爱情与友情.jpg"),"r");
           raf2 = new RandomAccessFile(new File("爱情与友情1.jpg"),"rw");
           //2.
           byte[] buffer = new byte[1024];
           int len;
           while((len = raf1.read(buffer)) != -1){
               raf2.write(buffer,0,len);
          }
      } catch (IOException e) {
           e.printStackTrace();
      } finally {
           //3.
           if(raf1 != null){
               try {
                   raf1.close();
              } catch (IOException e) {
                   e.printStackTrace();
              }

          }
           if(raf2 != null){
               try {
                   raf2.close();
              } catch (IOException e) {
                   e.printStackTrace();
              }

          }
      }
  }

   @Test
   public void test2() throws IOException {

       RandomAccessFile raf1 = new RandomAccessFile("hello.txt","rw");

       raf1.seek(3);//将指针调到角标为3的位置
       raf1.write("xyz".getBytes());//

       raf1.close();

  }
   /*
   使用RandomAccessFile实现数据的插入效果
    */
   @Test
   public void test3() throws IOException {

       RandomAccessFile raf1 = new RandomAccessFile("hello.txt","rw");

       raf1.seek(3);//将指针调到角标为3的位置
       //保存指针3后面的所有数据到StringBuilder中
       StringBuilder builder = new StringBuilder((int) new File("hello.txt").length());
       byte[] buffer = new byte[20];
       int len;
       while((len = raf1.read(buffer)) != -1){
           builder.append(new String(buffer,0,len)) ;
      }
       //调回指针,写入“xyz”
       raf1.seek(3);
       raf1.write("xyz".getBytes());

       //将StringBuilder中的数据写入到文件中
       raf1.write(builder.toString().getBytes());

       raf1.close();

       //思考:将StringBuilder替换为ByteArrayOutputStream
  }

4.网络编程

一、网络编程中有两个主要的问题:

  • 1.如何准确地定位网络上一台或多台主机;定位主机上的特定的应用

  • 2.找到主机后如何可靠高效地进行数据传输 *

  • 二、网络编程中的两个要素:

  • 1.对应问题一:IP和端口号

  • 2.对应问题二:提供网络通信协议:TCP/IP参考模型(应用层、传输层、网络层、物理+数据链路层) * *

  • 三、通信要素一:IP和端口号 *

    1. IP:唯一的标识 Internet 上的计算机(通信实体)

    1. 在Java中使用InetAddress类代表IP

    1. IP分类:IPv4 和 IPv6 ; 万维网 和 局域网

    1. 域名: www.baidu.com www.mi.com www.sina.com www.jd.com

  • www.vip.com

    1. 本地回路地址:127.0.0.1 对应着:localhost *

    1. 如何实例化InetAddress:两个方法:getByName(String host) 、 getLocalHost()

  • 两个常用方法:getHostName() / getHostAddress() *

    1. 端口号:正在计算机上运行的进程。

  • 要求:不同的进程有不同的端口号

  • 范围:被规定为一个 16 位的整数 0~65535。 *

    1. 端口号与IP地址的组合得出一个网络套接字:Socket

    2.  

上一篇:我的SFTP配置


下一篇:Windows10中安装Java JDK配置Tomcat10