Java的I/O技术可以将数据保存到文本文件、二进制文件甚至是ZIP压缩文件中,以达到永久性保存数据的要求。

1、流概述

流是一组有序的数据序列,根据操作的类型,可分为输入流和输出流两种。I/O(Input/Output)流提供了一条通道程序,可以使用这条通道把源中的字节序列送到目的地。虽然I/O流经常与磁盘文件存取有关,但是程序的源和目的地也可以是键盘、鼠标、内存或显示器窗口等。

2、输入/输出流

Java语言定义了许多类专门负责各种方式的输入/输出,这些类都被放在java.io包中。其中,所有输入流类都是抽象类InputStream(字节输入流)或抽象类Reader(字符输入流)的子类;而所有输出流都是抽象类OutputStream(字节输入流)或抽象类Writer(字符输出流)的子类。

2.1 输入流

InputStream类是字节输入流的抽象类,是所有字节输入流的父类。该类中所有方法遇到错误时都会引发IOException异常。

InputStream类的具体层次结构如图所示:

Java中的字符是Unicode编码,是双字节的。InputStream是用来处理字节的,在处理字符文本时不是很方便。Java为字符文本的输入提供了专门一套单独的类Reader,但Reader类并不是InputStream类的替换者,只是在处理字符串时简化了编程。Reader类是字符输入流的抽象类,所有字符输入流的实现都是它的子类。

Reader类的具体层次结构如下图所示:

2.2 输出流

OutputStream类是字节输入流的抽象类,此抽象类是表示输出字节流的所有类的超类。OutputStream类中的所有方法均返回void,在遇到错误时会引发IOException异常。

OutputStream类的具体层次如图所示:

Writer类是字符输出流的抽象类,所有字符输出类的实现都是它的子类。

Writer类的层次结构如下图所示:

3、File类

File对象即可表示文件,也可表示目录,在程序中一个File对象可以代表一个文件或目录。利用它可用来对文件或目录及其属性进行基本操作。

3.1 文件的创建与删除

(1)引入File类。

import java.io.File;

(2)构建一个文件对象,通用以下3种构造方法来创建文件对象。

构造方法 说明
File(String pathname)

该构造方法通过将给定路径名字符串转换为抽象路径名来创建一个新的File对象。

pathname:指定路径名称(包含文件名),例如:D:/doc/letter.txt

File(String parent , String child)

该构造方法根据定义的父路径和子路径字符串(包含文件名)创建一个新的File对象。

parent:父路径字符串,例如:D:/ 或 D:/doc

child:子路径字符串,例如:letter.txt

File(File f , String child)

该构造方法根据父路径对象和child路径名字符串创建一个新的File对象。

f:父路径对象。

child:子路径字符串。例如:letter.txt

示例:在项目中创建类FileTest,在主方法中判断文件是否存在,如果该文件存在则将其删除,不存在则创建该文件。

import java.io.File;/*** 判断文件是否存在* * @author pan_junbiao**/
public class FileTest
{// 创建类FileTestpublic static void main(String[] args){// 创建文件对象File file = new File("word.txt");if (file.exists()){// 如果该文件存在file.delete(); // 将文件删除System.out.println("文件已删除"); // 输出的提示信息} else{// 如果文件不存在try{// try语句块捕捉可能出现的异常file.createNewFile(); // 创建该文件System.out.println("文件已创建"); // 输出的提示信息} catch (Exception e){// catch处理该异常e.printStackTrace(); // 输出异常信息}}}
}

3.2 获取文件信息

File类提供了很多方法用于获取文件本身的一些信息。

File类的常用方法如下表所示:

方法 说明
getName() 获取文件的名称。
canRead() 判断文件是否为可读的。
canWrite() 判断文件是否可被写入。
exits() 判断文件是否存在。
length() 获取文件的长度(以字节为单位)。
getPath() 获取文件路径。
getAbsolutePath() 获取文件的绝对路径。
getParent() 获取文件的父路径。
isFile() 判断文件是否存在。
isDirectory() 判断文件是否为一个目录。
isHidden() 判断文件是否为隐藏文件。
lastModified() 获取文件最后修改时间(返回值:long类型)。
File[] listFiles() 获取该目录下的所有子目录和文件,返回File类数组。

示例:获取文件相关信息。

import java.io.File;/*** 获取文件相关信息* * @author pan_junbiao**/
public class FileTest
{public static void main(String[] args){File file = new File("word.txt"); // 创建文件对象if (file.exists()){ // 如果文件存在String name = file.getName(); // 获取文件名称long length = file.length(); // 获取文件长度String path = file.getPath();// 获取文件路径String absolutePath = file.getAbsolutePath();// 获取文件绝对路径boolean hidden = file.isHidden(); // 判断文件是否是隐藏文件System.out.println("文件名称:" + name); // 输出信息System.out.println("文件长度是:" + length);System.out.println("文件路径是:" + path);System.out.println("文件绝对路径是:" + absolutePath);System.out.println("该文件是隐藏文件吗?" + hidden);} else{ // 如果文件不存在System.out.println("该文件不存在"); // 输出信息}}
}

执行结果:

3.3 获取目录下的所有目录和文件

示例:假设目录“D:\TestDir1”下有两个文件夹(dir1 和 dir2)和一个文件 file1.txt 。

File[] listFiles()方法:获取该目录下的所有子目录和文件,返回File类数组。

import java.io.File;/*** 获取目录下的所有目录和文件* @author pan_junbiao**/
public class DirFileTest
{public static void main(String[] args){File file = new File("D:\\TestDir1");//判断目录是否存在if (!file.exists()){System.out.println("目录不存在");return;}//获取文件数组File[] fileList = file.listFiles();for (int i = 0; i < fileList.length; i++){//判断是否为目录if (fileList[i].isDirectory()){System.out.println("目录:" + fileList[i].getName());}else{System.out.println("文件:" + fileList[i].getName());}}}
}

执行结果:

4、文件输入/输出流

4.1 FileInputStream与FileOutputStream类

FileInputStream类与FileOutputStream类都是用来操作磁盘文件。如果用户的文件读取需求比较简单,则可以使用FileInputStream类。该类继承自InputStream类。FileOutputStream类与FileInputStream类对应,提供了基本的文件写入能力。FileOutputStream类是OutoputStream类的子类。

示例:使用FileOutputStream类向文件中写入信息,然后通过FileInputStream类将文件中的数据读取到控制台上。

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;/*** 使用FileOutputStream类向文件中写入信息,<br/>* 然后通过FileInputStream类将文件中的数据读取到控制台上* * @author pan_junbiao**/
public class FileTest
{public static void main(String[] args){// 创建文件对象File file = new File("word.txt");// 文件写操作try{// 创建FileOutputStream对象FileOutputStream out = new FileOutputStream(file);// 创建byte型数组byte[] msgBytes = "您好,欢迎访问 pan_junbiao的博客".getBytes();// 将数组中的信息写入到文件中out.write(msgBytes);// 关闭流out.close();} catch (Exception e){e.printStackTrace();}// 文件读操作try{// 创建FileInputStream类对象FileInputStream in = new FileInputStream(file);// 创建Byte数组byte[] byt = new byte[1024];// 从文件中读取信息int len = in.read(byt);// 关闭流in.close();// 将文件中的信息输出System.out.println("使用FileInputStream与FileOutputStream类:");System.out.println("文件中的信息是:" + new String(byt, 0, len));} catch (Exception e){e.printStackTrace();}}
}

执行结果:

说明:虽然Java在程序结束时自动关闭所有打开的流,但是当使用完流后,显示地关闭所有打开的流仍是一个好习惯。一个被打开的流有可能会用尽系统资源,这取决于平台和实现。如果没有将打开的流关闭,当另一个程序试图打开另一个流时,可能会得不到需要的资源。

4.2 FileReader类和FileWriter类

使用FileOutputStream类向文件中写入数据与使用FileInputStream类从文件中将内容读出来,存在一点不足,即这两个类都只提供了对字节或字节数组的读取方法。由于汉字在文件中占用两个字节,如果使用字节流,读取不好可能会出现乱码现象。此时采用字符流Reader或Writer类即可避免这种现象。
FileReader、FileWriter字符流对应了FileInputStream、FileOutputStream类。FileReader流顺序地读取文件,只要不关闭流,每次调用read()方法就顺序地读取源中其余的内容,直到源的末尾或流被关闭。

示例:使用FileWriter类向文件中写入信息,然后通过FileReader类将文件中的数据读取到控制台上。

import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;/*** 使用FileWriter类向文件中写入信息<br/>* 然后通过FileReader类将文件中的数据读取到控制台上。* * @author pan_junbiao**/
public class FileTest
{public static void main(String[] args){// 创建文件对象File file = new File("word.txt");// 文件写操作try{// 创建FileWriter对象FileWriter out = new FileWriter(file);// 创建字符串内容String msgStr = "您好,欢迎访问 pan_junbiao的博客";// 将数组中的信息写入到文件中out.write(msgStr);// 关闭流out.close();} catch (Exception e){e.printStackTrace();}// 文件读操作try{// 创建FileReader类对象FileReader in = new FileReader(file);// 创建char数组char[] charArray = new char[1024];// 从文件中读取信息int len = in.read(charArray);// 关闭流in.close();// 将文件中的信息输出System.out.println("使用FileReader类和FileWriter类:");System.out.println("文件中的信息是:" + new String(charArray, 0, len));} catch (Exception e){e.printStackTrace();}}
}

执行结果:

5、带缓存的输入输出流

缓存是I/O的一种性能优化。缓存流为I/O流增加了内存缓存区。有了缓存区,使得在流上执行skip()、mark()和reset()方法都成为可能。

5.1 BufferedInputStream类与BufferedOutputStream类

BufferedInputStream类可以对任何的InputStream类进行带缓存区的包装以达到性能的优化。BufferedInputStream类有两个构造方法:

BufferedInputStream(InputStream in)。

BufferedInputStream(InputStream in, int size)。

使用BufferedOutputStream类输出信息和往OutputStream输出信息完全一样,只不过BufferedOutputStream有一个flush()方法用来将缓存区的数据强制输出完。BufferedOutputStream类也有两个构造方法:

BufferedOutputStream(OutputStream out)。

BufferedOutputStream(OutputStream out, int size)。

注意:flush()方法就是用于即使在缓存区没有满的情况下,也将缓存区的内容强制写入到外设,习惯上称这个过程为刷新。flush()方法只对使用缓存区的OutputStream类的子类有效。当调用close()方法时,系统在关闭流之前,也会将缓存区中的信息刷新到磁盘文件中。

5.2 BufferedReader与BufferedWriter类

BufferedReader类与BufferedWriter类分别继承Reader类与Writer类。这两个类同样具有内部缓存机制,并可以以行为单位进行输入输出。

BufferedReader类常用方法:

方法 说明
read() 读取单个字符。
readLine() 读取一个文本行,并将其返回为字符串。若无数据可读,则返回null。

在使用BufferedWriter类的Write()方法时,数据并没有立刻被写入至输出流中,而是首先进入缓存区中。如果想立刻将缓存区中的数据写入输出流中,一定要调用flush()方法。

BufferedWriter类中的方法都是返回void,常用方法:

方法 说明
write(String s, int off, int len) 写入字符串的某一部分。
flush() 刷新该流的缓存。
newLine() 写入一个行分隔符。

示例:向指定的文件写入数据,并通过BufferedReader类将文件中的信息分行显示。

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;/*** 向指定的文件写入数据<br />* 并通过BufferedReader类将文件中的信息分行显示* * @author pan_junbiao**/
public class FileTest
{public static void main(String args[]){// 定义字符串数组String content[] = { "好久不见", "最近好吗", "欢迎访问 pan_junbiao的博客", "博客地址:https://blog.csdn.net/pan_junbiao","常联系,祝您身体健康" };File file = new File("word.txt"); // 创建文件对象try{FileWriter fw = new FileWriter(file); // 创建FileWriter类对象// 创建BufferedWriter类对象BufferedWriter bufw = new BufferedWriter(fw);// 循环遍历数组for (int k = 0; k < content.length; k++){bufw.write(content[k]); // 将字符串数组中元素写入到磁盘文件中bufw.newLine(); // 将数组中的单个元素以单行的形式写入文件}bufw.close(); // 将BufferedWriter流关闭fw.close(); // 将FileWriter流关闭} catch (Exception e){ // 处理异常e.printStackTrace();}try{FileReader fr = new FileReader(file); // 创建FileReader类对象// 创建BufferedReader类对象BufferedReader bufr = new BufferedReader(fr);String s = null; // 创建字符串对象int i = 0; // 声明int型变量// 如果文件的文本行数不为null,则进入循环while ((s = bufr.readLine()) != null){i++; // 将变量做自增运算System.out.println("第" + i + "行:" + s); // 输出文件数据}bufr.close(); // 将FileReader流关闭fr.close(); // 将FileReader流关闭} catch (Exception e){ // 处理异常e.printStackTrace();}}
}

运行结果:

6、数据输入输出流

数据输入输出流(DataInputStream类与DataOutputStream类)允许应用程序以与机器无关的方式从底层输入流中读取基本Java数据类型。也就是说,当读取一个数据时,不必再关心这个数值应当是什么字节。

6.1 利用数据流类DataInputStream类读二进制文件

(1)引用相关类

import java.io.FileInputStream;
import java.io.DataInputStream;

(2)构造一个数据输入流对象

FileInputStream fis = new FileInputStream("D:\\MyImage.jpg");
DataInputStream dis = new DataInputStream(fis);

(3)利用数据输入流类的方法读取二进制文件的数据。

dis.readInt();   // 读取出来的是整型
dis.readByte();  // 读取出来的数据是Byte类型

(4)关闭数据输入流

dis.close();  // 关闭数据输入流

6.2 利用数据流类DataOutputStream类写二进制文件

(1)引用相关类

import java.io.DataOutputStream;
import java.io.FileOutputStream;

(2)构造一个数据输出流对象

FileOutputStream outFile = new FileOutputStream("E:\\MyImage2.jpg");
DataOutputStream out = new DataOutputStream(outFile);

(3)利用数据输出流类的方法写二进制文件的数据

out.write(1);   //把数据写入二进制文件

(4)关闭数据输出流

out.close();

示例:将D盘下的MyImage.jpg文件复制到E盘下,并命名为MyImage2.jpg。

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;/*** 将D盘下的MyImage.jpg文件复制到E盘下 <br />* 并命名为MyImage2.jpg* * @author pan_junbiao**/
public class ReadAndWriteBinaryFile
{public static void main(String[] args){try{FileInputStream fis = new FileInputStream("D:\\MyImage.jpg");DataInputStream dis = new DataInputStream(fis);FileOutputStream outFile = new FileOutputStream("E:\\MyImage2.jpg");DataOutputStream out = new DataOutputStream(outFile);int temp;while ((temp = dis.read()) != -1){out.write(temp);}dis.close();out.close();System.out.println("文件复制成功");} catch (Exception e){e.printStackTrace();}}
}

7、ZIP压缩输入/输出流

ZIP压缩管理文件(ZIP archive)是一种十分典型的文件压缩形式,使用它可以节省存储空间。关于ZIP压缩的I/O实现,在Java的内置类中提供了非常好用的相关类,所以其实实现方法非常简单。使用java.util.zip包的ZipInputStream类与ZipOutputStream类来实现文件的压缩/解压缩。利用ZipEntry、ZipInputStream和ZipOutputStream这3个Java类实现ZIP数据压缩方式的编程方法。

7.1 压缩文件

利用ZipOutputStream类对象,可将文件压缩为“.zip”文件。ZipOutputStream类的构造函数如下所示:

ZipOutputStream(OutputStream out);

ZipOutputStream类的常用方法:

方法 说明
putNextEntry(ZipEntry e) 开始编写新的ZIP文件条目,并将流定位到条目数据的开头。 
write(byte[] b, int off, int len) 将一个字节数组写入当前的ZIP条目数据。 
finish() 完成编写ZIP输出流的内容,而不关闭底层流。 
setComment(String comment) 设置ZIP文件注释。

示例:使用ZipOutputStream类对文件夹进行压缩。

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;/*** 使用ZipOutputStream类对文件夹进行压缩* * @author pan_junbiao**/
public class MyZip
{ // 创建类private void zip(String zipFileName, File inputFile) throws Exception{ZipOutputStream out = new ZipOutputStream(new FileOutputStream(zipFileName)); // 创建ZipOutputStream类对象zip(out, inputFile, ""); // 调用方法System.out.println("压缩中…"); // 输出信息out.close(); // 将流关闭}private void zip(ZipOutputStream out, File f, String base) throws Exception{ // 方法重载if (f.isDirectory()){ // 测试此抽象路径名表示的文件是否是一个目录File[] fl = f.listFiles(); // 获取路径数组out.putNextEntry(new ZipEntry(base + "/")); // 写入此目录的entrybase = base.length() == 0 ? "" : base + "/"; // 判断参数是否为空for (int i = 0; i < fl.length; i++){ // 循环遍历数组中文件zip(out, fl[i], base + fl[i]);}} else{out.putNextEntry(new ZipEntry(base)); // 创建新的进入点// 创建FileInputStream对象FileInputStream in = new FileInputStream(f);int b; // 定义int型变量System.out.println(base);while ((b = in.read()) != -1){ // 如果没有到达流的尾部out.write(b); // 将字节写入当前ZIP条目}in.close(); // 关闭流}}public static void main(String[] temp){ // 主方法MyZip book = new MyZip(); // 创建本例对象try{// 调用方法,参数为压缩后文件与要压缩文件book.zip("hello.zip", new File("src"));System.out.println("压缩完成"); // 输出信息} catch (Exception ex){ex.printStackTrace();}}
}

7.2 解压ZIP文件

ZipInputStream类可读取ZIP压缩格式的文件,包括对已压缩和未压缩条目的支持(entry)。ZipInputStream类的构造函数如下所示:

ZipInputStream(InputStream in)

ZipInputStream的常用方法:

方法 说明
read(byte[] b, int off, int len) 从当前ZIP条目读取到字节数组。 
available() 判断是否已读完目前entry所指定的数据。已读完成返回0,否则返回1。
closeEntry() 关闭当前的ZIP条目,并定位流以读取下一个条目。 
skip(long n) 跳过当前ZIP条目中指定的字节数。 
getNextEntry() 读取下一个ZIP文件条目,并将流定位在条目数据的开头。 
createZipEntry(String name) 为指定的条目名称创建一个新的 ZipEntry对象。

示例:使用ZipInputStream类对文件进行解压缩。

import java.io.File;
import java.io.FileInputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;/*** 使用ZipInputStream类对文件进行解压缩* * @author pan_junbiao**/
public class Decompressing
{ // 创建文件public static void main(String[] temp){ZipInputStream zin; // 创建ZipInputStream对象try{ // try语句捕获可能发生的异常zin = new ZipInputStream(new FileInputStream("hello.zip"));// 实例化对象,指明要进行解压的文件ZipEntry entry = zin.getNextEntry(); // 获取下一个ZipEntrywhile (((entry = zin.getNextEntry()) != null) && !entry.isDirectory()){// 如果entry不为空,并不在同一目录下File file = new File("d:\\" + entry.getName()); // 获取文件目录System.out.println(file);if (!file.exists()){ // 如果该文件不存在file.mkdirs();// 创建文件所在文件夹file.createNewFile(); // 创建文件}zin.closeEntry(); // 关闭当前entrySystem.out.println(entry.getName() + "解压成功");}zin.close(); // 关闭流} catch (Exception e){e.printStackTrace();}}
}

总结:

1、流是指一连串流动的字符,是以先进先出的方式发送信息的通道。程序和数据源之间是通过流联系起来的。

2、流可以分为输入流和输出流,也可以分为字节流和字符流。

3、File类用于访问文件或目录的属性。

4、FileInputStream类和FileOutputStream类以字节流的方式读写文本文件。

5、BufferedReader类和BufferedWriter类以字符流的方式读写文本文件,而且效率更高。

6、DataInputStream类和DataOutputStream类可用于读写二进制文件。

7、ZipInputStream类和ZipOutputStream类可用于文件的压缩和解压缩。

Java中I/O(输入/输出)的操作相关推荐

  1. java io字符输出流_灵魂一击!详解Java中的IO输入输出流

    什么是流?流表示任何有能力产生数据的数据源对象或者是有能力接收数据的接收端对象,它屏蔽了实际的I/O设备中处理数据的细节. IO流是实现输入输出的基础,它可以很方便地实现数据的输入输出操作,即读写操作 ...

  2. 在JAVA中 以下程序_在Java中,以下程序的输出结果是()_学小易找答案

    [单选题]运行以下Java代码,说法正确的是( ). [单选题]在Java中,以下程序的输出结果是() [单选题]利用"出声"的方式向学生展示教师分析问题的过程与方法的教学方法是_ ...

  3. Java中的字节输入出流和字符输入输出流

    Java中的字节输入出流和字符输入输出流 下面哪个流类属于面向字符的输入流( ) A BufferedWriter  B FileInputStream  C ObjectInputStream  D ...

  4. java中从键盘输入的三种方法以及Console输入

    java中从键盘输入的三种方法: import java.io.BufferedReader; import java.io.IOException; import java.io.InputStre ...

  5. java中文件的输入和输出

    以下所有对象需要关闭(close)的,都使用jdk1.7的try-with-resource来进行释放 文件的输入(读取)需要使用到: 创建一个File对象,在初始化的时候赋值一个文件路径. 创建Fi ...

  6. 在java中数组的输入与输出_Java 数组的输入输出

    Java中要对控制台进行输入操作的话要调用Scanner类,定义一个扫描的对象,例: //要导入java.util.Scanner;Scanner scanner = new Scanner(Syst ...

  7. java中的进制输出转换_Java I/O : Java中的进制详解

    作者:李强强 上一篇,泥瓦匠基础地讲了下Java I/O : Bit Operation 位运算.这一讲,泥瓦匠带你走进Java中的进制详解. 一.引子 在Java世界里,99%的工作都是处理这高层. ...

  8. java中如何限制输入非空_项目中的参数限制、非空、以及集合中的验证,你真的会做吗(Java)...

    背景: 在项目管理中,我们通常要对一个个参数做验证, 前端校验,后端加校验,这里为了保证校验的一致性,我们需要将我们的校验写的比较高效率一点,不至于满篇都是is null的进行参数验证,为了成为一个成 ...

  9. 文件输出 java_用Java读写文件(输入/输出)-教程

    一.文件的Java I/O(输入/输出) 1.1.概述 在现代Java应用程序中,通常使用Java.nio.fileAPI来读写文件. Java将把所有输入作为字节流读取.input stream类是 ...

  10. java中的进制输出转换_java中进制的转换,Byte与16进制的转换

    java中对于进制的转换有很多方式,其中对于常见的基本的二进制 八进制 十进制 十六进制等的转换有对于的包装类实现,不需要通过二外的算法来进行实现,具体如下: 首先关于最简单的二进制转换的方法有: 十 ...

最新文章

  1. 这样写交互说明,开发不会约你去爬山~
  2. 一般控制矩阵转能控标准型
  3. 关于9999元的小米铁蛋,这里有一份官方解答
  4. python连接postgis_python连接PostgreSQL
  5. shell 判断目录还是文件
  6. 调度 Cmax和∑Ci是什么区别
  7. JSONArray.fromObject(str)
  8. 投屏软件_五款良心投屏软件,将安卓iOS投射到大屏幕
  9. 基于信息熵的新词发现算法
  10. 【第10章】接口与Lambda表达式
  11. 机器学习——需求预测——准确性(误差)统计——MAE、MSE、MAPE、WMAPE
  12. 淘宝新店被人举报盗图要扣分处理办法
  13. adb devices后显示List of devices attached/unauthorized问题解决
  14. mac os 卸载java_三种方法教你在苹果Mac OS X系统中卸载软件
  15. 用JAVA写一个电话号码滚动抽奖器
  16. matlab simulink 车辆能耗_[Lib库 1]CoppeliaSim差分避障小车的Simulink实现
  17. IT人员要善用图表来说明问题
  18. WinForm调用摄像头扫码识别二维码
  19. highway network
  20. 用ALTER TABLE语句来创建索引

热门文章

  1. 文件之间的拷贝(拷贝图片实例)java.io.FileNotFoundException: G:\dad (拒绝访问。)通过绝对路径获取各种文件名
  2. Django框架--路由分配系统
  3. 如何快速学习音视频开发?
  4. python中def func是什么意思_Python的函数参数详解
  5. vcs编译vivado原语:
  6. 期刊论文重复率多少算合格?
  7. 中国冷鲜鸡肉行业竞争战略及企业核心竞争力提升策略分析报告2022-2028年版
  8. vue js ES6 数组去重常用的几种方法
  9. oracle插入数据脚本
  10. SQL HAVING用法详解