zoukankan      html  css  js  c++  java
  • Java 持久化操作之 --io流与序列化

    1)File类操作文件的属性

    1.File类的常用方法

    1.

    文件的绝对完整路径:getAbsolutePath()

    文件名:getName()

    文件相对路径:getPath()

    文件的上一级目录:getParent()

    文件的大小为:length()

    删除文件:delete()

    具体操作请参考如下代码:

    package text;
    import java.io.File;
    import java.util.Scanner;
    /**
     * 
     * @author: 房上的猫
     * 
     * @time: 下午7:55:16
     * 
     * @博客地址: https://www.cnblogs.com/lsy131479/
     *
     *        消费信息
     *
     */
    public class TextFile {
        public static void main(String[] args) 
        {
            try {
                FileText();
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        public static void FileText() throws Exception
        {
            //1.实例化对象指定判断路径
            File file=new File("D:\TextFile\A.txt");
            //2.判断A.txt是否存在
            if(file.exists())
            {
                //判断是否是文件夹
                if(file.isDirectory())
                {
                    System.out.println("这是一个文件夹");
                }else
                {
                    System.out.println("当前文件存在");
                    System.out.println("这是一个文件");
                    System.out.println("文件的绝对完整路径:"+file.getAbsolutePath());
                    System.out.println("文件名:"+file.getName());
                    System.out.println("文件相对路径:"+file.getPath());
                    System.out.println("文件的上一级目录:"+file.getParent());
                    System.out.println("文件的大小为:"+file.length());    
                    Scanner input=new Scanner(System.in);
                    System.out.println("请按1删除此文件=======");
                    if(input.nextInt()==1)
                    {
                        boolean flog1= file.delete();
                        if(flog1)
                        {
                            System.out.println("删除成功");
                        }
                    }
                }
            }else
            {
                System.out.println("当前文件不存在---开始创建");
                //3.不存在则创建新文件
                boolean flog=file.createNewFile();
                if(flog)
                {
                    System.out.println("文件创建成功");
                }    
            }
        }
    }


    2)IO流(堵塞型io)

     如何读写文件?

        分析:流是指一连串流动的字符,是以先进先出方式发送信息的通道

     输入/输出流于数据源:

        

    java流的分类:

    我们可以对它进行如下分类:

    · 按处理的数据类型可分为字节流字符流

    · 按流的流向可分为输入流(in)与输出流(out)

    · 按流的功能可分为节点流(Node)和过滤流(Filter)

    在Java中,字节流一般适用于处理字节数据(诸如图片、视频),字符流适用于处理字符数据(诸如文本文件),但二者并没有严格的功能划分,因为有转换流的存在,使得对于数据的处理变得更加灵活。 

    1)字节流读写文件

    一般用于处理字节数据,但字节流采用ASCII编码的,所以处理字符数据时容易出现中文乱码

    1. 输入流

    InputStream:此抽象类是表示字节输入流的所有类的超类(基类)

    序号

    方法描述

    1

    public final int read(byte[] r, int off, int len)throws IOException
    从所包含的输入流中将 len 个字节读入一个字节数组中。如果len为-1,则返回已读字节数。

    2

    Public final int read(byte [] b)throws IOException
    从所包含的输入流中读取一定数量的字节,并将它们存储到缓冲区数组 b 中。

    3

    1. public final Boolean readBooolean()throws IOException,

    2. public final byte readByte()throws IOException,

    3. public final short readShort()throws IOException

    4. public final Int readInt()throws IOException

    从输入流中读取字节,返回输入流中两个字节作为对应的基本数据类型返回值。

    4

    public String readLine() throws IOException
    从输入流中读取下一文本行。

    所有字节输入流都是以此类发散出来的,但此类是一个抽象类,不可被实例化,所以实际编程过程中,都是使用它发散出来的一些子类,下面是输入流的关系图:

    输入流最常用的就是FileInputStream类:

    1-1 文本文件的读取:用FileInputStream

    该流用于从文件读取数据,它的对象可以用关键字 new 来创建。

    ·有多种构造方法可用来创建对象。

    ·可以使用字符串类型的文件名来创建一个输入流对象来读取文件:

    ·····InputStream f = new FileInputStream("C:/java/hello");

    ·也可以使用一个文件对象来创建一个输入流对象来读取文件。我们首先得使用 File() 方法来创建一个文件对象:

    ·····File f = new File("C:/java/hello");

    ·····InputStream out = new FileInputStream(f);

    ·创建了InputStream对象,就可以使用下面的方法来读取流或者进行其他的流操作。

        字节流:

        基类:InputStream     子类:FileInputStream

        构造:

        FileInputStream(File file)   ||   FileInputStream(String name)

        

        方法:

        read() 按字节读    

        read(byte[] b) 读到字节数组缓冲区,数组存满统一批次循环读取

        read(byte[] b, int off, int len)  向数组存放时进行了限制,起始位置off和终止位置len

        int  available()   表示当前还剩多少个字节未读取

        

        注意:read方法返回 int 类型 返回读入字节数组的长度,如果读取到文件末尾的时候,则返回-1

    代码演示按字节读取到控制台:

        四步走:1.导入相关类   2.创建字节流对象   3.实现读取文本文件的数据   4.关闭文件流对象

        测试文档:

        使用Read()读取

       废话不多说 举个栗子:

    package text;
    import java.io.FileNotFoundException;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.FileInputStream;
    public class FileInputStream01 {
        public static void main(String[] args) {
            //创建字节流对象
            InputStream fls=null;
            try {
                fls=new FileInputStream("D://TextFile//A.txt");
                //实现读取操作
                int data;//存储读取的字节
                while((data=fls.read())!=-1)
                {
                    //System.out.print(data);//读取的是数字
                    System.out.print((char)data);//读取的是和文件一致
                }
            } catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }finally
            {
                try {
                    if(fls!=null)
                    fls.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    }

    修改代码使用Read(byte[] b)读取

     
    int len;//存储读入数组的长度
    byte[] wrods=new byte[1024];
    while((len=fls.read(wrods))!=-1)
    {
        System.out.print(new String(wrods,0,len));//String构造方法 把字节byte[] 转换成字符串形式,0代表截取起始位置,len表示截取终止位置
    }

    结果与上述一致:

    1. 输出流

    OutputStream:此抽象类是表示字节输出流的所有类的超类(基类)

    序号

    方法描述

    1

    public final void write(byte[] w, int off, int len)throws IOException
    将指定字节数组中从偏移量 off 开始的 len 个字节写入此字节数组输出流。

    2

    Public final int write(byte [] b)throws IOException
    将指定的字节写入此字节数组输出流。

    3

    1. public final void writeBooolean()throws IOException,

    2. public final void writeByte()throws IOException,

    3. public final void writeShort()throws IOException,

    4. public final void writeInt()throws IOException

    这些方法将指定的基本数据类型以字节的方式写入到输出流。

    4

    Public void flush()throws IOException
      刷新此输出流并强制写出所有缓冲的输出字节。

    5

    public final void writeBytes(String s) throws IOException
    将字符串以字节序列写入到底层的输出流,字符串中每个字符都按顺序写入,并丢弃其高八位。

    所有字节输出流都是以此类发散出来的,但此类是一个抽象类,不可被实例化,所以实际编程过程中,都是使用它发散出来的一些子类,下面是输出流的关系图:

    输出流最常用的就是FileOutputStream 类:

    1-2文本文件的写入:用FileOutputStream 

    该类用来创建一个文件并向文件中写数据。

    如果该流在打开文件进行输出前,目标文件不存在,那么该流会创建该文件。

    有两个构造方法可以用来创建 FileOutputStream 对象。

    使用字符串类型的文件名来创建一个输出流对象:

    OutputStream f = new FileOutputStream("C:/java/hello")

    也可以使用一个文件对象来创建一个输出流来写文件。我们首先得使用File()方法来创建一个文件对象:

    File f = new File("C:/java/hello");

    OutputStream f = new FileOutputStream(f);

        输出流:

        基类:OutputStream

        子类:FileOutputStream  ..............

        构造:

            

        方法:

       废话不多说 举个栗子:

    package text;
    import java.io.File;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.OutputStream;
    public class FileoutputStream {
        public static void main(String[] args) {
            //创建输出字节流
            OutputStream fls =null;
            try {
                //以File类对象作为参数,或 String name
                //构造一个参数
                //fls=new FileOutputStream(new File("D://TextFile//B.txt"));
                
                //file - 为了进行写入而打开的文件。
                //append - 如果为 true,则将字节写入文件末尾处,而不是写入文件开始处 
                fls=new FileOutputStream(new File("D://TextFile//B.txt"),true);
                //声明要写入的内容
                String name="我是测试字符串";
                //将字符串转换为字节数组
                byte[] words=name.getBytes();
                //写入方法一
                //fls.write(words);
                //写入方法二
                fls.write(words,0,words.length);
                System.out.println("写入成功");
            } catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }finally
            {
                try {
                    fls.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    }

    1-3文件读取和写入同步

       废话不多说 举个栗子:

    package text;
    import java.io.File;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.OutputStream;
    public class FileoutputStream {
        public static void main(String[] args) {
            //创建输出字节流
            OutputStream fls =null;
            try {
                //以File类对象作为参数,或 String name
                //构造一个参数
                //fls=new FileOutputStream(new File("D://TextFile//B.txt"));
                
                //file - 为了进行写入而打开的文件。
                //append - 如果为 true,则将字节写入文件末尾处,而不是写入文件开始处 
                fls=new FileOutputStream(new File("D://TextFile//B.txt"),true);
                //声明要写入的内容
                String name="我是测试字符串";
                //将字符串转换为字节数组
                byte[] words=name.getBytes();
                //写入方法一
                //fls.write(words);
                //写入方法二
                fls.write(words,0,words.length);
                System.out.println("写入成功");
            } catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }finally
            {
                try {
                    fls.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    }

    2)字符流读和缓冲流读文件

        用BufferedReader 和 BufferedWriter读写文本文件//字符流

        或 FileReader

        字符编码:ASCII码   0~127  8位二进制数1个字节。  16位二进制数表示一个字符 两个字节

        字符流:输入流

        基类:Reader----FileReader

                    

        构造:

                

        常用方法:

                

    1)如果 使用字节流读取带有汉字的文件会怎么样那

    package text;
    import java.io.FileNotFoundException;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.FileInputStream;
    public class FileInputStream01 {
        public static void main(String[] args) {
            //创建字节流对象
            InputStream fls=null;
            try {
                fls=new FileInputStream("D://TextFile//A.txt");
                //实现读取操作
                int data;//存储读取的字节
                while((data=fls.read())!=-1)
                {
                    //System.out.print(data);//读取的是数字
                    //System.out.println("还剩:"+fls.available()+"字节未读取");            
                    System.out.print((char)data);
                }
            } catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }finally
            {
                try {
                    if(fls!=null)
                    fls.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    }

    运行结果如下:

    很明显出现了乱码

    2)下面使用FileReader字符流 Read()读取文件,示例如下

    package text;
    /**
     * 使用字符流读取文本文件
     *<p>Title:FileReaderDemo</p>
     *<p>Description:</p>
     *<p>Company:</p>
     * @author MLQ
     * @date 2018年3月7日 下午12:38:35
     */
    import java.io.FileNotFoundException;
    import java.io.FileReader;
    import java.io.IOException;
    import java.io.Reader;
    
    public class FileReaderDemo {
        public static void main(String[] args) {
            //创建一个字符流对象
            Reader rd=null;
            try {
                rd=new FileReader("D://TextFile//A.txt");
                int word;//就收读取的字符
                while((word=rd.read())!=-1)
                {
                    System.out.print((char)word);
                }
            } catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }finally
            {
                if(rd!=null)
                {
                    try {
                        rd.close();
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }
        }
    }

    运行结果你会发现,乱码消失了

    3)下面使用FileReader字符流 Read(char[] b)读取文件,示例如下

          修改代码如下:

     
    package text;
    /**
     * 使用字符流读取文本文件
     *<p>Title:FileReaderDemo</p>
     *<p>Description:</p>
     *<p>Company:</p>
     * @author MLQ
     * @date 2018年3月7日 下午12:38:35
     */
    import java.io.FileNotFoundException;
    import java.io.FileReader;
    import java.io.IOException;
    import java.io.Reader;
    
    public class FileReaderDemo {
        public static void main(String[] args) {
            //创建一个字符流对象
            Reader rd=null;
            StringBuffer sb=new StringBuffer();
            try {
                rd=new FileReader("D://TextFile//A.txt");
                int word;//就收读取的字符
                char[] ch=new char[1024];
                while((word=rd.read(ch))!=-1)
                {
                    sb.append(ch,0,word);
                }
                System.out.println(sb.toString());
            } catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }finally
            {
                if(rd!=null)
                {
                    try {
                        rd.close();
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }
        }
    }

    运行结果如下:

    温馨提示:如果上述的代码 sb.append(ch,0,word)  只写数组的话,会把空格也会追加到 StringBuffer。读取文

                      件的时候最后可能没有写满数组

    4)使用BufferedReader读取文本文件

    (增强)

        BufferedReader类是Reader类的子类

        bufferedReader类带有缓冲区

        按行读取内容的ReadLine()方法

        实现步骤:

        

        构造:

        

        方法:

        

    演示代码如下:

    package text;
    import java.io.FileNotFoundException;
    import java.io.FileReader;
    import java.io.IOException;
    import java.io.Reader;
    import java.io.*;
    public class BufferedReader01 {
        public static void main(String[] args) {
            //创建一个字符流对象
            Reader rd=null;
            //创建BufferedReader对象
            BufferedReader bf=null;
            StringBuffer sb=new StringBuffer();
            try {
                rd=new FileReader("D://TextFile//A.txt");
                bf=new BufferedReader(rd);//传入Reader对象
                String word=null;//接收返回值,读到末尾返回null
                while((word=bf.readLine())!=null)
                {
                    System.out.println(word);
                }
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }finally
            {
                if(rd!=null)
                {
                    try {
                        rd.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if(bf!=null)
                {
                    try {
                        bf.close();
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }
        }
    }

    运行结果如下:

    3)字符流读和缓冲流写文件

        基类:Write    子类:FileWrite

        

        构造:

        

        方法:

        

    演示代码如下:

    3-1)使用FileWrite字符流写入文档

    package text;
    import java.io.FileWriter;
    import java.io.IOException;
    import java.io.Writer;
    public class FileWriter01 {
        public static void main(String[] args) {
            //创建写入字符流
            Writer rd=null;
            try {
                rd=new FileWriter("D://TextFile//A.txt",true);
                String s="我是写入测试编码";
                rd.write(s);//写入文档
                rd.flush();//刷新缓冲区
                System.out.println("写入成功");
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }finally
            {
                if(rd!=null)
                {
                    try {
                        rd.close();
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }
        }
    }

    3-2)使用BufferedWrite字符流写入文件

            如何提高字符流写文本文件的效率?

            解:使用FileWrite类与BufferReader类

            BufferedWrite类是Write类的子类

            BufferedWrite类带有缓冲区

            步骤:

            

        构造:

        

        方法:

        

    代码演示如下:

     
    package text;
    import java.io.BufferedReader;
    import java.io.BufferedWriter;
    import java.io.FileReader;
    import java.io.FileWriter;
    import java.io.IOException;
    import java.io.Reader;
    import java.io.Writer;
    
    public class BufferedWrite01 {
        public static void main(String[] args) {
            //创建FileWrite 和 BufferedWrite 对象
            Writer wd=null;
            BufferedWriter bw=null;
            //创建FileReader  和 BufferedReader  对象
            Reader ed=null;
            BufferedReader br=null;
            try {
                wd=new FileWriter("D:\TextFile\A.txt");
                bw=new BufferedWriter(wd);
                bw.write("我是测试员");
                bw.newLine();//换行符方法
                bw.write("负责测试程序运行问题");
                bw.flush();
                System.out.println("成功写入");
                //读取文本文件信息
                ed=new FileReader("D:\TextFile\A.txt");
                br=new BufferedReader(ed);
                String word=null;
                while((word=br.readLine())!=null)
                {
                    System.out.println(word);
                }
                
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            finally
            {
                if(wd!=null){
                    try {
                        wd.close();
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
                if(bw!=null){
                    try {
                        bw.close();
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
                if(ed!=null){
                    try {
                        ed.close();
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
                if(bw!=null){
                    try {
                        bw.close();
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }
        }
    }

    4)使用数据流读写文件

        二进制文件读写:

        使用DataInputStream  和  DataOutputStream 读写二进制文件  //属于字节流

        DataInputStream  类:

            FileInputStream的子类

            与FileInputStream类结合使用读取二进制文件

        DataOutputStream 类:

            FileOutputStream的子类

            与FileOutputStream类结合使用写二进制文件

         

    DataOutputStream:

    演示代码如下:

    实现步骤:

    [
    package text;
    import java.io.DataInputStream;
    import java.io.DataOutputStream;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    @SuppressWarnings("unused")
    public class DataInOutStream {
        @SuppressWarnings("resource")
        public static void main(String[] args)throws Exception {
            DataInputStream di=null;
            DataOutputStream ds=null;
            di=new DataInputStream(new FileInputStream("D://TextFile//dd.class"));
            ds=new DataOutputStream(new FileOutputStream("D://TextFile//coty.class"));
            int len;//接收读取的字节
            while((len=di.read())!=-1)
            {
                ds.write(len);
            }
            System.out.println("执行完毕");
            if(di!=null)
            di.close();
            ds.close();
        }
    }

    3)序列化和反序列化

        序列化和反序列化的过程

        

    序列化的步骤:

        1.实现 Serializable 接口

        2.创建对象输出流

        3.调用 writeObject()方法将对象写入文件

        4.关闭对象输出流

        使用集合保存对象,可以将集合中的所有对象序列化

        序列化构造和常用方法   

    反序列化构造和常用方法

        实现序列化 和 反序列化 演示代码:

    package text;
    import java.io.Serializable;
    public class Student implements Serializable
      {
        /**
         * 记录版本信息
         */
        private static final long serialVersionUID = 224961941376318131L;
        private String name;
        private int age;
        transient private String sex;
        public Student(String name, int age, String sex) {
            super();
            this.name = name;
            this.age = age;
            this.sex = sex;
        }
        /**
         * @return the name
         */
        public String getName() {
            return name;
        }
        /**
         * @param name the name to set
         */
        public void setName(String name) {
            this.name = name;
        }
        /**
         * @return the age
         */
        public int getAge() {
            return age;
        }
        /**
         * @param age the age to set
         */
        public void setAge(int age) {
            this.age = age;
        }
        /**
         * @return the sex
         */
        public String getSex() {
            return sex;
        }
        /**
         * @param sex the sex to set
         */
        public void setSex(String sex) {
            this.sex = sex;
        }
        
        public void show()
        {
            System.out.println("我叫:"+this.getName()+"年龄:"+this.getAge()+"性别:"+this.getSex());
        }
    }
    Student 类
    package text;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.ObjectInputStream;
    import java.io.ObjectOutputStream;
    import java.util.HashMap;
    import java.util.Iterator;
    import java.util.Map;
    import java.util.Set;
    public class TextStudent {
        @SuppressWarnings("unchecked")
        public static void main(String[] args) {
            //创建序列化对象
            ObjectOutputStream xl=null;
            //创建反序列化对象
            ObjectInputStream xl1=null;
            //初始化要序列化的对象
            Map<String,Student> map=new HashMap<String,Student>();
            Map<String,Student> map1=new HashMap<String,Student>();
            Student stu=new Student("小明",18,"男");
            Student stu1=new Student("小红",18,"女");
            map.put(stu.getName(), stu);
            map.put(stu1.getName(), stu1);
            try {
                xl=new ObjectOutputStream(new FileOutputStream("D://TextFile//xuliehua.bin"));
                xl1=new ObjectInputStream(new FileInputStream("D://TextFile//xuliehua.bin"));
                xl.writeObject(map);
                System.out.println("写入成功");
                //反序列化文件输出到控制台
                map1=(Map<String,Student>)xl1.readObject();
                Set<String> key=map1.keySet();
                Iterator<String> l=key.iterator();
                while(l.hasNext())
                {
                    String keys=l.next();
                    map1.get(keys).show();
                }
            } catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (ClassNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            finally
            {
                if(xl!=null){
                    try {
                        xl.close();
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                    e.printStackTrace();
                    }
                }
                if(xl1!=null)
                {
                    try {
                        xl1.close();
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }
    
        }
    }
    测试类

    提示:如果不希望Student类某一属性被序列化可使用 transient 修饰

     biu ~biu ~ biu ~  

    注:最后在提一句:使用序列化操作时,一定要将准备序列化的类或数据声明为可序列化操作!!!!

  • 相关阅读:
    人脸识别算法初次了解
    Linux守护进程的编程实现
    Groovy新手教程
    Matlab画图-非常具体,非常全面
    拓扑排序
    Ubuntu下很给力的下载工具
    NYOJ-289 苹果
    使用PHPExcel导入导出excel格式文件
    Visual Studio 2010 中的 Web 开发
    mysql 加入�列,改动列,删除列。
  • 原文地址:https://www.cnblogs.com/lsy131479/p/8728724.html
Copyright © 2011-2022 走看看