JAVASE_IO流

  1. IO流是用来处理设备之间的数据传输
  2. java对数据的操作都是通过流的方式
  3. java把处理流的对象都存放在IO包中
  4. 流按操作数据分为两种:字节流和字符流(字符在生活中用的比较多,因此把字节流从字节流中独立出来(字符流中存在编码表))
  5. 字符流基于字节流,读出来的字节数组对应的编码查询转换后就成了一个个码值显示成文字
  6. 流按流向分:输入流和输出流
  7. IO的常用基类:
  8. 字节流的抽象基类:InputStream,OutpuStream
  9. 字符流的抽象基类:Reader , writer
  10. 这四个基类派生出来的子类名称都是以其父类名作为其子类的后缀名的,前缀名为该类的功能

  11. *:其实java并不能直接去写数据的,java是调用了windows和linux等操作系统的写数据的方法
  12. *:注意在写java代码时,向windows的记事本中写数据写换行符:"\r\n"来表示,windows记事本不能识别\n换行
  13. 1.Writer
  14. FileWriter:(写数据)
  15. //创建一个新的文件对象如果该文件已经存在了该文件,则原有的文件将会被覆盖
  16. //所有在创建该对象时应该先判断
  17. if()
  18. FileWriter fw = new FileWriter("d:\\demo.txt");

  19. eg:
  20. FileWriter fw = null ;
  21. File file = new File("d:\\demo.txt");
  22. if(file.exists()){
  23. //执行本条语句必定会创建file指定路径下的文件,若文件存在则会覆盖该该路径下的文件
  24. fw = new FileWriter(file,true);//如果文件存在则追加
  25. }else{
  26. fw = new FileWriter(file );
  27. }
  28. fw.write("1234");//并未直接写入文件,而是写入buff缓存(内存中,缓存满才写入文件中)
  29. // fw.flush();//刷新缓冲,虽然缓存未满也写入文件(内存中的数据也写入文件中)
  30. fw.close();//关闭流资源之前,也会把内存的缓冲刷新,也会把数据刷新到文件
  31. BufferWriter:(字符缓冲写出流)
  32. bw.newLine();//写入一个换行符,针对不同平台性实现不同的换行(实现的是夸平台行)
  33. 2.Reader:
  34. FileReader:(读取数据)(采用了其默认的字符编码来进行读取数据:获取的是当前操作系统中的编码)
  35. BufferReader:(字符缓冲读入流):缓冲区的出现为为了提高流的操作效率,所以在创建缓冲区对象之前应该先创建缓冲流对象
  36. eg:
  37. FileWriter fw = new FileWriter("d:\\demo.txt");
  38. BufferWriter bw = new BufferWriter(fw);
  39.  
  40. //Buffer拷贝
  41. public void copyByBuffer() throws IOException{
  42. BufferedReader br = new BufferedReader(new FileReader(new File("d:\\demo.txt")));
  43. BufferedWriter bw = new BufferedWriter(new FileWriter( new File("d:\\demoCopy.txt")));
  44. String str;
  45. while(( str = br.readLine()) != null ){
  46. bw.write(str);//并不会自动换行
  47. bw.newLine();
  48. bw.flush();//在缓冲区的后面立马进行flush的作用是:防止计算机断电后的数据的丢失
  49. }
  50. br.close();
  51. bw.close();
  52. }
  53. //BufferedReader是对FileReader的功能的加强,这是一种装饰设计模式
  54. *:字节流和字符流的读写方式差异不大,最主要的区别是,字节流读写时用的是byte(字节),字符流读写时用的是char(字符)
  55. 字节流能读写所有的文件类型数据(操作的都是字节)
  56. *:注意Writer和Reader都只能操作的是字符流对象

  57. 3.InputStream:(字节读入流)
  58. 4.OutputStream:(字节输出流)
  59. 5.重写BufferedInputStreeam();采用read方法读取的字符:
  60. 读取的数据格式为32位:
  61. 11111111 11111111 11111111 10111101(read方法读取的二进制数据每次为一个字节,前方24个字节自动补1,write方法只写后面8位)
  62. 00000000 00000000 00000000 11111111(为了保证能通过条件判断in.read()!=-1,通常为们把读取的数据和0x000000ff相与再写出到write)
  63. ------------------------------------
  64. 00000000 00000000 00000000 10111101(最后8位有效)

  65. 6.读取键盘录入
  66. System.out:对应标准的输出设备
  67. System.in:对象的是标准的输入设备
  68. InputStream in = System.in;


  69. 7.InputStreamReader(转换流:字节流使用字符流中的readLine方法)
  70. 8.OutputStreamWriter(转换流:将字符流转换为字节流写出)


  71. 9.PrintStream:(改变控制台流向)
  72. 1.把控制台录入的信息输出到文件中
  73. PrintStream p = new PrintStream(new FileOutputStream(new File("d:\\demo.txt"),true));//改变目的流向
  74. 2.把控制台录入的信息输出到文件中
  75. BufferedWriter bw = new BufferedWriter( new OutputStreamWriter( new FileOutputStream("d:\\demo.txt" , true)));
  76. 10.总结:
  77. 1.明确操作的文件时字节流还是字符流
  78. 2.BufferedWriter和BufferedReader是字符流的缓冲流,若要操作字节流需要采用转换流包装:InputStreamReader或OutputStreamWriter
  79. 3.通过设备来进行区分:
  80. 原设备:内存,硬盘,键盘。
  81. 目的设备:内存,硬盘,控制台。

  82. File类:
  83. 1.用来将文件或者文件夹封装成对象
  84. 2.方便将文件或文件夹进行操作
  85. 3.File对象可以作为参数传递给流的构造函数
  86. File.separator:与平台无关的系统分隔符,可替代"\\"或"/"
  87. File类常用的方法:
  88. 1.创建
  89. 2.删除(在windows中删除目录是从里面往外面删除的)
  90. 3.判断
  91. 4.获取信息
  92. 5.对File实例进行判断时,先判断该文件是否存在,再判断该实例是否是文件或目录
  93. 6.文件管理:(把文件的绝对路径保存到一个文本文件中,方便下次调用(持久化存储))
  94.  
  95. properties:(map集合的子类和IO流的结合体)

  96. 打印流:保证了数据的原样性
  97. printStream:(字节打印流:可以将各种各样的数据类型的数据都原样输出)
  98. printWriter:(字符打印流:)

  99. 合并流:
  100. SequenceInputStream:(可将多个流合并为一个流)
  101. 对象流:ObjectInputStream,ObjectOutputStream


  102. 管道流:pipedInputStream,PipedOutputStream:(管道输入流和管道输出流可以直接对接使用)
  103. 通常数据从某个线程由PipedInputStream读取,并有其他的线程写入到PipedOuputStream,
  104. 不建议对这连个对象使用单线程,这样可能会照成死锁。


  105. 随机访问流:RandomAccessFile(随机访问文件的读取和写入)
  106. 作用:可以实现多线程的下载。
  107. 字符流的出现是为了方便操作字符。更总要的是加入了编码转换
  108. 通过子类转换流来完成:
  109. InputStreamReader
  110. OutputStremWriter
  111. 在两个对象进行构造的时候可以加入字符集。

  112. 字符编码:
  113. ASCII:美国标准信息交换码,用一个字节的7位表示
  114. ISO8859-1:拉丁码表,欧洲码表。用一个字节的8位表示。
  115. GB2312:中国的中文编码表
  116. GBK:中国的中文编码表的升级版,融合了更多的的中文字符。
  117. Unicode:国际标准码,融合了许多文字,java语言就是使用的Unicode
  118. UTF-8(Unicode编码的升级版):最多用三个字节来表示一个字符。

  119. 编码:字符串编程字节数组 String --> byte[]  str.getBytes(charSetName);
  120. 解码:字节数组编程字符串 byte[] --> String  new String(byte[] , charSetName);
    package io流;
    
    import java.io.BufferedReader;
    import java.io.BufferedWriter;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.FileReader;
    import java.io.FileWriter;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.io.OutputStream;
    import java.io.OutputStreamWriter;
    import java.io.PrintStream;
    import java.io.RandomAccessFile;
    import java.text.SimpleDateFormat;
    import java.util.Arrays;
    import java.util.Comparator;
    import java.util.Date;
    import java.util.Enumeration;
    import java.util.LinkedList;
    import java.util.Properties;
    
    import org.junit.Test;
    
    /**
     * 
     * @author Administrator
     * 
     */
    public class IO加强版 {
    
    	@Test
    	public void test() throws Exception {
    		FileWriter fw = null;
    		File file = new File("d:\\demo.txt");
    		if (file.exists()) {
    			// 执行本条语句必定会创建file指定路径下的文件,若文件存在则会覆盖该该路径下的文件
    			fw = new FileWriter(file, true);// 如果文件存在则追加
    		} else {
    			fw = new FileWriter(file);
    		}
    		fw.write("1234");// 并未直接写入文件,而是写入buff缓存(内存中,缓存满才写入文件中)
    		// fw.flush();//刷新缓冲,虽然缓存未满也写入文件(内存中的数据也写入文件中)
    		fw.close();// 关闭流资源之前,也会把内存的缓冲刷新,也会把数据刷新到文件
    	}
    
    	@Test
    	// IO异常处理
    	public void test1() {
    		FileWriter fw = null;
    		try {
    			fw = new FileWriter("D:\\demo.txt");
    			// 不能只对该语句做异常处理,因为若本句发生异常,
    			// 后面的代码便没有意义,所有,这里把整个代码块放入try-catch中
    			fw.write("123");
    			fw.close();
    		} catch (IOException e) {
    			System.out.println(e.toString());
    		} finally {
    			try {
    				if (fw != null) {
    					fw.close();
    				}
    			} catch (IOException e) {
    				// TODO Auto-generated catch block
    				e.printStackTrace();
    			}
    		}
    	}
    	
    	@Test
    	public void readerTest() throws Exception{
    		
    		//创建一个文件读取流对象,和指定的文件相关联
    		FileReader fr = new FileReader("D:\\demo.txt");
    		System.out.println(fr.getEncoding());
    		int len;
    		char[] buff= new char[1024];
    		while((len = fr.read(buff)) >0){
    				System.out.println(new String(buff  , 0 , 1024));
    		}
    		fr.close();
    	}
    	
    	@Test
    	/*
    	 * 拷贝文件
    	 * 注意:文件操作,尽量不要从文件读取一个字符然后就写入该字符到文件,
    	 * 			应该尽量的先把读取的字符存储到缓冲区(内存当中),然后再一次性写入到磁盘中,
    	 * 			减少磁头的移动,加快拷贝的速度
    	 * 文件:是存储在磁盘上的,每次的读和写都要移动磁头,花费时间的。
    	 */
    	public void copyTest() throws IOException{
    		File fromFile = new File("D:\\demo.txt");
    		File toFile = new File("D:\\demo2.txt");
    		if(!fromFile.exists())
    			System.exit(0);
    		
    		FileReader fr = new FileReader(fromFile);
    		FileWriter fw = new FileWriter(toFile,true);
    		
    		int len;
    		char buff[] =  new char[1024];
    		
    		while((len = fr.read(buff))>0){
    			fw.write(new String(buff,0 ,len));
    		}
    			fr.close();
    			fw.close();
    	}
    	
    	@Test
    	/*
    	 * 缓冲写:bufferedWriter
    	 */
    	public void bufferrdWriterTest() throws IOException{
    		
    		FileWriter fw = new FileWriter("d:\\demo.txt");
    		
    		BufferedWriter bw = new BufferedWriter(fw);
    		
    		bw.write("bufferedWriter 123");
    		
    		bw.newLine();//写入一个换行符,针对不同平台性实现不同的换行(实现的是夸平台行)
    		
    		bw.flush();
    		bw.close();
    		//fw.close();此句可以不写 ,关闭缓冲区,流也就自然关闭了 
    	}
    	
    	/*
    	 * 缓冲读取流
    	 */
    	@Test
    	public void bufferedRederTest() throws IOException{
    		
    		FileReader fr = new FileReader(new File("d:\\demo.txt"));
    		
    		BufferedReader br = new BufferedReader(fr);
    		
    		String str;
    		while((str = br.readLine())!=null){
    			System.out.println(str);
    		}
    		
    		br.close();
    	}
    	
    	
    	@Test
    	/*
    	 * Buffer拷贝
    	 */
    	public void copyByBuffer() throws IOException{
    		BufferedReader br = new BufferedReader(new FileReader(new File("d:\\demo.txt")));
    		BufferedWriter bw = new BufferedWriter(new FileWriter( new File("d:\\demoCopy.txt")));
    	
    			String str;
    		while(( str = br.readLine()) != null ){
    			bw.write(str);//并不会自动换行
    			bw.newLine();
    			bw.flush();//在缓冲区的后面立马进行flush的作用是:防止计算机断电后的数据的丢失
    		}
    		br.close();
    		bw.close();
    	}
    	
    	/**
    	 * 字节流的对文件的读取
    	 * @throws Exception 
    	 */
    	@Test
    	public void inputStreamTest() throws Exception{
    		
    			FileInputStream in = new FileInputStream( new File( "d:\\demo.txt"));
    			
    			int len;
    			byte buff[]  = new byte[1024];
    			
    			while(( len = in.read( buff ) ) > 0 ){
    				System.out.println(new String ( buff , 0 , len ) );
    			}
    			
    			in.close();
    	}
    	
    	@Test
    	//字节流输出文件
    	public void outputStreamTest() throws Exception{
    		
    		FileOutputStream out = new FileOutputStream(new File("d:\\demo.txt"));
    		
    		String str = "asdasdasd";
    		
    		out.write(str.getBytes());
    		
    		out.close();
    		
    	}
    	
    	@Test
    	/*
    	 * 拷贝图片
    	 * 1.字符
    	 */
    	public  void copyPicTest() throws IOException{
    		FileInputStream in = new FileInputStream( new  File ("d:\\ios.jpg") );
    		FileOutputStream out = new FileOutputStream( new File("d:\\ios2.jpg"));
    		
    		int len;
    		byte[] buff = new byte[1024];
    		
    		while( ( len = in .read( buff ) ) > 0 ){
    				out.write(buff);
    		} 
    	}
    	
    	/**
    	 * 拷贝avi视频
    	 * @throws IOException 
    	 */
    	@Test
    	public void coptAviTest() throws IOException{
    		FileInputStream fis = new FileInputStream("E:\\BaiduYunDownload\\黑马程序员_毕向东_Java基础视频教程\\毕向东_Java基础视频教程下载_第19天\\黑马程序员_毕向东_Java基础视频教程第19天-12-IO流(拷贝图片).avi");
    		FileOutputStream fos = new FileOutputStream("D:\\图片复制.avi");
    		
    		int len = 0;
    		byte buff[] = new byte[1024];
    		
    		while( ( len = fis.read(buff)) > 0 ){
    			fos.write(buff);
    		}
    		fis.close();
    		fos.close();
    	}
    	
    	/**
    	 * 键盘的录入
    	 * @throws IOException 
    	 */
    	@Test
    	public void SystemInTest() throws IOException{
    		InputStream  in = System.in;
    		
    		int ch;
    		while((ch = in.read()) > 0){
    			System.out.println((char)ch);
    		}
    	}
    	/**
    	 * 转换流:字节流转换到字符流对象的使用
    	 * @throws Exception 
    	 */
    	@Test
    	public void changeStream() throws Exception{
    		InputStream in = System.in;
    		
    		InputStreamReader isr = new InputStreamReader( in );
    		
    		BufferedReader br = new BufferedReader(isr);
    		
    		String str;
    		while( (str = br .readLine() ) != null){
    			System.out.println(str);
    		}
    		br.close();
    	}
    	
    	/**
    	 * 字符流转字节流输出
    	 * @throws Exception 
    	 */
    	@Test
    	public void BufferedWriteOuputStreamWrite() throws Exception{
    		
    		InputStream in = System.in;
    		InputStreamReader inr = new InputStreamReader(in);
    		BufferedReader br = new BufferedReader(inr);//转换成字符流
    		
    		OutputStream out = System.out;
    		OutputStreamWriter osw = new OutputStreamWriter(out);//转换成字节流输出
    		BufferedWriter bw = new BufferedWriter(osw);
    		
    		String str;
    		while( ( str = br.readLine()) !=null){
    			bw.write(str);
    			bw.newLine();
    			bw.flush();
    		}
    		bw.close();
    		br.close();
    	}
    	
    	/**
    	 * 将控制台输入的信息打印到d:\\demo.txt文件中(可以用作日志文件)
    	 * @throws Exception 
    	 */
    	@Test
    	public void 形同日志的生成() throws Exception{
    		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    		PrintStream p = new PrintStream(new FileOutputStream(new File("d:\\demo.txt"),true));//改变目的流向
    		//也可以采用以下方式
    		//BufferedWriter bw = new BufferedWriter( new OutputStreamWriter( new FileOutputStream("d:\\demo.txt" , true)));
    		//System.setIn(new  FileInputStream("d:\\demo.txt"));
    		System.setOut(p);
    		String str;
    		while( ( str = br . readLine() ) != null ){
    			if("over".equals(str))
    				break;
    			System.out.println(str);
    		}
    		p.close();
    		br.close();
    	}
    	
    	/**
    	 * 把异常信息打印到日志文件中
    	 */
    	@Test
    	public void printTOLog(){
    		try{
    		int[] intrr = new int[2];
    		int a = intrr[3];
    		}catch(Exception e){
    			
    			try {
    				Date date = new Date();
    				SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    				String s = sdf.format(date);
    				
    				System.setOut(new PrintStream(new FileOutputStream("d:\\demo.log",true)));
    				System.out.println(s+" :");
    			} catch (FileNotFoundException e1) {
    				// TODO Auto-generated catch block
    				e1.printStackTrace();
    			}
    			
    			e.printStackTrace(System.out);
    		}
    	}
    	
    	@Test
    	/**
    	 * 递归遍历文件夹
    	 */
    	public void testThreeWalk(){
    /*		File f = new File("D:\\ACM");
    		
    		File[] fs = f.listFiles();
    		
    		for(File file : fs){
    			System.out.println(file.getParent()+":"+file.getName());
    		}*/
    		threeWalk(new File("D:\\ACM"));
    	}
    	
    	public void threeWalk(File file){
    		if(file.isDirectory()){
    				System.out.println("isD:"+file.getParent()+file.getName());
    				//String path = file.getParent()+"\\"+file.getName();
    				//System.out.println("path:"+path);
    				File[] fs = file.listFiles();
    			for(File f : fs){
    					threeWalk(f);
    				}
    		}else{
    			System.out.println("isF:"+file.getParent()+file.getName());
    		}
    	}
    	
    	/**
    	 * 删除文件目录
    	 */
    	@Test
    	public void deleteDir(){
    		threeWalkDel(new File("C:\\Users\\Administrator\\Desktop\\a.txt"));
    	}
    	
    	public  void threeWalkDel(File file){
    		File [] fs = file.listFiles();
    		System.out.println(fs.length);
    		for(int i = 0 ; i < fs.length ; i++){
    			if(fs[i].isDirectory())
    				threeWalkDel(fs[i]);
    			else
    				System.out.println(fs[i].toString()+"被删除:"+fs[i].delete());
    		}
    		System.out.println(file.toString()+":"+file.delete());
    	}
    	
    	/**
    	 * 读取properties配置文件
    	 * @throws IOException 
    	 */
    	@Test
    	public void readProperties() throws IOException{
    		//创建pro对象
    		Properties prop = new Properties();
    		//加载文件
    		BufferedReader br = new BufferedReader(new FileReader("src\\io流\\conf.properties"));
    		
    		String line;
    		while(( line = br.readLine() )!=null){
    			System.out.println(line);
    			if("".equals(line.trim()))
    				continue;
    			String key = line.substring(0 , line.lastIndexOf("="));
    			String value = line.substring(line.lastIndexOf("=") + 1);
    			prop.setProperty(key, value);
    		}
    		br.close();
    		
    		//读出属性
    		Enumeration ems =  prop.propertyNames();
    		while(ems.hasMoreElements()){
    			String key = (String)ems.nextElement();
    		System.out.println("key:"+key+"value:"+prop.getProperty(key));
    		}
    		
    	}
    	
    	/**
    	 * 随机读写流:RandomAccessFile();
    	 * @throws IOException 
    	 */
    	@Test
    	public void RandomAccessTest() throws IOException{
    		//
    		RandomAccessFile raf = new RandomAccessFile("d:\\raf.txt","rw");
    		raf.write("张三".getBytes());
    		raf.writeInt(1000);
    		
    	//	raf.write("李四".getBytes());
    //		raf.write(102);
    		
    		raf.close();
    		
    /*		byte[] buf = new byte[12];
    		raf.read(buf);
    		System.out.println(new String(buf));*/
    	}
    	
    	/**
    	 *文件读写:字符编码 
    	 * @throws IOException 
    	 */
    	@Test
    	public void encodeTest() throws IOException{
    		BufferedReader isr = new BufferedReader(new InputStreamReader( new FileInputStream("d:\\utf-8.txt"),"GBK"));
    		//OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("d:\\utf-8.txt",true),"UTF-8");
    		//osw.write("你好");
    		//osw.close();
    		String line;
    		while((line = isr.readLine()) != null){
    			
    			System.out.println(line);
    			
    			byte[] bs = line.getBytes("GBK");//反向解码
    			System.out.println(new String(bs,"UTF-8"));//再重新编码
    			
    		}
    		isr.close();
    	}
    	
    	/**
    	 * 练习:从键盘输入学生信息eg:张三,30,40,60,。并计算出总成绩按照总成绩排序保存在stud.txt中
    	 * @throws IOException 
    	 */
    	@Test
    	public void StuSumTest() throws IOException{
    		BufferedReader br = new BufferedReader(new InputStreamReader( System . in ,"GBK" ));
    		BufferedWriter bw = new BufferedWriter(new FileWriter("d:\\stud.txt"));
    		
    		String instr;
    		LinkedList<Student> llist = new LinkedList<Student> ();
    		while((instr = br.readLine()) != null){
    				if("over".equals(instr))
    					break;
    				instr = instr.replaceAll(",", ",").trim();
    				System.out.println(instr);
    				String[] infos = instr.split(",");
    				System.out.println("infos:"+infos[0]+","+infos[1]+","+infos[2]+","+infos[3]);
    				Student stu = new Student(infos[0] ,Integer.parseInt(infos[1]) , Integer.parseInt(infos[2]),Integer.parseInt(infos[3]));
    				
    				llist.add(stu);	
    		}
    		br.close();
    		bw.close();
    		Student[] stus = (Student[]) llist.toArray();
    		
    		for(int i = 0 ; i < stus.length ; i ++){
    			System.out.println(stus[i].getName()+":"+stus[i].getSum());
    		}
    		
    		Arrays.sort(stus, new Comparator<Object>(){
    			@Override
    			public int compare(Object o1, Object o2) {
    				// TODO Auto-generated method stub
    				Student s1 = (Student) o1;
    				Student s2 = (Student) o2;
    				return s1.getSum()>=s2.getSum()?1:-1;
    			}
    		} );
    		for(int i = 0 ; i < stus.length ; i ++){
    			System.out.println(stus[i].getName()+":"+stus[i].getSum());
    		}
    		
    	}
    	
    }
    
    class Student{
    	private String name;
    	private int subj1;
    	private int subj2;
    	private int subj3;
    	private int sum=0;
    	
    	public  Student(String name){
    		this. name = name;
    	}
    	public  Student(String name, int subj1 , int subj2 , int subj3){
    		this. name = name;
    		this.subj1 = subj1;
    		this.subj2 = subj2;
    		this.subj3 = subj3;
    	}
    
    	public String getName() {
    		return name;
    	}
    
    	public void setName(String name) {
    		this.name = name;
    	}
    
    	public int getSubj1() {
    		return subj1;
    	}
    
    	public void setSubj1(int subj1) {
    		this.subj1 = subj1;
    	}
    
    	public int getSubj2() {
    		return subj2;
    	}
    
    	public void setSubj2(int subj2) {
    		this.subj2 = subj2;
    	}
    
    	public int getSubj3() {
    		return subj3;
    	}
    
    	public void setSubj3(int subj3) {
    		this.subj3 = subj3;
    	}
    
    	public int getSum() {
    		return this.subj1+this.subj2+this.subj3;
    	}
    	
    	public boolean  compareSum(Student stu){
    		return this.getSum()>stu.getSum()?true:false;
    	}
    }
    

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值