1. 数据输入输出流

1. 数据输入输出流的概述:
(1)以Stream结尾的,一般都是字节流
(2)数据输入流(DataInputStream):数据输入流允许应用程序以与机器无关方式从底层输入流中读取基本 Java 数据类型
(3)数据输出流(DataOutputStream):数据输出流允许应用程序以适当方式将基本 Java 数据类型写入输出流中

2. 数据输入输出流的特点:可以写基本数据类型,可以读取基本数据类型

3. 构造方法及常用方法

DataInputStream(InputStream in):使用指定的底层 InputStream 创建一个 DataInputStreamboolean readBoolean():读取一个boolean类型的数据 byte readByte():读取一个byte类型的数据 char readChar():读取一个char类型的数据 double readDouble():读取一个double类型的数据 float readFloat():读取一个float类型的数据 int readInt():读取一个int类型的数据 DataOutputStream(OutputStream out):创建一个新的数据输出流,将数据写入指定基础输出流void writeBoolean(boolean v) :写入一个boolean类型的数据void writeByte(int v) :写入一个byte类型的数据void writeChar(int v) :写入一个char类型的数据void writeDouble(double v) :写入一个double类型的数据void writeFloat(float v) :写入一个float类型的数据void writeInt(int v):写入一个int类型的数据【注意】读取顺序:怎么写的就怎么读,顺序不能乱

4. 代码实现

public class TestDemo01 {public static void main(String[] args) throws IOException {DataOutputStream dos = new DataOutputStream(new FileOutputStream("a.txt"));DataInputStream dis = new DataInputStream(new FileInputStream("a.txt"));dos.writeBoolean(true);dos.writeInt(100);dos.writeChar('a');dos.writeDouble(3.14);System.out.println(dis.readBoolean());   //trueSystem.out.println(dis.readInt());   //100System.out.println(dis.readChar());   //aSystem.out.println(dis.readDouble());   //3.14}
}

2. 内存操作流

1. 操作字节数组

  • ByteArrayOutputStream:ByteArrayOutputStream():创建一个新的 byte 数组输出流
  • ByteArrayInputStream:ByteArrayInputStream(byte[] buf):创建一个 ByteArrayInputStream,使用 buf 作为其缓冲区数组
  • 此流关闭无效,所以无需关闭
  • 此类实现了一个输出流,其中的数据被写入一个 byte 数组。缓冲区会随着数据的不断写入而自动增长
  • 可使用 toByteArray () 和 toString () 获取数据
  • 代码示例
public class TestDemo02 {public static void main(String[] args) throws IOException {//创建ByteArrayOutputStreamByteArrayOutputStream baos = new ByteArrayOutputStream();String str1 = "艾欧尼亚";String str2 = "诺克萨斯";String str3 = "暗影岛";String str4 = "影流";byte[] bytes1 = str1.getBytes();byte[] bytes2 = str2.getBytes();byte[] bytes3 = str3.getBytes();byte[] bytes4 = str4.getBytes();//把上面4个字节数组中的数据写入到ByteArrayOutputStream自己所维护的那个字节数组中baos.write(bytes1);baos.write(bytes2);baos.write(bytes3);baos.write(bytes4);byte[] allBytes = baos.toByteArray();System.out.println(new String(allBytes));  //艾欧尼亚诺克萨斯暗影岛影流System.out.println(baos.toString());   //艾欧尼亚诺克萨斯暗影岛影流//创建ByteArrayInputStreamByteArrayInputStream bais = new ByteArrayInputStream(allBytes);byte[] catchBytes = new byte[1024 * 8];int len = bais.read(catchBytes);System.out.println(new String(catchBytes,0,len));   //艾欧尼亚诺克萨斯暗影岛影流}
}
  • 案例:使用ByteArrayInputStream和ByteArrayOutputStream,将两首歌合并成一首歌【很麻烦,不建议这么搞,只是作为对ByteArrayInputStream和ByteArrayOutputStream的理解】
public class TestDemo03 {public static void main(String[] args) throws IOException {FileInputStream fis1 = new FileInputStream("阿刁_赵雷_128K.mp3");FileInputStream fis2 = new FileInputStream("鼓楼_赵雷_128K.mp3");ArrayList<FileInputStream> list = new ArrayList<>();list.add(fis1);list.add(fis2);//遍历集合,读取两首歌的字节数据,并把两首歌的字节数据放到内存操作流所维护的字节数组中ByteArrayOutputStream baos = new ByteArrayOutputStream();byte[] bytes = new byte[1024 * 8];int len = 0;for (FileInputStream f : list) {while ((len = f.read(bytes)) != -1){baos.write(bytes,0,len);}f.close();}//取出两首歌的字节数据byte[] allBytes = baos.toByteArray();//把两首歌的字节数据写入到同一个文件中ByteArrayInputStream bais = new ByteArrayInputStream(allBytes);FileOutputStream fos = new FileOutputStream("阿刁+鼓楼-1.mp3");byte[] bytes2 = new byte[1024 * 8];int len2 = 0;while ((len2 = bais.read(bytes2)) != -1){fos.write(bytes2,0,len2);}fos.close();System.out.println("合并完成");}
}

2. 操作字符数组

  • CharArrayWrite:CharArrayWriter():创建一个新的 CharArrayWriter
  • CharArrayReader:CharArrayReader(char[] buf):根据指定的 char 数组创建一个 CharArrayReader
  • 代码示例
public class TestDemo04 {public static void main(String[] args) throws IOException {CharArrayWriter caw = new CharArrayWriter();String str1 = "艾欧尼亚";String str2 = "诺克萨斯";String str3 = "暗影岛";String str4 = "影流";caw.write(str1);caw.write(str2);caw.write(str3);caw.write(str4);//取出CharArrayWrite所维护的字符数组char[] allChars = caw.toCharArray();System.out.println(allChars.toString());   //[C@4f023edbSystem.out.println(new String(allChars));   //艾欧尼亚诺克萨斯暗影岛影流CharArrayReader car = new CharArrayReader(allChars);char[] catchChars = new char[1024 * 8];int len = car.read(catchChars);System.out.println(new String(catchChars,0,len));   //艾欧尼亚诺克萨斯暗影岛影流}
}

3. 打印流

1. 打印流的概述
(1)打印流是单个的,只能往出写数据
(2)打印流分为字符打印流、字节打印流

2. 字符打印流
(1)构造方法

 PrintWriter(File file):使用指定文件创建不具有自动行刷新的新 PrintWriter。PrintWriter(String fileName):创建具有指定文件名称且不带自动行刷新的新 PrintWriterPrintWriter(OutputStream out, boolean autoFlush):通过现有的 OutputStream 创建新的 PrintWriterPrintWriter(Writer out, boolean autoFlush):创建新 PrintWriter//参数2:true开启自动刷新【注意】如果启用了自动刷新,则只有在调用 println、printf 或 format的其中一个方法时才可能完成此操作,而不是每当正好输出换行符时才完成

(2)成员方法

     void println():通过写入行分隔符字符串终止当前行

(3)代码示例

public class TestDemo05 {public static void main(String[] args) throws FileNotFoundException {PrintWriter pw = new PrintWriter(new File("b.txt"));pw.println(5);pw.println(3.14);pw.println(true);pw.println("java");pw.flush();pw.close();System.out.println("--------------------------------------");PrintWriter pw2 = new PrintWriter(new FileOutputStream("c.txt"),true);pw2.println(5);pw2.println(3.14);pw2.println(true);pw2.println("java");pw2.close();}
}

3. 字节打印流

(1)构造方法

     PrintStream(File file):创建具有指定文件且不带自动行刷新的新打印流。PrintStream(File file, String csn):创建具有指定文件名称和字符集且不带自动行刷新的新打印流。PrintStream(OutputStream out):创建新的打印流。PrintStream(String fileName):创建具有指定文件名称且不带自动行刷新的新打印流。PrintStream(String fileName, String csn):创建具有指定文件名称和字符集且不带自动行刷新的新打印流

(2)代码示例

public class TestDemo06 {public static void main(String[] args) throws FileNotFoundException {PrintStream ps = new PrintStream("d.txt");ps.println(100);ps.println(3.14);ps.println(true);ps.println("java");ps.flush();ps.close();}
}

(3)需求:打印流复制文本文件

//需求:打印流复制文本文件
public class TestDemo07 {public static void main(String[] args) throws IOException {/*** 这个打印流只能进行写数据,不能进行读取数据,* 那么我们应该找一个可以读取文本文件中的的数据的流对象进行读取操作.* 可以使用BufferedReader进行读取数据*/BufferedReader br = new BufferedReader(new FileReader("d.txt"));PrintWriter pw = new PrintWriter(new FileWriter("newD.txt"));String line = null;while ((line = br.readLine()) != null){pw.println(line);}br.close();pw.close();}
}

4. 随机访问流

1. 随机访问流概述
(1)RandomAccessFile:最大特点:能读能写而且有一个文件指针,可以控制指针的位置
(2)RandomAccessFile类不属于流,是Object类的子类。但它融合了InputStream和OutputStream的功能。支持对随机访问文件的读取和写入
(3)随机访问文件的行为类似存储在文件系统中的一个大型 byte 数组。存在指向该隐含数组的光标或索引,称为文件指针;输入操作从文件指针开始读取字节,并随着对字节的读取而前移此文件指针

2. 构造方法及成员方法

(1)构造方法

 RandomAccessFile(String name, String mode):创建从中读取和向其中写入(可选)的随机访问文件流,该文件具有指定名称参数1:文件名称参数2:模式"r" 以只读方式打开。调用结果对象的任何 write 方法都将导致抛出 IOException。  "rw" 打开以便读取和写入。如果该文件尚不存在,则尝试创建该文件。  "rws" 打开以便读取和写入,对于 "rw",还要求对文件的内容或元数据的每个更新都同步写入到底层存储设备。  "rwd"   打开以便读取和写入,对于 "rw",还要求对文件内容的每个更新都同步写入到底层存储设备。

(2)成员方法

 long getFilePointer():返回此文件中的当前偏移量 void seek(long pos):设置到此文件开头测量到的文件指针偏移量,在该位置发生下一个读取或写入操作int read():从此文件中读取一个数据字节 int read(byte[] b):将最多 b.length 个数据字节从此文件读入 byte 数组int read(byte[] b, int off, int len):将最多 len 个数据字节从此文件读入 byte 数组boolean readBoolean():从此文件读取一个 booleanbyte readByte():从此文件读取一个有符号的八位值char readChar():从此文件读取一个字符double readDouble():从此文件读取一个 doublefloat readFloat():从此文件读取一个 floatint readInt():从此文件读取一个有符号的 32 位整数String readLine():从此文件读取文本的下一行void write(byte[] b):将 b.length 个字节从指定 byte 数组写入到此文件,并从当前文件指针开始。 void write(byte[] b, int off, int len):将 len 个字节从指定 byte 数组写入到此文件,并从偏移量 off 处开始。 void write(int b):向此文件写入指定的字节。 void writeBoolean(boolean v):按单字节值将 boolean 写入该文件 void writeInt(int v):按四个字节将 int 写入该文件,先写高字节

(3)代码示例

public class TestDemo08 {public static void main(String[] args) throws IOException {RandomAccessFile raf1 = new RandomAccessFile("e.txt","rw");raf1.writeInt(100);raf1.writeBoolean(true);raf1.writeDouble(3.14);raf1.writeUTF("你好");RandomAccessFile raf2 = new RandomAccessFile("e.txt", "rw");int i = raf2.readInt();System.out.println(i);   //100long filePointer = raf2.getFilePointer();System.out.println("文件指针的位置" + filePointer);    //文件指针的位置4boolean b = raf2.readBoolean();System.out.println(b);    //truefilePointer = raf2.getFilePointer();System.out.println("文件指针的位置" + filePointer);    //文件指针的位置5double d = raf2.readDouble();System.out.println(d);    //3.14filePointer = raf2.getFilePointer();System.out.println("文件指针的位置" + filePointer);    //文件指针的位置13String s = raf2.readUTF();System.out.println(s);     //你好filePointer = raf2.getFilePointer();System.out.println("文件指针的位置" + filePointer);    //文件指针的位置21//可以使用seek()方法移动文件指针raf2.seek(0);int i1 = raf2.readInt();System.out.println(i1);    //100raf2.seek(13);String s1 = raf2.readUTF();System.out.println(s1);    //你好}
}

5. 序列化流与反序列化流

1. 序列化流与反序列化流概述:
(1)序列化流(ObjectOutputStream):就是把对象通过流的方式存储到文件中.注意:此对象 要重写Serializable 接口才能被序列化
(2)反序列化流(ObjectInputStream):就是把文件中存储的对象以流的方式还原成对象
(3)注意:一个对象可以被序列化的前提是这个对象对应的类必须实现Serializable接口

2. 构造方法和成员方法
(1)构造方法

 ObjectOutputStream(OutputStream out):创建写入指定 OutputStream 的 ObjectOutputStreamObjectInputStream(InputStream in):创建从指定 InputStream 读取的 ObjectInputStream

(2)成员方法

  void writeObject(Object obj):将指定的对象写入 ObjectOutputStream Object readObject():从 ObjectInputStream 读取对象

(3)代码示例

①序列化单个对象

public class TestDemo01 {public static void main(String[] args) throws IOException, ClassNotFoundException {Student student = new Student("伊泽瑞尔", 22, '男');ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("obj.txt"));oos.writeObject(student);oos.close();ObjectInputStream ois = new ObjectInputStream(new FileInputStream("obj.txt"));Student stu = (Student) ois.readObject();System.out.println(stu.getName() + "--" + stu.getAge() + "--" + stu.getSex());ois.close();}
}class Student implements Serializable {//当你实现了Serializable接口后,在给他一个标记private static final long serialVersionUID = 6007595135962043221L;private String name;private int age;private char sex;public Student() {}public Student(String name, int age, char sex) {this.name = name;this.age = age;this.sex = sex;}public static long getSerialVersionUID() {return serialVersionUID;}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 char getSex() {return sex;}public void setSex(char sex) {this.sex = sex;}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +", sex=" + sex +'}';}
}

②序列化多个对象

public class TestDemo01 {public static void main(String[] args) throws IOException, ClassNotFoundException {Student student1 = new Student("ez", 22, '男');Student student2 = new Student("noc", 25, '男');Student student3 = new Student("tf", 27, '男');ArrayList<Student> list = new ArrayList<>();list.add(student1);list.add(student2);list.add(student3);//如果我们要序列化多个对象,我们一个个去存这个对象。我我们可以把这多个对象,放到一个容器中,把容器序列化到文件中ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("newObj.txt"));oos.writeObject(list);ObjectInputStream ois = new ObjectInputStream(new FileInputStream("newObj.txt"));ArrayList<Student> myList = (ArrayList<Student>) ois.readObject();Student stu1 = myList.get(0);System.out.println(stu1.getName() + "--" + stu1.getAge() + "--" + stu1.getSex());   //ez--22--男Student stu2 = myList.get(1);System.out.println(stu2.getName() + "--" + stu2.getAge() + "--" + stu2.getSex());   //noc--25--男Student stu3 = myList.get(2);System.out.println(stu3.getName() + "--" + stu3.getAge() + "--" + stu3.getSex());   //tf--27--男oos.close();ois.close();}
}class Student implements Serializable {//当你实现了Serializable接口后,在给他一个标记private static final long serialVersionUID = 6007595135962043221L;private String name;private int age;private char sex;public Student() {}public Student(String name, int age, char sex) {this.name = name;this.age = age;this.sex = sex;}public static long getSerialVersionUID() {return serialVersionUID;}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 char getSex() {return sex;}public void setSex(char sex) {this.sex = sex;}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +", sex=" + sex +'}';}
}

6. Properties类(集合)

1. Properties类的概述:

  • Properties类继承自Hashtable,是一个双列集合,表示了一个持久的属性集
  • Properties可以保存在流中或者在流中加载,经常使用该集合来读取配置文件
  • Properties规定了键和值都是String类型

2. Properties集合特有的功能

 public Object setProperties(String key,String value):向该集合中添加数据。返回值:属性列表中指定键的旧值,如果没有值,则为 nullpublic String getProperties(String key):取出该集合的数据。返回值:value的值public Set<String> stringPropertyName():获取一个key的set集合
public class TestDemo01 {public static void main(String[] args) {Properties properties = new Properties();properties.setProperty("刀妹", "艾欧尼亚");properties.setProperty("诺手","诺克萨斯");properties.setProperty("武器大师","战争学院");String s1 = properties.getProperty("刀妹");String s2 = properties.getProperty("诺手");String s3 = properties.getProperty("武器大师");System.out.println(s1);   //艾欧尼亚System.out.println(s2);   //诺克萨斯System.out.println(s3);   //战争学院System.out.println("--------------------------------");//如果键没有找到值,则返回nullString s4 = properties.getProperty("亚索");System.out.println(s4);   //null//如果键没有找到值,第二个参数设定为一个默认值,则返回这个默认值String s5 = properties.getProperty("劫", "影流");System.out.println(s5);System.out.println("--------------------------------");Set<String> set = properties.stringPropertyNames();System.out.println(set);   //[诺手, 武器大师, 刀妹]}
}

3. Properties的load()和store()功能(和IO流配合使用)

 public void load(Reader reader):读取键值对数据把数据读取到Properties中public void store(Writer writer, String comments):把Properties集合中的键值对数据写入到文件中, comments注释
/*** 需求:把双列集合的数据,存储到文本文件中* 示例:* username = zhangsan* password = 123456* email = haha@163.com*/
public class TestDemo02 {public static void main(String[] args) throws IOException {//方式1:HashMap<String, String> hashMap = new HashMap<>();hashMap.put("username", "zhangsan");hashMap.put("password", "123456");hashMap.put("email", "haha@163.com");PrintWriter pw = new PrintWriter(new FileWriter("user1.properties"), true);hashMap.forEach(new BiConsumer<String, String>() {@Overridepublic void accept(String key, String value) {pw.println(key + "=" + value);}});pw.flush();pw.close();System.out.println("-------------------------------------");//方式2:Properties properties = new Properties();properties.setProperty("username", "zhangsan");properties.setProperty("password", "123456");properties.setProperty("email", "haha@163.com");properties.store(new FileWriter("user2.properties"), null);}
}===============================================================================================/*** 需求:*      我有一个配置文件,配置文件是简直对的数据 键=值*      我要把配置文件中的数据读取到双列集合中*/
public class TestDemo03 {public static void main(String[] args) throws IOException {//方式1:HashMap<String, String> hashMap = new HashMap<>();BufferedReader br = new BufferedReader(new FileReader("user1.properties"));String s1 = br.readLine();System.out.println(s1);   //password=123456String[] strings1 = s1.split("=");hashMap.put(strings1[0],strings1[1]);String s2 = br.readLine();System.out.println(s2);   //email=haha@163.comString[] strings2 = s2.split("=");hashMap.put(strings2[0],strings2[1]);String s3 = br.readLine();System.out.println(s3);    //username=zhangsanString[] strings3 = s3.split("=");hashMap.put(strings3[0],strings3[1]);System.out.println(hashMap);  //{password=123456, email=haha@163.com, username=zhangsan}System.out.println("-------------------------------------");/*** 方式2:*      使用Properties集合中的load()方法,直接读取到集合中*      Properties 属性集合来取读取配置文件,要求配置文件的中的数据 键和值是以=来拼接的*      一般属性配置文件的后缀名会以 .properties作为扩展名*/Properties properties = new Properties();properties.load(new FileReader("user1.properties"));System.out.println(properties);   //{password=123456, email=haha@163.com, username=zhangsan}System.out.println(properties.getProperty("email"));    //haha@163.com}
}

Java基础(28)数据输入输出流、内存操作流、打印流、随机访问流、序列化与反序列化流、Properties类(集合)相关推荐

  1. Java基础知识(七) 输入输出流

    Java基础知识 输入输出流 1. Java IO流的实现机制是什么 2. 管理文件和目录的类是什么 3. Java Socket是什么 4. Java NIO是什么 5. 什么是Java序列化 6. ...

  2. 黑马程序员_JAVA之IO流的(转换流,数据输入输出流等)

    ------- android培训.java培训.期待与您交流!---------- IO流: 笔记内容:转换流,字节输入输出流,数据输入输出流,内存操作流,随机访问流 打印流,对象序列化流,Prop ...

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

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

  4. java基础-基本的输入与输出

    java基础-基本的输入与输出 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.基本的输出 基本的输出,System.out 就是系统的标准输出设备,默认为显示器. 1>. ...

  5. Java基础复习笔记系列 七 IO操作

    Java基础复习笔记系列之 IO操作 我们说的出入,都是站在程序的角度来说的.FileInputStream是读入数据.?????? 1.流是什么东西? 这章的理解的关键是:形象思维.一个管道插入了一 ...

  6. Java基础之数据导入

    Java基础之数据导入 首先来看看数据导入的代码 导包: import java.util.Scanner;(导包的动作必须出现在类定义的上边) 创建对象: Scanner sc = new Scan ...

  7. 【Java基础】Java IO编程:输入输出流、内存流、打印流、缓冲流BufferedReader、扫描流Scanner、序列化与反序列化

    文章目录 第11章.Java IO编程 11.1 文件操作类:File 11.2 字节流与字符流 字节输出流:OutputStream OutputStream类 FileOutputStream类 ...

  8. java的 I/O 输入输出流详解

    I/O 输入输出流 流的定义: 流就是程序和设备之间嫁接起来的一根用于数据传输的管道,这个管道上有很多按钮,不同的按钮可以实现不同的功能. 这根用于数据传输的管道就是流,流就是一根管道 流一定是类,但 ...

  9. java之九 基本输入输出流

    流的概念 视频课堂:[免费]JAVA面向对象高级编程-1-数组的学习-张晨光的在线视频教程-CSDN程序员研修院 Java程序通过流来完成输入/输出.流是生产或消费信息的抽象.流通过Java的输入/输 ...

最新文章

  1. 「无心插柳柳成荫」的乔姆斯基 | 追溯 AI 大师系列
  2. css 字体大小_用一个 CSS 属性打造自适应网站
  3. hibernate笔记--缓存机制之 一级缓存(session缓存)
  4. java_codereview随笔
  5. java如何arraylist_Java如何使用ArrayList类?
  6. 用Java编写约分最简公式,2013年Java方向C组第五题
  7. 线程池----合理的设置大小
  8. 阿里云 mysql 连接 慢_记录在阿里云上遇到的一个坑-数据库连接请求缓慢
  9. aix-裸设备文件大小查看
  10. ppt设置外观样式_ppt设置图片样式_PPT如何快速修改图像样式图文教
  11. NO.5 Android Opencv 相机人脸识别
  12. 如何用python计算圆周率_使用MicroPython计算任意位数圆周率
  13. Django报错异常django.core.exceptions.ImproperlyConfigured: Specifying a namespace in include() without
  14. 开源BI框架对比选择 Superset-Redash-Metabase
  15. 来自清华学子的一个自述---在树洞里
  16. 基于Python(Django)+MongoDB实现的(Web)新闻采集和订阅系统【100010319】
  17. extern声明变量或函数
  18. 从零开始在Linux服务器上搭建JAVA开发运行环境
  19. WIN7/WIN10 临时及永久 强制关闭驱动签名验证
  20. python随机抽号_Python 随机从字典中抽取数据

热门文章

  1. 记录vue中使用scss报红但是不影响css样式,代码行会提示css-rcurlyexpected这个问题
  2. 大话西游手游服务器维护要多久,大话西游手游2018年8月2日维护公告
  3. 《Android 应用案例开发大全(第3版)》——第2.7节线程相关类
  4. STM32的3种低功耗模式
  5. 锡山中专计算机应用,无锡市锡山中等专业学校
  6. 四相八拍步进c语言程序,5线四相八拍步进电机的C51演示程序
  7. 笔记本开启热点后,笔记本网页无法打开,QQ可以使用,
  8. 【Android游戏开发十八】解放手指,利用传感器开发游戏!(本文讲解在SurfaceView中用重力传感器控制圆球的各方向移动)
  9. java手机买_java学习之买手机
  10. SkyIDC - 国际云服务厂商