java IO流总结

1.IO流分类:

1)  流的方向

输入流:读取数据

输出流:写入数据

2)  数据类型

字节流

         字节输入流InputStreamàFileInputStream

                   字节缓冲输入流BufferedInputStream

         字节输出流OutputStreamàFileOutputStream

                   字节缓冲输出流BufferedOutputStream

字符流              //字符流中的close:关闭该流的同时,之前一定要刷新流

 

         字符输入流Reader

                   字符缓冲输入流BufferedReader

         字符输出流Writer

                   字符缓冲输出流BufferedWriter

2.编码和解码

package 临时;

/*编码和解码:前后的编码格式要一致!

* 编码:

*      简单理解:将能看懂的东西--->看不懂的东西

* 解码:

*      看不懂的东西---能看懂的东西

*

* 举例: 谍战片

*     

*   今天老地方见...

* 编码:

*      今---->字节---->二进制数据

*

* 解码:二进制数据-->十进制数据--->字节---->字符串

*          今

*

* 编码: 将字符串变成一个字节数组   

*      public byte[] getBytes() :平台默认编码集(默认的是Gbk)

*       public byte[] getBytes(Charset charset);"指定编码格式

*

* 解码:将字节数组--->字符串

*      public String(byte[] bytes) :使用平台默认编码集(gbk)

*      public String(byte[] bytes,Charset charset):用指定的编码格式来解码*/

import java.util.Arrays;

/**

 *计算机如何存储中文的?

 *  当前平台默认编码集 :GBK 一个中文两个字节

 *     第一个字节:一定是负数

 *     第二个字节:一般是负数,可能也会是正数,不会影响的结果.

 *

 */

public class 编码解码 {

    publicstatic void main(String[] args) {

       Strings="中国";

       byte[]bys=s.getBytes();

       //System.out.println(bys);//[B@532760d8

       System.out.println(Arrays.toString(bys));//[-42,-48, -71, -6]

       System.out.println(newString(bys));//中国

    }

 

}

 

3. 常用流

1)字节输入流:一次读取字节数组

一次读取一个字节数组的方式要比一次读取一个字节方式高效

* 一次读取一个字节数组,相当于构造一个缓冲区,有没有比一次读取一个字节数组还要高效的流

* 字节缓冲流         :

public class FileInputStreamDemo {

        

         publicstatic void main(String[] args) throws IOException {

                  

                   //复制操作:e盘下的abc.mp4复制到当前项目下,输出copy.mp4

                   //封装源文件

                   FileInputStreamfis = new FileInputStream("e://abc.mp4") ;

 

                   //封装目的地文件

                   FileOutputStreamfos = new FileOutputStream("copy.mp4") ;

                  

                   //读写操作:一次读取字节数组

                   byte[]bys = new byte[1024] ;

                   intlen = 0 ;

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

                            //边读边写

                            fos.write(bys,0, len);

                   }

                  

                   //释放资源

                   fis.close();

                   fos.close();

         }

}

2)

1.字节缓冲输入流

 *   public BufferedInputStream(InputStream in):默认缓冲区大小构造缓冲输入流对象

 *   public BufferedInputStream(InputStream in,intsize):指定缓冲区大小构造缓冲输入流对象

 *   public int read()  读取字节完毕后返回-1

 *   public int read(byte[] b,int off,int len)  返回字节数组长度,读取完毕后返回-1

 *

 *在使输入流的时候,

 *                       两种方式读取(一次读取一个字节/一次读取一个字节数在),只能用一种方式,否则,会出现错误!

//构造一个字节缓冲输入流对象

                   BufferedInputStreambis=new BufferedInputStream(new FileInputStream("bos.txt"));

                  

                   //读数据

                   //一次读取一个字节

         /*     int by = 0 ;

                   while((by=bis.read())!=-1){

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

                   }*/

                  

                  

                   //一次读取一个字节数组

                   byte[]bys = new byte[1024] ;

                   intlen = 0 ;

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

                            System.out.println(newString(bys, 0, len));

                   }

                   //释放资源

                   bis.close();

2.字节缓冲输出流:

 * 构造方式:

 *   (第一种开发中)       public BufferedOutputStream(OutputStreamout):采用的默认的缓冲区大小(足够大了) ,来构造一个字节缓冲输出流对象

 *             publicBufferedOutputStream(OutputStream out,int size):指定size缓冲区大小构造缓冲输出流对象

 *                               IllegalArgumentException- 如果 size <= 0

 *

 * 写数据的方式:

 *                      一次写一个字节

 *                               write(int by)

 *                      一次写一个字节数组的一部分

 *                               write(byte[] b,int off, int len)

 *

 * 方法:

 *             void flush() ;刷新缓冲区的流

 *

 * 面试题:

 *             字节缓冲输出流它的构造方法为什么不能直接传递路径/文件?

 *             缓冲输入流/缓冲输出流,它只是在底层内部提供一个缓冲区的数组,

 *                      底层实现文件的复制/读取/写入这些操作都依赖于基本流对象来操作

 

示例

//构造一个字节缓冲输出流对象

                   //publicBufferedOutputStream(OutputStream out)

                   /*OutputStreamout = new FileOutputStream("out.txt") ;

                   BufferedOutputStreambos = new BufferedOutputStream(out) ;*/

                  

                   //符合Java一种设计模式:装饰者设计模式(过滤器:Filter)

                   BufferedOutputStreambos = new BufferedOutputStream(new FileOutputStream("bos.txt")) ;

                  

                   //写数据

                   bos.write("hello".getBytes());

                  

                   //释放资源

                   bos.close();

3)

1.字符转换输入流:InputStreamReader

 *InputStreamReader(InputStream in) :构造一个字符转换输入流,默认编码

 *public InputStreamReader(InputStreamin,Charset cs) 构造一个字符转换输入流,指定编码

 *字符转换输入流=字节流+编码格式

 */

InputStreamReader isr = newInputStreamReader(new FileInputStream("osw.txt") ;

InputStreamReader isr = newInputStreamReader(new FileInputStream("osw.txt"),"gbk") ;

2.字符转换输出流

构造方法

 *public OutputStreamWriter(OutputStream out):使用默认的编码格式构造一个字符转换输出流对象

 *public OutputStreamWriter(OutputStream out, Charset cs):使用指定编码格式构造一个字符转换输出流对象

 

转换流的对象的创建,格式比较长,非常麻烦,Java--->转换流的便捷类

 4)

 1. 便捷类:FileReader,

Reader:抽象类:字符输入流

 *             inputStreamReader(字符转换输入流:inputStream+编码格式)

 *                               便捷类:FileReader,这个类可以直接对文件进行操作

*字符输入流读数据的方法:

 *     int read(char[] chs):读取一个字符数组

 *     int read():读取单个字符

 *

 2.便捷类FileWriter,

  Writer:抽象类:字符输出流

 *             outputStreamWriter(字符转换输出流:outputStream+编码格式)

 *                               便捷类:FileWriter,这个类可以直接对文件进行操作

*字符输出流写数据的功能:

 *     public void write(int c):写单个字符

 *     public void write(char[] cbuf):写字符数组

 *     public abstract void write(char[] cbuf, intoff,  int len):写字符数组的一部分

 *     public void write(String str):写字符串

 *     public void write(String str,int off, intlen):写字符串的某一部分

示例

//读取当前项目下的StringDemo.java文件

                   FileReaderfr = new FileReader("StringDemo.java") ;

/创建字符输出流对象

                   FileWriterfw = new FileWriter("fw.txt") ;

//字符流中的close:关闭该流的同时,之前一定要刷新流

 

*flushclose方法的区别?

 *     close:关闭该流,关闭该流对象以及它关联的资源文件,关闭之后,不能再对流对象进行操作了,否则会有异常

 *     flush:刷新该流,为了防止一些文件(图片文件/音频文件),缺失,或者没有加载到流对象中,刷新了该流,还是可以流对象进行操作

 5

1.字符缓冲输出流:

 *              特有功能:public voidnewLine():写入一个行的分隔符号

                                                                                    bw.write("\r\n");//写入换行符号

bw.newLine();//换行

BufferedWrier:文本写入字符输出流,缓冲各个字符,从而提供单个字符、数组和字符串的高效写入

 *             构造方法

 *                      BufferedWriter(Writer out):默认缓冲区大小构造字符缓冲输出流对象

 *                      BufferedWriter(Writerout,int size):指定缓冲区大小

//创建一个字符缓冲输出流对象

                   BufferedWriterbw = new BufferedWriter(new FileWriter("bw.txt")) ;

 

2.字符缓冲输入流:

 *特有功能:  public String readLine():一次读取一行

构造方法

 *             public BufferedReader(Reader in)创建一个使用默认大小输入缓冲区的缓冲字符输入流。

 *             public BufferedReader(Reader in, intsz)创建一个使用指定大小输入缓冲区的缓冲字符输入流。

//创建字符缓冲输入流对象

                   BufferedReaderbr = new BufferedReader(new FileReader("bw.txt"));

4.其他流

①内存操作流:适用于临时存储文件.(该流不需要关闭)

        内存操作输入流:byteArrayInputStream

        ByteArrayInputStream(byte[]buf)

           

        内存操作输出流: byteArrayOutputStream

        构造方法:ByteArrayOutputStream()

 内存操作流:一个程序结束后,那么这些程序的变量,就会从内存消失(马上消失的这些数据进行读取写入)

//创建内存操作输入流对象

        ByteArrayInputStream bais = newByteArrayInputStream(bys) ;

//创建内存操作输出流对象

        ByteArrayOutputStream baos = newByteArrayOutputStream() ;

②打印流

        字符打印流(针对文本进行操作:PrintWriter)

        字节打印流(printStream 和标准输出流有关系 System.out;) 

 

 PrintWriter:属于输出流

            1)只能写数据(只能针对目的地文件进行操作),不能读数据(不能针对源文件进行操作)

            2)可以针对文件直接进行操作

                如果一个类中的构造方法里面有File对象或者String类型数据,这个类可以对文本文件直接操作

                FileInputStream

                FileOutputStream

                FileWriter

                FileReader..

                PrintWriter

            3)自动刷新功能::PrintWriter(OutputStream out/Writer out,boolean autoflush);第二个参数如果是true 表示启动自动刷新功能

            4)打印的方法:print(XXX x)/println(XXX  xx)

示例

//创建一个字符打印流对象

        PrintWriter pw = new PrintWriter(newFileWriter("pw.txt")) ;

/*创建一个字符打印流对象,启动自动刷新

        PrintWriter pw = new PrintWriter(newFileWriter("pw2.txt"), true) ;*/

       

        //写数据

        /*pw.write("hello");

        pw.write("world");

        pw.write("java");*/

       

        pw.println("hello");//本身自动换行并且向pw.txt文件打印内容

       

        pw.flush(); //本身在构造的时候,就可以启动自动刷新

       

        //关闭流

        pw.close();

③数据流:针对Java基本类型的数据进行读写操作

 *数据输入流:DataInputStream   

 *数据输出流:DataOutputStream

 

示例

DataOutputStream dos= new DataOutputStream(newFileOutputStream("dos.txt")) ;

 

//给流中写入数据

dos.writeInt(10);

dos.writeShort(100);

dos.writeByte(120);

dos.writeDouble(13.34);

dos.writeFloat(12.56F);

dos.writeBoolean(true);

dos.writeChar('a');

       //读

DataInputStream dis= new DataInputStream(newFileInputStream("dos.txt")) ;

       inti = dis.readInt() ;

      

       shorts = dis.readShort() ;

       byteb = dis.readByte() ;

       doubled = dis.readDouble() ;

       floatf = dis.readFloat();

       booleanflag = dis.readBoolean() ;

       charch = dis.readChar() ;

      

       dis.close();

      

       System.out.println(i);

       System.out.println("---------");

       System.out.println(s);

       System.out.println(b);

       System.out.println(d);

       System.out.println(f);

       System.out.println(flag);

       System.out.println(ch);

④合并流

SequenceInputStream表示其他输入流的逻辑串联

 构造方法

        1.publicSequenceInputStream(InputStream s1, InputStream s2)

示例

//封装源文件

        InputStream in1 = newFileInputStream("StringDemo.java") ;

        InputStream in2 = new FileInputStream("SystemInDemo.java");

       

        //创建合并流对象

        SequenceInputStream sis = newSequenceInputStream(in1, in2) ;

        //创建一个字节缓冲输入流对象

        BufferedOutputStream bos = newBufferedOutputStream(

                newFileOutputStream("Copy.java"));

       

        //原来怎么读写,现在依然这样读写

        byte[] bys = new byte[1024] ;

        int len = 0 ;

        while((len=sis.read(bys))!=-1) {

            bos.write(bys, 0, len);

            bos.flush(); //读图片文件的时候

        }

       

        //关闭资源

        sis.close();

        bos.close();

*sequenceInputStream另一种构造方式

 2.public SequenceInputStream(Enumeration e)

 *

 *  将多个输入流对象进行合并

 *  a.txt+b.txt+c.txt--->d.txt

 示例

//定义一个集合Vector

        Vector<InputStream>v  = new Vector<InputStream>();

        //使用InputStream封装文件

        InputStream s1 = newFileInputStream("StringDemo.java") ;

        InputStream s2 = newFileInputStream("SystemInDemo.java") ;

        InputStream s3 = newFileInputStream("PrintWriterDemo.java") ;

       

        //将流对象添加到集合中

        v.add(s1) ;

        v.add(s2) ;

        v.add(s3) ;

       

        //特有功能

       Enumeration<InputStream> en =v.elements() ;

       

        //创建合并输入流对象

       SequenceInputStream sis = new SequenceInputStream(en);

        //创建字节缓冲输出流对象

        BufferedOutputStream bos = newBufferedOutputStream(new FileOutputStream("Copy.java")) ;

       

        //一次读取一个字节数组

        byte[] bys = new byte[1024] ;

        int len = 0 ;

        while((len=sis.read(bys))!=-1) {

            bos.write(bys, 0, len);

            bos.flush();

        }

       

        //关闭资源

        bos.close();

        sis.close();

 

⑤标准的输入输出流

 *      InputStreamin = System.in

 *      PrintStreamout = Syste.out ;

 *

 *jdk5以后,Java--->Scanner(InputStream in)

 *

 *  键盘录入

 *      1)Scanner

 *      2)BufferedReader里面包装字符转换输入流,包装System.in

标准输出流

PrintStream ps =System.out ;

        //PrintStream的功能

        //public void println(String x)

        ps.println("我爱高圆圆");

       

        ps.println();

//      ps.print() ;没有该功能

标准输入流

//创建输入流对象

        InputStream in = System.in ;

//使用这个类最终可不可实现一次读取一行?readLine()

        //想要实现一次读取一行,使用BufferedReader

//构造一个字符转换输入流对象

        InputStreamReader isr = newInputStreamReader(in) ;

        BufferedReader br = newBufferedReader(isr) ;

/*构造BufferedReader流对象

        BufferedReader br = newBufferedReader(in) ;  //不能直接将字节流使用BufferedReader进行包装*/

⑥序列化:将对象按照流的方式存储到文本文件中或者再网络中传输    对象---->流数据序列化流 (ObjectOutputStream)

 

    反序列化:将文本文件中的流对象或者网络传输中的流对象还原成对象   流数据--->对象  反序列化流(ObjectInputStream)

 

示例

//反序列化     将文本文件中的流对象或者网络传输中的流对象还原成对象

    private static void read() throwsFileNotFoundException, IOException, ClassNotFoundException {

       

        //创建反序列化流对象

        //public ObjectInputStream(InputStreamin)

        ObjectInputStream in = newObjectInputStream(new FileInputStream("oos.txt")) ;

       

        //读

        //publicfinal Object readObject():从 ObjectInputStream 读取对象。

        Objectobj = in.readObject() ;

       

        in.close();

        System.out.println(obj);//Person [name=高圆圆, age=27]

    }

 

   

    //序列化  将对象按照流的方式存储到文本文件中或者再网络中

    private static void write() throwsFileNotFoundException, IOException {

       

        //创建一个序列化流对象

        //public ObjectOutputStream(OutputStreamout)

        ObjectOutputStream oos = newObjectOutputStream(new FileOutputStream("oos.txt")) ;

       

        //创建一个Person类对象

        Person p = new Person("高圆圆", 27) ;

       

        //publicfinal void writeObject(Object obj)

        oos.writeObject(p);        

       

        //关闭资源

        oos.close();

 

5. Properties:表示了一个持久的属性集(简称:属性集合类)

1.Properties:表示了一个持久的属性集(简称:属性集合类)  extends Hashtable<K,V>

 Map集合的

 * 可保存在流中或从流中加载。属性列表中每个键及其对应值都是一个字符串。

 * public Properties():无参构造

//创建一个属性集合类对象

//      Properties<String,String> prop = newProperties<String,String>() ;错误的构造方式

        Properties prop = new Properties() ;

        System.out.println(prop);

        System.out.println("---------------------");

       

        //给属性集合类中的属性列表添加元素

        prop.put("高圆圆", "赵又廷") ;

        prop.put("文章", "马伊琍") ;

        prop.put("黄晓明", "baby") ;

       

        System.out.println(prop);

       

        //遍历属性集合类

        Set<Object> keySet = prop.keySet();

        for(Object key :keySet) {

            Object value = prop.get(key) ;

            System.out.println(key+"="+value);

        }

2.属性集合类的特有功能:

        publicObject setProperty(String key, String value) :给属性列表中添加键和值,并且强制都使用String,相当于put();

        publicSet<String> stringPropertyNames():遍历的功能,相当于keySet();

        publicString getProperty(String key)用指定的键在此属性列表中搜索属性,相当于get(key);

//遍历

        //获取所有的键的集合

        Set<String>keyset = prop.stringPropertyNames() ;

        for(String key:keyset) {

            //通过键找值

            Stringvalue = prop.getProperty(key) ;

            System.out.println(key+"----"+value);

3.可保存在流中或从流中加载,只能使用属性集合类

*  public void store(Writer writer,Stringcomments):把集合中的数据保存文本文件中(属性集合)

 *  publicvoid load(Reader reader):将文本文件中的数据加载到属性集合中

示例

//将文本文件中的数据加载属性集合类中

    private static void MyLoad() throwsIOException {

       

        //创建属性集合类对象

        Properties prop =new Properties() ;

       

        //public void load(Reader reader):将文本文件中的数据加载到属性集合中

        FileReader fr = new FileReader("prop.txt");

        //加载

        prop.load(fr);

        fr.close();

        System.out.println(prop);

       

    }

   

    //将属性集合中的数据保存到文本文件中

    private static void MyStore() throwsIOException {

       

        //创建一个属性集合类对象

        Properties prop = new Properties() ;

       

        //添加元素

        prop.setProperty("张三", "20") ;

        prop.setProperty("文章", "29") ;

        prop.setProperty("成龙", "55") ;

       

        //public void store(Writer writer,Stringcomments):把集合中的数据保存文本文件中(属性集合)

        FileWriter fw = newFileWriter("name.txt") ;

        //将数据保存到文本文件中

        prop.store(fw, "names'content");

       

        //释放资源

        fw.close();

6.多线程

我们学习多线程,首先先学习什么是进程,线程依赖于进程存在

 

进程:系统可以进行独立调配并且是一个不可分割 独立单元

开启一个任务管理器,很多进程(应用软件/某些客户端)

 

什么是多进程?

    多进程的意义:是为了提高CPU的使用率

    现在计算机都是多进程,假设:在听音乐的同时,也在打游戏..,他们是同时进行的吗?

        他们不是同时进行的,感觉同时,一点点CPU的时间片在同一个时刻在两个进程之间进行高效的切换!

       

什么是线程?

    线程:进程的一个独立的单元

    一个进程里面有多个任务,把每一个任务看成一个线程

多线程:

    线程之间在抢占CPU的执行权(抢占资源)

        多线程的执行具有随机性

       

        举例"

        打篮球:1v1  两个人抢占篮球的几率同样大     

             1v5   5个人抢占篮球的几率大,并不能说一定抢到 (随机性的)

JVM:Java虚拟机 识别main(主线程)

  面试题:

        JVM是多线程程序吗?至少有几条线程..

    jvm是多线程的,

        至少有2条线程...

        有主线程,main..执行这些代码,能够被Jvm识别

        在执行一些程序的时候,一些对象Jvm释放掉,原因,

        它开启了垃圾回收线程,里面GC:垃圾回收器(回收一些没有更多引用的对象或者变量...)

 

如何实现多线程程序呢?

 要实现多线程程序,需要开启进程,

 开启进程,是需要创建系统资源,但是Java语言不能创建系统资源

 只有C/C++可以创建系统资源, 利用c语言创建好的系统资源实现

 Java提供了一个类:Thread类

        实现多线程程序的步骤:

        1)将类声明为 Thread 的子类

        2)该子类应重写 Thread 类的 run 方法

        3)在主线程进行该自定义的线程类的对象的创建

 

 并行和并发(高并发:MyBatis --->IBatis:半自动化)

 前者的同时,指的是同一个时间点

 后者的同时,指的是同一个时间段,宏观上体现为同时,微观上不是同时

示例

public classMyThread extends Thread {

 

    @Override

    public void run() {

//      System.out.println("helloworld");

        for(int x = 0 ;x <200; x ++) { //两个线程都需要执行这个代码

            System.out.println(x);

        }

    }

-------------------------------------------------------------

public staticvoid main(String[] args) {

       

        //创建MyThread类对象

//      MyThread my = new MyThread() ;

       

        //当前Thread类有一个run public void run()

//      my.run();

//      System.out.println("-------------------");

//      my.run();

        //执行线程不是run方法 ,run方法的调用相当于一个普通方法的调用

       

        /*publicvoid start()使该线程开始执行;Java 虚拟机调用该线程的 run 方法。

        结果是两个线程并发地运行*/

       

        MyThread t1 = new MyThread() ;

        t1.start();

        //IllegalThreadStateException:非法状态异常,同一个线程只能被执行一次

//      t1.start();

        MyThread t2 = new MyThread() ;

        t2.start();

       

       

    }

Thread类提供了一些方法

 *      publicfinal void setName(String name):给线程起名称

 *      publicfinal String getName() :获取线程名称

Thread类中提供另一个功能:

        //publicstatic Thread currentThread():返回当前正在执行的线程对象的引用

 

publicfinal void setDaemon(boolean on) :true时,表示为守护线程

 *  将该线程标记为守护线程或用户线程。当正在运行的线程都是守护线程时,Java 虚拟机退出。(守护线程不会立即结束掉,它会执行一段时间在结束掉)

 *  该方法必须在启动线程前调用。

跟线程优先级相关的方法:

        public final int getPriority()返回线程的优先级

        public final void setPriority(intnewPriority)更改线程的优先级

        线程存在一个默认优先级

 

 public static final int MAX_PRIORITY 10        最大优先级

 public static final int MIN_PRIORITY 1         最小优先级

 public static final int NORM_PRIORITY 5        默认优先级

 

publicfinal void join():等待该线程终止 有interruputedException 中断异常

 

publicstatic void sleep(long millis):线程睡眠指定是时间毫秒值 throws InterruptedException

 

*publicfinal void stop() ;强迫线程停止执行。  不会执行了 (过时了),方法能使用的

 

publicstatic void yield()暂停当前正在执行的线程对象,并执行其他线程

  

  两个区别?

public final voidstop() ;强迫线程停止执行。    不会执行了 (过时了),方法能使用的

public voidinterrupt()中断线程。 表示中断线程的一种状态

面试题

wait()和sleep()区别?

wait(): wait()调用的,立即释放锁 (同步锁/Lock锁)

sleep():    线程睡眠,调用不会释放锁

 

实现多线程程序的第二种方式:

        1)自定义一个类,实现Runnable接口

        2)实现接口中的run方法,对耗时的代码进行操作

        3)然后在主线程中创建该类对象,将该类对象做为一个资源类,创建Thread类的对象,将刚才的资源类作为参数进行传递

示例

//自定义类实现接口,实现run方法

public classMyThread implements Runnable {

 

    @Override

    public void run() {

       

        for(int x= 0; x <100 ; x ++) {

//          System.out.println(getName()+":"+x);错误的

            System.out.println(Thread.currentThread().getName()+":"+x);

        }

    }

}

public staticvoid main(String[] args) {

       

        //创建当前类对象

        MyThread my =new MyThread() ;

       

        //实现多线程

        //public Thread(Runnable target,Stringname)

        Thread t1 = new Thread(my, "高圆圆") ;

        Thread t2 = new Thread(my, "赵又廷") ;

       

        //启动线程

        t1.start();       

        t2.start();

    }

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值