Java深入浅出说流的使用

网友投稿 233 2022-09-28


Java深入浅出说流的使用

目录一、File类的使用A.常用构造器B.路径分隔符C.常用方法二、流的分类及其体系输入、输出的标准化过程1.输入过程2.输出过程三、流的详细介绍1.字节流和字符流2.节点流和处理流(重点)3.其他流1.标准的输入、输出流对象流 (重点)对象流的使用Person类对象的序列化机制随机存取文件流(了解)java中的NIO

一、File类的使用

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

2.File了声明在java.io包下

3.File类中涉及到关于文件或文件目录的创建、删除、重命名、修改时间、文件大小等方法。

并涉及到写入或读取文件内容的操作。入宫需要读取或写入文件内容,必须使用IO流来完成。

4.后续File类的对象常会作为参数传递到流的构造器中,指明读取或写入的"终点"。

A.常用构造器

B.路径分隔符

/*

1.如何创建File类的实例

File(String filePath)

File(String parentPath,String,childPath)

File(File parentFile,String childPath)

2.相对路径:相较于某个路径下,知名的路径。

绝对路径:包含盘符在内的未见或文件目录的路径

3.路径分隔符

windows:\\

unix:/

*/

public void test1() {

//构造器1

File file1 = new File("hello.txt");//相对于module

File file2 = new File("E:\\zxdym\\IDEA\\code\\JavaSenior\\2021_08\\he.txt");

System.out.println(file1);

System.out.println(file2);

//构造器2

File file3 = new File("E:\\zxdym\\IDEA\\code", "JavaSenior");

System.out.println(file3);

//构造器3

File file4 = new File(file3, "hi.txt");

System.out.println(file4);

}

C.常用方法

public void test2() {

File file1 = new File("hello.txt");

File file2 = new File("d:\\io\\hi.txt");

System.out.println(file1.getAbsolutePath());

System.out.println(file1.getPath());

System.out.println(file1.getName());

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 void test3() {

File file = new File("E:\\\\zxdym\\\\IDEA\\\\code\\\\JavaSenior");

String[] list = file.list();

for (String s : list) {

System.out.println(s);

}

System.out.println();

File[] files = file.listFiles();

for (File f : files) {

System.out.println(f);

}

}

/*

public boolean removeTo(File dest):把文件重命名为指定的文件路径

比如:file1.renameTo(file2)为例:

要想保证返回true,需要file1在硬盘中是存在的,且file2不能在硬盘中存在。

*/

@Test

public void test4() {

File file1 = new File("hello.txt");

File file2 = new File("D:\\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());

}

@Test

public void test6() throws IOException {

File file1 = new File("hi.txt");

if (!file1.exists()) {

file1.createNewFile();

System.out.println("创建成功");

} else {//文件存在

file1.delete();

System.out.println("删除成功");

}

}

@Test

public void test7(){

//文件目录的创建

File file1 = new File("e:\\io\\io1\\io3");

boolean mkdir = file1.mkdir();

if(mkdir){

System.out.println("创建成功1");

}

File file2 = new File("e:\\io\\io1\\io3");

boolean mkdir1 = file1.mkdirs();

if(mkdir1){

System.out.println("创建成功2");

}

}

D.注意点

二、流的分类及其体系

开发中,用缓冲流,效率比节点流高(蓝色框中的表示重要的、常用的)

输入、输出的标准化过程

1.输入过程

A.创建File类的对象,指明读取的数据的来源。(要求此文件一定要存在)

B.创建相应的输入流,将File类的对象作为参数,传入流的构造器中

C.具体的读入过程:

创建相应的byte[] 或 char[]

D.关闭流资源

说明:程序中出现的异常需要使用try-catch-finally处理。

2.输出过程

A.创建File类的对象,指明写出的数据的来源。(要求此文件一定要存在)

B.创建相应的输出流,将File类的对象作为参数,传入流的构造器中

C.具体的写出过程:

write(char[]/byte[] buffer,0,len)

D.关闭流资源

说明:程序中出现的异常需要使用try-catch-finally处理。

public class FileReaderWriterTest {

public static void main(String[] args) {

File file = new File("hello.txt");//相较于前工程

System.out.println(file.getAbsolutePath());

File file1 = new File("2021_08\\hello.txt");

System.out.println(file1.getAbsolutePath());

}

/*

将day09下的hello.txt文件内容读入程序中,并输出到控制台

说明点:

1.read()的理解,返回读入的一个字符,如果达到文件末尾,返回-1

2.异常的处理:为了保证流资源一定可以执行关闭操作。需要使用try-catch-finally处理

3.读入的文件一定要存在,否则就会报FileNotFoundException.

*/

@Test

public void testFileReader(){

FileReader fr = null;

try {

//1.实例化File类的对象,指明要操作的文件

File file = new File("hello.txt");//相较于当前Module

//2.提供具体的流

fr = new FileReader(file);

//3.数据的读入

//read():返回读入的一个字符,如果达到文件末尾,返回-1

//方式一:

// int data = fr.read();

// while(data != -1){

// System.out.print((char)data);

// data = fr.read();

// }

//方式二:语法上针对方式一的修改

int data;

while((data = fr.read()) != -1){

System.out.print((char)data);

}

} catch (IOException e) {

e.printStackTrace();

} finally {

//4.流的关闭操作

try {

if(fr != null)

fr.close();

} catch (IOException e) {

e.printStackTrace();

} finally {

}

}

}

@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[] cbuf):返回每次读入cbuf数组中的字符的个数,如果达到文件末尾,返回-1

char[] cbuf = new char[5];

int len;

while(( len = fr.read(cbuf)) != -1){

//方式一:

//错误的写法//知识点难点:数组元素的覆盖

// for(int i = 0;i < cbuf.length;i++){

// System.out.print(cbuf[i]);

// }

//正确的写法

// for(int i = 0;i < len;i++){

// System.out.print(cbuf[i]);

// }

//方式二:

//错误的写法,对应着方式一的错误的写法

// String str = new String(cbuf);

// System.out.println(str);

//正确的写法

String str = new String(cbuf, 0, len);

System.out.print(str);

}

} catch (IOException e) {

e.printhttp://StackTrace();

} finally {

if(fr != null){

//4.资源的关闭

try {

fr.close();

} catch (IOException e) {

e.printStackTrace();

}

}

}

}

/*

从内存中写出数据到硬盘的文件里

说明:

1.输出操作,对应的File可以不存在的,并不会报异常

2.

File对应的硬盘中的文件如果不存在,在输出的过程中,会自动创建此文件

File对应的硬盘中的文件如果存在:

如果流使用的构造器是:FileWriter(file,false) / FileWriter(file):对原有文件的覆盖

如果流使用的构造器是:FileWriter(file,true):不会对原有文件覆盖,而是在原有文件基础上追加内容

*/

@Test

public void testFileWriter() {

FileWriter fw = null;

try {

//1.提供File类的对象,指明写出到的文件

File file = new File("hello1.txt");

//2.提供FileWriter的对象,用于数据的写出

fw = new FileWriter(file,false);

//3.写出的操作

fw.write("I have a dream!\n");

fw.write("you need to have a dream!");

} catch (IOException e) {

e.printStackTrace();

} finally {

//4.流资源的关闭

if(fw != null){

try {

fw.close();

} catch (IOException e) {

e.printStackTrace();

}

}

}

}

@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");

//不能使用字符流来处理图片等字节数据

// File srcFile = new File("爱情与友情.jpg");

File destFile = new File("爱情与友情1.jpg");

//2.创建数据入流和输出流的对象

fr = new FileReader(srcFile);

fw = new FileWriter(destFile);

//3.数据的读入和写出操作

char[] cbuf = new char[5];

int len;//记录每次读入到cbuf数组中的字符的个数

while((len = fr.read(cbuf)) != -1){

//每次写出len个字符

fw.write(cbuf,0,len);

}

} catch (IOException e) {

e.printStackTrace();

} finally {

// //4.关闭流资源

// //方式一:

// try {

// fw.close();

// } catch (IOException e) {

// e.printStackTrace();

// }finally {

// try {

// fr.close();

// } catch (IOException e) {

// e.printStackTrace();

// }

// }

//方式二:

try {

fw.close();

} catch (IOException e) {

e.printStackTrace();

}

try {

fr.close();

} catch (IOException e) {

e.printStackTrace();

}

}

}

}

三、流的详细介绍

1.字节流和字符流

测试FileInputStream和FileOutputStream的使用

public class FileInputOutputStreamTest {

//使用字节流FileInputOutputStream处理文本文件,可能出现乱码

@Test

public void testFileInputStream(){

FileInputStream fis = null;

try {

//1.造文件

File file = new File("hello.txt");

//2.造流

fis = new FileInputStream(file);

//3.读数据

byte[] buffer = new byte[5];

int len;//记录每次读取的字节的个数

while((len = fis.read(buffer)) != -1){

String str = new String(buffer, 0, len);

System.out.print(str);

}

} catch (IOException e) {

e.printStackTrace();

} finally {

//4.关闭资源

try {

fis.close();

} catch (IOException e) {

e.printStackTrace();

}

}

}

/*

实现对图片的复制操作

*/

@Test

public void testFileInputOutputStream(){

FileInputStream fis = null;

FileOutputStream fos = null;

try {

File srcFile = new File("爱情与友情.jpg");

File destFile = new File("爱情与友情2.jpg");

fis = new FileInputStream(srcFile);

fos = new FileOutputStream(destFile);

//复制的过程

byte[] buffer = new byte[5];

int len;

while((len = fis.read(buffer)) != -1){

fos.write(buffer,0,len);

}

} catch (IOException e) {

e.printStackTrace();

} finally {

if(fos != null){

try {

fos.close();

} catch (IOException e) {

e.printStackTrace();

}

}

if(fis != null){

try {

fis.close();

} catch (IOException e) {

e.printStackTrace();

}

}

}

}

//指定路径下文件的复制

public void copyFile(String srcPath,String destPath){

FileInputStream fis = null;

FileOutputStream fos = null;

try {

File srcFile = new File(srcPath);

File destFile = new File(destPath);

fis = new FileInputStream(srcFile);

fos = new FileOutputStream(destFile);

//复制的过程

byte[] buffer = new byte[5];

int len;

while((len = fis.read(buffer)) != -1){

fos.write(buffer,0,len);

}

} catch (IOException e) {

e.printStackTrace();

} finally {

if(fos != null){

try {

fos.close();

} catch (IOException e) {

e.printStackTrace();

}

}

if(fis != null){

try {

fis.close();

} catch (IOException e) {

e.printStackTrace();

}

}

}

}

@Test

public void testCopyFile(){

long start = System.currentTimeMillis();

String srcPath = "C:\\Users\\Administrator\\Desktop\\01-视频.avi";

String destPath = "C:\\Users\\Administrator\\Desktop\\02-视频.avi";

copyFile(srcPath,destPath);

long end = System.currentTimeMillis();

System.out.println("复制操作花费的时间为:" + (end - start));

}

}

结论:

1.对于文本文件(.txt,.java,.c,.cpp),使用字符流处理

2.对于非文本文件(.jpg,.mp3,.mp4,.avi,.doc,.ppt,...),使用字节流处理

2.节点流和处理流(重点)

处理流之一:缓冲流的作用

1.缓冲流:

BufferedInputStream

BufferedOutputStream

BufferedReader

BufferedWriter

2.作用:提高流的读取,写入的速度

提高读写速度的原因:内部提供了一个缓冲区,默认情况是8kb

3.处理流:就是"套接"在已有流的基础上

public class BufferedTest {

@Test

public void BufferedStreamTest(){

BufferedInputStream bis = null;

BufferedOutputStream bos = null;

try {

//1.造文件

File srcFile = new File("爱情与友情.jpg");

File destFile = new File("爱情与友情3.jpg");

//2.造流

//2.1造节点流

FileInputStream fis = new FileInputStream(srcFile);

FileOutputStream fos = new FileOutputStream(destFile);

//2.2造缓冲流

bis = new BufferedInputStream(fis);

bos = new BufferedOutputStream(fos);

//3.复制的细节:读取、写入

byte[] buffer = new byte[10];

int len;

while((len = bis.read(buffer)) != -1){

bos.write(buffer,0,len);

// bos.flush();//刷新缓冲区

}

} catch (IOException e) {

e.printStackTrace();

} finally {

//4.资源关闭

//要求:先关闭外层的流,再关闭内层的流

if(bos != null){

try {

bos.close();

} catch (IOException e) {

e.printStackTrace();

}

}

if(bis != null){

try {

bis.close();

} catch (IOException e) {

e.printStackTrace();

}

}

//说明:关闭外层流的同时,内层流也会自动的进行关闭,关于内层流的关闭,可以省略

// fos.close();

// fis.close();

}

}

@Test

public void testCopyFileWithBuffered(){

long start = System.currentTimeMillis();

String srcPath = "C:\\Users\\Administrator\\Desktop\\01-视频.avi";

String destPath = "C:\\Users\\Administrator\\Desktop\\03-视频.avi";

copyFileWithBuffered(srcPath,destPath);

long end = System.currentTimeMillis();

System.out.println("复制操作花费的时间为:" + (end - start));

}

//实现文件复制的方法

public void copyFileWithBuffered(String srcPath,String destPath) {

BufferedInputStream bis = null;

BufferedOutputStream bos = null;

try {

//1.造文件

File srcFile = new File(srcPath);

File destFile = new File(destPath);

//2.造流

//2.1造节点流

FileInputStream fis = new FileInputStream(srcFile);

FileOutputStream fos = new FileOutputStream(destFile);

//2.2造缓冲流

bis = new BufferedInputStream(fis);

bos = new BufferedOutputStream(fos);

//3.复制的细节:读取、写入

byte[] buffer = new byte[10];

int len;

while ((len = bis.read(buffer)) != -1) {

bos.write(buffer, 0, len);

}

} catch (IOException e) {

e.printStackTrace();

} finally {

//4.资源关闭

//要求:先关闭外层的流,再关闭内层的流

if (bos != null) {

try {

bos.close();

} catch (IOException e) {

e.printStackTrace();

}

}

if (bis != null) {

try {

bis.close();

} catch (IOException e) {

e.printStackTrace();

}

}

//说明:关闭外层流的同时,内层流也会自动的进行关闭,关于内层流的关闭,可以省略

// fos.close();

// fis.close();

}

}

/*

使用BufferedReader和BufferedWriter实现文本文件的复制

*/

@Test

public void testBufferedReaderBufferedWriter(){

BufferedReader br = null;

BufferedWriter bw = null;

try {

//创建文件和相应的流

br = new BufferedReader(new FileReader(new File("dpcp.txt")));

bw = new BufferedWriter(new FileWriter(new File("dpcp1.txt")));

//读写操作

//方式一:使用char[]数组

// char[] cbuf = new char[1024];

// int len;

// while((len = br.read(cbuf)) != -1){

// bw.write(cbuf,0,len);

// }

//方式二:使用String

String data;

while((data = br.readLine()) != null){

//方法一:

bw.write(data + "\n");//data中不包含换行符

//方法二:

bw.write(data);//data中不包含换行符

bw.newLine();//提供换行的操作

}

} catch (IOException e) {

e.printStackTrace();

} finally {

//关闭资源

if(bw != null){

try {

bw.close();

} catch (IOException e) {

e.printStackTrace();

}

}

if(br != null){

try {

br.close();

} catch (IOException e) {

e.printStackTrace();

}

}

}

}

}

处理流之二:转换流的使用(重点)

1.转换流:属于字符流

InputStreamReader:将一个字节的输入流转换为字符的输入流

OutputStreamWriter:将一个字符的输出流转换为字节的输出流

2.作用:提供字节流与字符流之间的转换

3.解码:字节、字节数组 ---> 字符数组、字符串

编码:字符数组、字符串---> 字节、字节数组

说明:编码决定了解码的方式

4.字符集

说明:文件编码的方式(比如:GBK),决定了解析时使用的字符集(也只能是GBK)

public class InputStreamReaderTest {

/*

此时处理异常的话,仍然应该使用try-catch-finally

*/

@Test

public void test1() throws IOException{

FileInputStream fis = new FileInputStream("dbcp.txt");

// InputStreamReader isr = new InputStreamReader(fis);//使用系统默认的字符集

//参数2指明了字符集,具体使用那个字符集,取决于文件dbcp.txt保存时使用的字符集

InputStreamReader isr = new InputStreamReader(fis, "UTF-8");

char[] cbuf = new char[20];

int len;

while((len = isr.read(cbuf)) != -1){

String str = new String(cbuf,0,len);

System.out.print(str);

}

isr.close();

}

/*

此时处理异常的话,仍然应该使用try-catch-finally

综合使用InputStreamReader和OutputStreamWriter

*/

@Test

public void test2() throws Exception{

//1.造文件、造流

File file1 = new File("dbcp.txt");

File file2 = new File("dbcp_gbk.txt");

FileInputStream fis = new FileInputStream(file1);

FileOutputStream fos = new FileOutputStream(file2);

InputStreamReader isr = new InputStreamReader(fis, "UTF-8");

OutputStreamWriter osw = new OutputStreamWriter(fos, "gbk");

//2.读写过程

char[] cbuf = new char[20];

int len;

while((len = isr.read(cbuf)) != -1){

osw.write(cbuf,0,len);

}

//3.关闭资源

isr.close();

osw.close();

}

}

3.其他流

1.标准的输入、输出流

1.1  System.in:标准的输入流,默认从键盘输入

System.out:标准的输入流,默认从控制台输出

1.2  System类的setIn() / setOut()方式重新指定输入和输出的流。

修改默认的输入和输出行为:

System类的setIn(InputStream is) / setOut(PrintStream ps)方式重新指定输入和输出的流。

1.3  练习:

从键盘输入字符串,要求将读取道德整行字符串转换成大写输出。然后继续进行输入操作。

直至当输入"e"或"exit"时,退出程序

方法一:使用Scanner实现,调用next()返回一个字符串

方法二:使用System.in实现。System.in ---> 转换流 -->BufferedReader的readLine()

public static void main(String[] args) {

BufferedReader br = null;

try {

InputStreamReader isr = new InputStreamReader(System.in);

br = new BufferedReader(isr);

while(true){

System.out.println("请输入字符串:");

String data = br.readLine();//调用此方法读取一行数据

if("e".equalsIgnoreCase(data) || "exit".equalsIgnoreCase(data)){//避免空指针的写法,之前有

System.out.println("程序结束");

break;

}

String upperCase = data.toUpperCase();

System.out.println(upperCase);

}

} catch (IOException e) {

e.printStackTrace();

} finally {

if(br != null){

try {

br.close();

} catch (IOException e) {

e.printStackTrace();

}

}

}

}

对象流 (重点)

对象流的使用

1.ObjectInputStream和ObjectOutputStream

2.作用:用于存储和读取基本数据类型或对象的处理流。

3.要想一个Java对象是可序列化的,需要满足相应的要求。见Person.java

4.序列化机制:(重点!!!!)

对象序列化机制允许把内存中的Java对象转换成平台无关的二进制流,从而允许把这种二进制流持久的保存在磁盘上,或通过网络将这种

二进制流传输到另一个网络节点,当其他程序获取了这种二进制流,就可以恢复成原来的Java对象

序列化过程:将内存中的java对象保存到磁盘中或通过网络传输出去

使用ObjectOutputStream实现

@Test

public void testObjectOutputStream(){

ObjectOutputStream oos = null;

try {

oos = new ObjectOutputStream(new FileOutputStream("object.dat"));

oos.writeObject(new String("我爱北京天安门"));

oos.flush();//刷新操作

oos.writeObject(new Person("王铭",23));

oos.flush();

} catch (IOException e) {

e.printStackTrace();

} finally {

if(oos != null){

try {

oos.close();

} catch (IOException e) {

e.printStackTrace();

}

}

}

}

反序列化:将磁盘文件中的对象还原为内存中的一个Java对象

使用ObjectInputStream来实现

@Test

public void testObjectInputStream(){

ObjectInputStream ois = null;

try {

ois = new ObjectInputStream(new FileInputStream("object.dat"));

Object obj = ois.readObject();

String str = (String) obj;

Person p = ois.readObject();

System.out.println(str);

System.out.println(p);

}catch(IOException e){

e.printStackTrace();

}catch(ClassNotFoundException e){

e.printStackTrace();

}finally {

if(ois != null){

ois.close;

}

}

}

Person类

Person需要满足如下的要求,方可序列化

1.需要实现接口:Serializable

2.当前类提供一个全局常量:serialVersionUID

3.除了当前Person类需要实现Serializable接口之外,还必须保证其内部所有属性也必须是可序列化的(默认情况下,基本数据类型、String:本身是可序列化的)

补充:ObjectOutputStream 和 ObjectInputStream不能序列化static和transient修饰的成员变量

eg:输出结果:Person{name='null',age=0,id=0,acct=null}

public class Person implements Serializable{

public static final long serialVersionUID = 397497937034L;

private String name;

private int age;

@Override

public String toString() {

return "Person{" +

"name='" + name + '\'' +

", age=" + age +

'}';

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public int getAge() {

return age;

}

public void setAge(int age) {

this.age = age;

}

public Person(String name, int age) {

this.name = name;

this.age = age;

}

public Person() {

}

}

对象的序列化机制

随机存取文件流(了解)

RandomAccessFile

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

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

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

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

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

public abstract class RandomAccessFileTest {

@Test

public void test1(){

RandomAccessFile raf1 = null;

RandomAccessFile raf2 = null;

try {

raf1 = new RandomAccessFile(new File("爱情与友情.jpg"), "r");

raf2 = new RandomAccessFile(new File("爱情与友情1.jpg"), "rw");

byte[] buffer = new byte[1024];

int len;

while((len = raf1.read(buffer)) != -1){

raf2.write(buffer,0,len);

}

} catch (IOException e) {

e.printStackTrace();

} finally {

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){

http:// builder.append(new String(buffer,0,len));

}

//调回指针,写入"xyz"

raf1.seek(3);

raf1.write("xyz".getBytes());

//将StringBuilder中的数据写入到文件中

raf1.write(builder.toString().getBytes());

raf1.close();

}

}

Java中的NIO


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:4-高级路由:RIP默认路由
下一篇:2-高级路由:RIP路由汇总(路由配置RIP)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~