美文网首页
Java高级- IO流

Java高级- IO流

作者: ttiga | 来源:发表于2021-05-17 10:12 被阅读0次

13.1.File类的使用

File类的使用
1.File类的一个对象,代表一个文件或一个文件目录(俗称: 文件夹)
2.File类声明在java.io包下
3.File类中涉及到关于文件或文件目录的创建,删除,重命名,修改时间,文件大小等方法,
并未涉及到写入或读取文件内容的操作.若需要读取或写入文件内容,必须用IO流来完成.
4.后续File类的对象常会作为参数传递到流的构造器中,指明读取或写入的"终点"(:从哪读或写入到哪,或叫节点,这个点就用File来表示),真的要读写内容了,File类的对象主要指的是一个文件就不是文件目录了

  • File类的实例化

1.如何创建File类的实例
File(String filePath)
File(String filePath, String childPath)
File(File parentFile, String childPath)
2.相对路径: 相较于某个路径下,指明的路径
绝对路径: 包含盘符在内的文件或文件目录的路径
3.路径分隔符:
windows: \
unix: /

@Test
    public void test1(){
        // 构造器1
        File file1 = new File("hello.txt");// 路径相对于当前module
        File file2 = new File("F:\\markdown\\JavaSE\\基础语法\\src\\com\\JavaSenior\\IO\\he.txt");// 第二条斜杠表示避免转义的意思
        // 这里还这是单元测试现在还不需要对应硬盘中的文件,此时就仅仅只是内存层面的对象,还没有涉及到对文件中的数据的操作,现在就理解为内存层面对象而已
        System.out.println(file1);
        System.out.println(file2);
        // 构造器2,在上一层目录下指定的可以是文件也可以是文件目录
        File file3 = new File("F:\\markdown\\JavaSE\\基础语法\\src\\com","JavaSenior");// 上一层目录和下一层目录
        System.out.println(file3);
        // 构造器3: 在file3的目下创建的文件
        File file4 = new File(file3, "hi.txt");
        System.out.println(file4);
    }
  • File类的常用方法
// File类的常用方法
    @Test
    public void test2(){
        File file1 = new File("hello.txt");
        File file2 = new File("F:\\markdown\\IO\\hi.txt");
        // 获取绝对路径
        System.out.println(file1.getAbsolutePath());
        // 获取路径
        System.out.println(file1.getPath());
        //获取名字
        System.out.println(file1.getName());
        // 获取上层文件目录路径,若无返回null
        System.out.println(file1.getParent());
        // 获取文件长度(大小)(即:字节数).不能获取目录长度
        System.out.println(file1.length());
        // 获取最后一次修改时间,毫秒值
        System.out.println(new Date(file1.lastModified()));
        System.out.println();
        System.out.println(file2.getAbsolutePath());
        System.out.println(file2.getPath());
        System.out.println(file2.getName());
        System.out.println(file2.getParent());
        System.out.println(file2.length());
        System.out.println(file2.lastModified());
    }
    // 如下的两个方法适用于文件目录:
    //public String[] list(): 获取指定目录下的所有文件或文件目录的名称数组
    // public File[] listFiles(): 获取指定模流下的所有文件或文件目录的File数组
    @Test
    public void test3(){
        File file = new File("F:\\markdown\\JavaSE");
        String[] list = file.list();// 获取下一层目录或文件
        for (String s : list) {
            System.out.println(s);
        }
        File[] files = file.listFiles();// 以绝对路径方式获取下一层文件或目录
        for (File f : files) {
            System.out.println(f);
        }
    }
    /*
    public boolean renamTo(File dest): 把文件移动到指定文件路径并重命名
    比如: file1.renameTo(file2)为例:
    要想保证返回true,要file1在硬盘中是存在的,且file2不能在硬盘中存在
     */
    @Test
    public void test4(){
        File file1 = new File("hello.txt");
        File file2 = new File("F:\\markdown\\IO\\hi.txt");
        boolean renameTo = file1.renameTo(file2);
        System.out.println(renameTo);
    }
    @Test
    public void test5(){
        File file1 = new File("hello.txt");
        System.out.println(file1.isDirectory());//是否为文件目录
        System.out.println(file1.isFile());// 是否为文件
        System.out.println(file1.exists());//是否真正在硬盘中存在
        System.out.println(file1.canRead());//是否可读
        System.out.println(file1.canWrite());//是否可写
        System.out.println(file1.isHidden());//是否隐藏
        // 判断文件呢目录
        File file2 = new File("F:\\markdown\\IO");
        System.out.println(file2.isDirectory());
        System.out.println(file2.isFile());
        System.out.println(file2.exists());
        System.out.println(file2.canRead());
        System.out.println(file2.canWrite());
        System.out.println(file2.isHidden());
    }
    @Test
    public void test6() throws IOException {
        File file1 = new File("hi.txt");
        // 如果不存在
        if (!file1.exists()) {
            // 创建文件.若文件真实存在硬盘中,则不创建,返回false
            file1.createNewFile();
            System.out.println("创建成功");
        }else{// 文件存在
            // 删除磁盘中的文件或文件目录,java中的删除不走回收站
            file1.delete();
            System.out.println("删除成功");
        }
    }
    @Test
    public void test7(){
        // 文件目录(夹)的创建
        File file1 = new File("F:\\markdown\\IO\\IO1\\IO3");// 上一层目录存在
        // 创建文件目录.如果此文件目录存在,就不创建了.如果此文件目录的上层目录不存在,也不创建
        boolean mkdir = file1.mkdir();
        if (mkdir) {
            System.out.println("创建成功1");
        }
        File file2 = new File("F:\\markdown\\IO\\IO1\\IO4");
        // 创建文件目录,若上层文件目录不存在,一并创建
        boolean mkdirs = file2.mkdirs();
        if (mkdirs) {
            System.out.println("创建成功2");
        }
        // 文件删除,要想成功,欲删除的文件目录下不能有子目录或文件
        File file3 = new File("F:\\markdown\\IO\\IO1\\IO3");
        System.out.println(file3.delete());
    }

File类的练习

public class FileDemo {
    // 在
    @Test
    public void test1() throws IOException {
        // 创建一个与file同目录下的另一个文件,名为"haha.txt"
        File file = new File("F:\\markdown\\IO\\IO1\\hello.txt");
        File destFile = new File(file.getParent(), "haha.txt");
        boolean newFile = destFile.createNewFile();
        if (newFile) {
            System.out.println("创建成功");
        }
    }
    // 打印出指定目录所有文件名称,包括子文件目录中的文件
    @Test
    public void test4(){
        // 创建目录对象
        File dir = new File("F:\\markdown\\JavaSE");
        printSubFile(dir);
    }
    public static void printSubFile(File dir){
        // 打印目录子文件
        File[] subFiles = dir.listFiles();
        // 循环每个子文件
        for (File f : subFiles) {
            // 判断子文件是否文件目录
            // 是文件夹,递归打印文件目录方法
            if (f.isDirectory()) {
                printSubFile(f);
            }else{
                // 不是文件夹,输出每个文件的绝对地址
                System.out.println(f.getAbsolutePath());
            }
        }
    }
}

13.2.IO流原理及流的分类

image.png image.png image.png
  • 字节流: 以一个byte(8bit)为基本单位传输的流;适合处理非文本数据
  • 字符流: 以一个char(两个字节:16bit)为基本单位传输的;适合处理文本数据
  • 节点流: 直接作用在文件上的流
  • 处理流: 作用在已有节点流处理之上的
  • IO流的体系结构

一.流的分类:
1.操作的数据单位: 字节流,字符流
2.数据的流向: 输入流,输出流
3.流的角色: 节点流,处理流
二.流的体系结构

抽象基类 节点流(或文件流) 缓冲流(处理流的一种)
InputStream FileInputStream (read(byte[] buffer)) BufferedInputStream (read(byte[] buffer))
OutputStream FileOutputStream (write(byte[] buffer,0,len)) BufferedOutputStream (write(byte[] buffer,0,len))/ flush()
Reader FileReader (read(char[] cbuf)) BufferedReader (read(char[] cbuf))
Writer FileWriter (write(char[] cbuf,0,len)) BufferedWriter (write(char[] cbuf,0,len))/ flush()

13.3.节点流(或文件流).

  • FileReader读入数据的基本操作
public class FileReaderWriterTest {
    public static void main(String[] args) {
        // 用绝对路径可以无视main和单元测试
        // 相较于当前工程: F:\markdown\JavaSE\hello.txt
        File file = new File("hello.txt");
        System.out.println(file.getAbsolutePath());
        File file1 = new File("IO\\hello.txt");// 地址这要写就可以相较于当前module下
        System.out.println(file1.getAbsolutePath());
    }
    /*
    将IOmodule下的hello.txt文件内容读入程序中,并输出到控制台,实现读取硬盘中文件的操作
    说明点:
    1.read()的理解: 返回读入的一个字符.如果达到文件末尾,返回-1
    2.异常处理: 为了保证流资源一定可以执行关闭操作.要使用try-catch-finally处理
    3.读入的文件一定要存在,否则就会报FileNotFoundException
     */
    @Test // 单元测试,归具体的module所有
    public void testFileReader() {
        // 异常处理用try-catch比throws好,假如流的对象创建好了没有抛异常,但是下面read的时候出现阻塞读不过来抛了一个IOException
        // 出现了异常就会创建一个异常对象,默认情况下就抛出程序了,相当于程序后面就不执行了,这个时候流就没关,资源就浪费了,存在内存泄露
        // 为了保证即使出现了read异常也要能执行流的资源能执行关闭操作,所以不要用过throws处理,流资源的关闭放在finally是为了防止中途return退出
        FileReader fr = null; // 因为外部要使用,所以这里要先定义
        try {
            // 1.实例化File类的对象,指明要操作的文件
            File file = new File("hello.txt");// 相较于当前module:F:\markdown\JavaSE\基础语法\hello.txt
            // 2.提供具体的字符流来操作文件,相当于给文件提供一个管道来输出数据
            fr = new FileReader(file);// 参数提供文件的路径或名字,上面的file文件一定要存在,否则就会报异常
            // 打开管道的开关,让数据流出
            // 3.数据的读入
            // read(): 返回读入的一个字符.如果达到文件末尾,返回-1,读的是char类型但返回的是字符的int型值
            // int data = fr.read();// 读取文件返回单个字符,文件读完(读取字符末尾结束时)返回-1,文件有多个字符就要用到循环
            // 如果文件是空的,上来就是-1,所以先要做判断,并且有好多字符要读,用while循环
        /*while (data != -1) {
            // 以字符形式输出每个字符
            System.out.print((char) data);
            // 再读一个看看是不是-1
            data = fr.read();//像迭代器一样
        }*/
            // 方式二: 把方法直接写到循环体表达式汇总
            int data;
            while ((data = fr.read()) != -1) {
                System.out.println((char) data);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 4.手动关闭流的操作,防止内存泄露
        /*try {
            // 假如文件流对象没有实例化出现了异常,这里关闭会出现空指针异常,所以造了对象才要关闭
            if (fr != null)
                fr.close();
        } catch (IOException e) {
            e.printStackTrace();
        }*/
        // 或
        if (fr != null) {
            try {
                fr.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
  • FileReader使用read(char[ ] cbuf)读入数据
// 对read()操作升级: 使用read的重载方法
    @Test
    public void testFileReader1() {
        FileReader fr = null;
        try {
            // 1.File类的实例化(创建文件)
            File file = new File("hello.txt");
            // 2.FileReader流的实例化(创建读取文件的流对象)
            fr = new FileReader(file);
            // 3.读入的操作
            // read(char[] cubf): 返回每次到底写入cbuf数组中的字符的个数.如果达到文件末尾,返回-1
            // 先创建一个数组用来缓存要读数据的个数
            char[] cbuf = new char[5];// 可以存放5个字符的数组
            int len;// 定义每次读数据的个数
            // 判断每次读数据的个数,并且每读一次数据都会覆盖一次数组,可以理解为数组元素的替换
            while ((len = fr.read(cbuf)) != -1) {
                // 如果遍历的长度为cbuf.length,输出的结果就是123ld,因为最后一次只有3个字符,无法完全覆盖上一次 最后2个字符就留下了,所以不能是
                // 方式一:
                // 错误的写法
            /*for (int i = 0; i < cbuf.length; i++) {

            }*/
                // 正确写法: 每次读进去几个就遍历几个,不要过多的取后面的
                /*for (int i = 0; i < len; i++) {
                    System.out.print(cbuf[i]);
                }*/
                // 方式二:
                // 错误,对应着方式一的错误写法
                // 这里cbuf第三次读取还是保留最后的ld的,相当于数组有什么就全取出来了,其实跟cbuf.length一样
                /*String str = new String(cbuf);// char型数组转成String型数组
                System.out.print(str);*/
                // 正确写法: 用String的重载构造器,从头开始取,取到第len个
                String str = new String(cbuf, 0, len);
                System.out.println(str);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally { // 写在finally里防止try的时候return
            // 4.资源的关闭
            try {
                fr.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
  • FileWriter写出数据的操作

从内存中写出数据到硬盘的文件里
说明:
1.输出操作,对应的File可以不存在的.
File对应的硬盘中的文件若不存在,在输出过程中,会自动创建此文件
若存在:
如果流用的构造器是: FileWriter(file,false) / FileWriter(file): 会对原有文件进行覆盖
如果流用的构造器是: FileWriter(file,true): 不会对原有文件覆盖, 而是在原有文件基础上追加内容

@Test
    public void testFileWriter() throws IOException {
        FileWriter fw = null;
        try {
            // 1.提供File类的对象,指明写出的文件
            File file = new File("hello1.txt");
            // 2.提供FileWriter类(数据流)的对象,用于数据的写出
            fw = new FileWriter(file, true);// 第二个参数的意思: 是否在原有文件上添加,表示对原有文件的覆盖,默认为false
            // 3.写出操作
            fw.write("have dream\n");
            fw.write("have dream");
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                // 4.流资源关闭
                fw.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
  • 用FileReader和FileWriter实现文本文件的复制
@Test
    public void testFileReaderFileWriter() {
        FileReader fr = null;
        FileWriter fw = null;
        try {
            // 1.创建File类的对象,指明读取和写出的文件
            // 不能用字符流处理图片等字节数据
            File srcFile = new File("hello.txt");
            File destFile = new File("hello2.txt");
            // 2.创建输入流和输出流的对象
            fr = new FileReader(srcFile);// 对于输入流,文件一定要存在
            fw = new FileWriter(destFile);// 文件可以不存在
            // 3.读入内存和写出硬盘操作
            // 一次读多个先创建一个数组
            char[] cbuf = new char[5];
            int len;// 记录每次读入到cbuf数组中字符的个数
            // 循环读入: fr流对象读入到cbuf数组返回读入了几个 如果不是-1就还有数据
            while ((len = fr.read(cbuf)) != -1) {
                // 把数据写出到硬盘当中
                // 错误:若这样写 每次5个5个就把数据读出来了
                // fw.write(cbuf);
                // 正确: 读进去几个就写出几个
                fw.write(cbuf, 0, len);// 每次从0开始写出len个字符
                // 循环结束返回-1
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            // 4.关闭流资源,建议从下往上关
            // 两个操作并列写就可以了(也可以用finally),因为就算中途出现异常也已经catch掉了,不影响try以外的代码运行,try里面代码出现异常,内部接着往下的才不执行
            try {
                if (fw != null)
                    fw.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (fr != null)
                    fr.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
  • 字符流不能处理图片文件的测试

  • 用FileInputStream不能读取文本文件的测试

  • 用FileInputStream和FileOutputStream读写非文本文件

  • 用FileInputStream和FileOutputStream复制文件的测试

13.4.缓冲流

  • 缓冲流(字节型)实现非文本文件的复制

13.5.转换流

  • 转换流概述与InputStreamReader的使用

  • 转换流实现文件的读入和写出

13.6.标准输入输出流

13.7.打印流

13.8.数据流

13.9.对象流

image.png image.png
  • 对象流序列化与反序列化字符串操作

对象流的使用
1.ObjectInputStream 和 ObjectOutputStream
2.作用:用于存储和读取基本数据类型数据或对象的处理流。他的强大之处就是可以把Java中的对象写入到数据源中,也能把对象从数据源中还原回来
3.要想一个java对象是可序列化的,需要满足相应的要求。见Person.java

public class ObjectInputOutputStreamTest {
    /*
    序列化过程:将内存中的java对象保存到磁盘中或通过网络传输出去
    使用ObjectOutPutStream输出实现
     */
    @Test
    public void testObjectOutputStream(){
        ObjectOutputStream oos = null;
        try {
            // 1.造一个对象处理流包住一个节点流,造文件和流写在一起
            oos = new ObjectOutputStream(new FileOutputStream("object.dat"));
            // 2.写出到磁盘的对象
            // 一开始内存当中有个对象就是这个String,随时可能会被回收,就把他持久化保存起来,
            // 或者可以不生成文件,通过网络把它传出去也行,传出去以后再另外一端又可以把它还原成字符串
            oos.writeObject(new String("我爱天安门"));
            // 显式的刷新操作
            oos.flush();
            oos.writeObject(new Person("王敏", 23));// 被持久化到Object.dat文件里
            oos.flush();
            // 序列化自定义类,该类的属性也全都要可序列化
            oos.writeObject(new Person("张帅", 21,1001,new Account(5000)));
            oos.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if (oos != null) {
                // 3.流关闭
                try {
                    oos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    /*
    反序列化过程: 将磁盘文件中的对象还原为内存中的一个java对象,或通过网络方式获取到流,把网络中的流的数据还原为java层面的对象
    使用ObjectInputStream来实现
     */
    @Test
    public void testInputStream(){
        ObjectInputStream ois = null;
        try {
            // 1.造文件和流对象
            ois = new ObjectInputStream(new FileInputStream("object.dat"));
            // 2.写出磁盘操作,一般写入的都是同一个类型的
            Object obj = ois.readObject();// 通常往里放的都是同类型的对象
            String str = (String) obj;// 这个对象其实是个字符串所以可以强转
            Person p = (Person) ois.readObject();
            Person p1 = (Person) ois.readObject();
            // 还原为内存层面
            System.out.println(str);
            System.out.println(p);
            System.out.println(p1);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }finally {
            // 3.流关闭
            try {
                if (ois != null)
                    ois.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

Person类要满足如下的需求,方可序列化
1.要实现标识接口: Serializable
2.当前类要提供一个全局常量: serialVersionUID(版本序列号)
如果不添加这个全局常量,给这个类的对象序列化了,存储在磁盘中,紧接着对Person类修改了,修改后,自动生成的serialVersionUID就变了,
变了再去还原的话就找不到当初序列化的全局常量对应的Person,在还原时候就出问题了(报异常)
3.除了当前Person类需要实现Serializable接口之外,还必须保证其内部所有属性也必须是可序列化的。(默认情况下,基本数据类型是可序列化的)
补充: ObjectOutputStream和ObjectInputStream不能序列化static和transient修饰的成员变量
static属于类的资源不归对象所有所以不能序列化,transient是瞬态的
transient:被修饰的成员属性变量不能被序列化
4.对象序列化机制允许把内存中的Java对象转换成平台无关的二进制流,
从而允许把这种二进制流持久地保存在磁盘上,或通过网络将这种二进制流传输到另一个网络节点。
当其它程序获取了这种二进制流,就可以恢复成原来的Java对象

public class Person implements Serializable {
    public static final long serialVersionUID = 451615182L;
    private static String name;
    private transient int age;
    private int id;
    private Account acct;// 自定义类属性也要是可序列化的,
    public Person(String name, int age, int id, Account acct) {
        this.name = name;
        this.age = age;
        this.id = id;
        this.acct = acct;
    }

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

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

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

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

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", acct=" + acct +
                '}';
    }
}
class Account implements Serializable{
    // 加上唯一的全局静态常量避免反序列化报异常
    public static final long serialVersionUID = 4515182L;
    private double balance;
    public Account(double balance) {
        this.balance = balance;
    }

    public double getBalance() {
        return balance;
    }

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

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

13.10.随机存取文件流

RandomAccessFile的使用
1.RandomAccessFile直接继承于java.Lang.Object类,实现了DataInput和DataOutput接口
2.RandomAccessFile既可以作为一个输入流,又可以作为一个输出流
3.如果RandomAccessFile作为输出流时,写出到的文件若不存在,则在执行过程中自动创建
若写出到的文件存在,则会对原有文件内容进行覆盖.(默认情况下,从头覆盖,能覆盖多少算多少)
4.可以通过把指定指针位置后的内容缓存起来,然后再在指定指针位置插入新值,再把缓存的内容追加回原来的文件,实现RandomAccessFile"插入"数据的效果

public class RandomAccessFileTest {
    @Test
    public void test11() throws FileNotFoundException {
        RandomAccessFile raf1 = null;
        RandomAccessFile raf2 = null;
        try {
            // 1.造流的对象
            raf1 = new RandomAccessFile(new File("pic.jpg"), "r");// 只读模式
            raf2 = new RandomAccessFile(new File("pic3.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();
        }
        try {
            // 3.流关闭
            if (raf2 != null) {
                raf2.close();
            }
            if (raf1 != null) {
                raf1.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    @Test
    public void test2() throws IOException {
        // 创建写出流的对象和文件对象
        RandomAccessFile raf1 = new RandomAccessFile("hello4.txt", "rw");
        // 写出操作
        raf1.seek(3);// 将指针调到角标为3的位置
        raf1.write("xyz".getBytes());// 覆盖掉原来文件里的头三个字符
        // 流关闭
        raf1.close();
    }
    /*
    用RandomAccessFile实现数据的插入效果
     */
    @Test
    public void test3() throws IOException {
        RandomAccessFile raf1 = new RandomAccessFile("hello4.txt", "rw");
        raf1.seek(3);// 将指针调到下标为3的位置
        // 将读取的数据存入一个数组,将数组长度先设置为文件长度的大小避免扩容,提高效率,length()返回一个long类型的值
        // 保存指针角标3后面的所有数据到StringBuilder中
        StringBuilder builder = new StringBuilder((int) new File("hello4.txt").length());//新造数组的大小要么比原文件小,要么和源文件一样大
        // 读取操作
        byte[] buffer = new byte[20];
        int len;
        while ((len = raf1.read(buffer)) != -1) {
            // 把每次遍历的字符放入builder数组中
            builder.append(new String(buffer, 0, len));
        }
        // 此时指针自动跑到最后了,将指针调回角标为3的位置
        raf1.seek(3);
        // 插入"xyz"的数据,相当于对原有内容进行覆盖
        raf1.write("xyz".getBytes());// 这里write返回byte[]类型,所以要用getBytes()
        // 写出后不用再调指针了,指针已经在z的后面了
        // 将builder中的数据写入到文件中
        raf1.write(builder.toString().getBytes());
        // 关闭流
        raf1.close();
    }
}

13.11.NIO.2中Path,Paths,Files类的使用

  • 用第三方jar包实现数据读写

14.1.网络编程概述

14.2.网络通信要素概述

14.3.通信要素1: IP和端口号

  • 端口号的理解
image.png
public class InetAddressTest {
    public static void main(String[] args) {
        // 创建一个对象,其对应的ip就是方法的参数
        // 类似于File file = new File("hello.txt");
        // 内存中的file对象对应着hello.txt路径的文件
        try {
            InetAddress inet1 = InetAddress.getByName("192.168.10.14");// 参数host代表主机名
            System.out.println(inet1);
            InetAddress inet2 = InetAddress.getByName("www.taobao.com");
            System.out.println(inet2);
            InetAddress inet3 = InetAddress.getByName("127.0.0.1");
            System.out.println(inet3);
            // 直接获取本地IP地址的方法
            InetAddress inet4 = InetAddress.getLocalHost();
            System.out.println(inet4);
            // getHostName(): 获取域名
            System.out.println(inet2.getHostName());
            // getHostAddress(): 获取主机地址
            System.out.println(inet2.getHostAddress());
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }
    }
}

14.4.通信要素2: 网络协议

  • TCP和UDP网络通信协议的对比
  • 三次握手: 应该这样理解:1.A发送请求 2.B告诉A已经收到请求(ACK确认)3.A确认B收到了A的请求 4.A开始数据传输

14.5.TCP网络编程

  • TCP网络编程例题:

14.6.udp网络编程

  • UDP编程举例

14.7.url编程

相关文章

  • Java高级- IO流

    13.1.File类的使用 File类的使用1.File类的一个对象,代表一个文件或一个文件目录(俗称: 文件夹)...

  • Java之IO流详解

    title: Java之IO流详解tags: Java IO流categories: Java IO流 大多数应用...

  • 从0开始复习java(9)--IO

    Java的io通过java.io包下的类和接口支持。主要有输入、输出流,又分为字节流和字符流。Java的io流使用...

  • java IO入门笔记

    1.java IO流的概念,分类,类图 1.1. java IO 流的概念 java的io是实现输入和输出的基础,...

  • Java IO详解

    1 Java IO流的概念,分类 1.1 Java IO流的概念 java的IO是实现输入和输出的基础,可以方便的...

  • Java的IO和NIO

    Java的IO和NIO 一、Java的IO Java的IO功能在java.io包下,包括输入、输出两种IO流,每种...

  • IO流 秦始皇与编码的故事

    java零基础入门-高级特性篇(十一) IO 流 1 IO的故事可以从2000多年前的始皇帝开始讲起。自从秦始皇统...

  • java io 流

    java io 流 io 流总览 io 流主要提供四个接口 InputStream: 输入字节流 OutputSt...

  • 28、说说Java 中 IO 流

    说说Java 中 IO 流 Java 中 IO 流分为几种? 1、按照流的流向分,可以分为输入流和输出...

  • java IO流

    java IO流 java流操作的类和接口 java流类图结构 IO流的定义 流是一组有顺序的,有起点和终点的字节...

网友评论

      本文标题:Java高级- IO流

      本文链接:https://www.haomeiwen.com/subject/ujmrjltx.html