代码如下:

  1. package com.example.downloaderstopsart;
  2. import java.util.ArrayList;
  3. import java.util.HashMap;
  4. import java.util.List;
  5. import java.util.Map;
  6. import android.os.Bundle;
  7. import android.os.Handler;
  8. import android.os.Message;
  9. import android.os.StrictMode;
  10. import android.app.ListActivity;
  11. import android.view.View;
  12. import android.widget.LinearLayout;
  13. import android.widget.LinearLayout.LayoutParams;
  14. import android.widget.ProgressBar;
  15. import android.widget.SimpleAdapter;
  16. import android.widget.TextView;
  17. import android.widget.Toast;
  18. public class MainActivity extends ListActivity  {
  19. // 固定下载的资源路径,这里可以设置网络上的地址
  20. private static final String URL = "http://10.81.36.193:8080/";
  21. // 固定存放下载的音乐的路径:SD卡目录下
  22. private static final String SD_PATH = "/mnt/sdcard/";
  23. // 存放各个下载器
  24. private Map<String, Downloader> downloaders = new HashMap<String, Downloader>();
  25. // 存放与下载器对应的进度条
  26. private Map<String, ProgressBar> ProgressBars = new HashMap<String, ProgressBar>();
  27. /**
  28. * 利用消息处理机制适时更新进度条
  29. */
  30. private Handler mHandler = new Handler() {
  31. public void handleMessage(Message msg) {
  32. if (msg.what == 1) {
  33. String url = (String) msg.obj;
  34. int length = msg.arg1;
  35. ProgressBar bar = ProgressBars.get(url);
  36. if (bar != null) {
  37. // 设置进度条按读取的length长度更新
  38. bar.incrementProgressBy(length);
  39. if (bar.getProgress() == bar.getMax()) {
  40. Toast.makeText(MainActivity.this, "下载完成!", 0).show();
  41. // 下载完成后清除进度条并将map中的数据清空
  42. LinearLayout layout = (LinearLayout) bar.getParent();
  43. layout.removeView(bar);
  44. ProgressBars.remove(url);
  45. downloaders.get(url).delete(url);
  46. downloaders.get(url).reset();
  47. downloaders.remove(url);
  48. }
  49. }
  50. }
  51. }
  52. };
  53. @Override
  54. public void onCreate(Bundle savedInstanceState) {
  55. super.onCreate(savedInstanceState);
  56. setContentView(R.layout.activity_main);
  57. showListView();
  58. StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder().detectDiskReads().detectDiskWrites().detectNetwork().penaltyLog().build());
  59. StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder().detectLeakedSqlLiteObjects().detectLeakedClosableObjects().penaltyLog().penaltyDeath().build());
  60. }
  61. // 显示listView,这里可以随便添加音乐
  62. private void showListView() {
  63. List<Map<String, String>> data = new ArrayList<Map<String, String>>();
  64. Map<String, String> map = new HashMap<String, String>();
  65. map.put("name", "mm.mp3");
  66. data.add(map);
  67. map = new HashMap<String, String>();
  68. map.put("name", "pp.mp3");
  69. data.add(map);
  70. map = new HashMap<String, String>();
  71. map.put("name", "tt.mp3");
  72. data.add(map);
  73. map = new HashMap<String, String>();
  74. map.put("name", "ou.mp3");
  75. data.add(map);
  76. SimpleAdapter adapter = new SimpleAdapter(this, data, R.layout.list_item, new String[] { "name" },
  77. new int[] { R.id.tv_resouce_name });
  78. setListAdapter(adapter);
  79. }
  80. /**
  81. * 响应开始下载按钮的点击事件
  82. */
  83. public void startDownload(View v) {
  84. // 得到textView的内容
  85. LinearLayout layout = (LinearLayout) v.getParent();
  86. String musicName = ((TextView) layout.findViewById(R.id.tv_resouce_name)).getText().toString();
  87. String urlstr = URL + musicName;
  88. String localfile = SD_PATH + musicName;
  89. //设置下载线程数为4,这里是我为了方便随便固定的
  90. int threadcount = 4;
  91. // 初始化一个downloader下载器
  92. Downloader downloader = downloaders.get(urlstr);
  93. if (downloader == null) {
  94. downloader = new Downloader(urlstr, localfile, threadcount, this, mHandler);
  95. downloaders.put(urlstr, downloader);
  96. }
  97. if (downloader.isdownloading())
  98. return;
  99. // 得到下载信息类的个数组成集合
  100. LoadInfo loadInfo = downloader.getDownloaderInfors();
  101. // 显示进度条
  102. showProgress(loadInfo, urlstr, v);
  103. // 调用方法开始下载
  104. downloader.download();
  105. }
  106. /**
  107. * 显示进度条
  108. */
  109. private void showProgress(LoadInfo loadInfo, String url, View v) {
  110. ProgressBar bar = ProgressBars.get(url);
  111. if (bar == null) {
  112. bar = new ProgressBar(this, null, android.R.attr.progressBarStyleHorizontal);
  113. bar.setMax(loadInfo.getFileSize());
  114. bar.setProgress(loadInfo.getComplete());
  115. ProgressBars.put(url, bar);
  116. LinearLayout.LayoutParams params = new LayoutParams(LayoutParams.FILL_PARENT, 5);
  117. ((LinearLayout) ((LinearLayout) v.getParent()).getParent()).addView(bar, params);
  118. }
  119. }
  120. /**
  121. * 响应暂停下载按钮的点击事件
  122. */
  123. public void pauseDownload(View v) {
  124. LinearLayout layout = (LinearLayout) v.getParent();
  125. String musicName = ((TextView) layout.findViewById(R.id.tv_resouce_name)).getText().toString();
  126. String urlstr = URL + musicName;
  127. downloaders.get(urlstr).pause();
  128. }
  129. }

DBHelper:

  1. package com.example.downloaderstopsart;
  2. import android.content.Context;
  3. import android.database.sqlite.SQLiteDatabase;
  4. import android.database.sqlite.SQLiteOpenHelper;
  5. /**
  6. * 建立一个数据库帮助类
  7. */
  8. public class DBHelper extends SQLiteOpenHelper {
  9. // download.db-->数据库名
  10. public DBHelper(Context context) {
  11. super(context, "download.db", null, 1);
  12. }
  13. /**
  14. * 在download.db数据库下创建一个download_info表存储下载信息
  15. */
  16. @Override
  17. public void onCreate(SQLiteDatabase db) {
  18. db.execSQL("create table download_info(_id integer PRIMARY KEY AUTOINCREMENT, thread_id integer, "
  19. + "start_pos integer, end_pos integer, compelete_size integer,url char)");
  20. }
  21. @Override
  22. public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
  23. }
  24. }
  1. DownloadInfo:
  1. package com.example.downloaderstopsart;
  2. public class DownloadInfo {
  3. private int threadId;// 下载器id
  4. private int startPos;// 开始点
  5. private int endPos;// 结束点
  6. private int compeleteSize;// 完成度
  7. private String url;// 下载器网络标识
  8. public DownloadInfo(int threadId, int startPos, int endPos,
  9. int compeleteSize, String url) {
  10. this.threadId = threadId;
  11. this.startPos = startPos;
  12. this.endPos = endPos;
  13. this.compeleteSize = compeleteSize;
  14. this.url = url;
  15. }
  16. public DownloadInfo() {
  17. }
  18. public String getUrl() {
  19. return url;
  20. }
  21. public void setUrl(String url) {
  22. this.url = url;
  23. }
  24. public int getThreadId() {
  25. return threadId;
  26. }
  27. public void setThreadId(int threadId) {
  28. this.threadId = threadId;
  29. }
  30. public int getStartPos() {
  31. return startPos;
  32. }
  33. public void setStartPos(int startPos) {
  34. this.startPos = startPos;
  35. }
  36. public int getEndPos() {
  37. return endPos;
  38. }
  39. public void setEndPos(int endPos) {
  40. this.endPos = endPos;
  41. }
  42. public int getCompeleteSize() {
  43. return compeleteSize;
  44. }
  45. public void setCompeleteSize(int compeleteSize) {
  46. this.compeleteSize = compeleteSize;
  47. }
  48. @Override
  49. public String toString() {
  50. return "DownloadInfo [threadId=" + threadId + ", startPos=" + startPos
  51. + ", endPos=" + endPos + ", compeleteSize=" + compeleteSize
  52. + "]";
  53. }
  54. }

LoadInfo:

  1. package com.example.downloaderstopsart;
  2. public class LoadInfo {
  3. public int fileSize;// 文件大小
  4. private int complete;// 完成度
  5. private String urlstring;// 下载器标识
  6. public LoadInfo(int fileSize, int complete, String urlstring) {
  7. this.fileSize = fileSize;
  8. this.complete = complete;
  9. this.urlstring = urlstring;
  10. }
  11. public LoadInfo() {
  12. }
  13. public int getFileSize() {
  14. return fileSize;
  15. }
  16. public void setFileSize(int fileSize) {
  17. this.fileSize = fileSize;
  18. }
  19. public int getComplete() {
  20. return complete;
  21. }
  22. public void setComplete(int complete) {
  23. this.complete = complete;
  24. }
  25. public String getUrlstring() {
  26. return urlstring;
  27. }
  28. public void setUrlstring(String urlstring) {
  29. this.urlstring = urlstring;
  30. }
  31. @Override
  32. public String toString() {
  33. return "LoadInfo [fileSize=" + fileSize + ", complete=" + complete
  34. + ", urlstring=" + urlstring + "]";
  35. }
  36. }

Downloader:

  1. package com.example.downloaderstopsart;
  2. import java.io.File;
  3. import java.io.InputStream;
  4. import java.io.RandomAccessFile;
  5. import java.net.HttpURLConnection;
  6. import java.net.URL;
  7. import java.util.ArrayList;
  8. import java.util.List;
  9. import android.content.Context;
  10. import android.os.Handler;
  11. import android.os.Message;
  12. import android.util.Log;
  13. public class Downloader {
  14. private String urlstr;// 下载的地址
  15. private String localfile;// 保存路径
  16. private int threadcount;// 线程数
  17. private Handler mHandler;// 消息处理器
  18. private Dao dao;// 工具类
  19. private int fileSize;// 所要下载的文件的大小
  20. private List<DownloadInfo> infos;// 存放下载信息类的集合
  21. private static final int INIT = 1;//定义三种下载的状态:初始化状态,正在下载状态,暂停状态
  22. private static final int DOWNLOADING = 2;
  23. private static final int PAUSE = 3;
  24. private int state = INIT;
  25. public Downloader(String urlstr, String localfile, int threadcount,
  26. Context context, Handler mHandler) {
  27. this.urlstr = urlstr;
  28. this.localfile = localfile;
  29. this.threadcount = threadcount;
  30. this.mHandler = mHandler;
  31. dao = new Dao(context);
  32. }
  33. /**
  34. *判断是否正在下载
  35. */
  36. public boolean isdownloading() {
  37. return state == DOWNLOADING;
  38. }
  39. /**
  40. * 得到downloader里的信息
  41. * 首先进行判断是否是第一次下载,如果是第一次就要进行初始化,并将下载器的信息保存到数据库中
  42. * 如果不是第一次下载,那就要从数据库中读出之前下载的信息(起始位置,结束为止,文件大小等),并将下载信息返回给下载器
  43. */
  44. public LoadInfo getDownloaderInfors() {
  45. if (isFirst(urlstr)) {
  46. Log.v("TAG", "isFirst");
  47. init();
  48. int range = fileSize / threadcount;
  49. infos = new ArrayList<DownloadInfo>();
  50. for (int i = 0; i < threadcount - 1; i++) {
  51. DownloadInfo info = new DownloadInfo(i, i * range, (i + 1)* range - 1, 0, urlstr);
  52. infos.add(info);
  53. }
  54. DownloadInfo info = new DownloadInfo(threadcount - 1,(threadcount - 1) * range, fileSize - 1, 0, urlstr);
  55. infos.add(info);
  56. //保存infos中的数据到数据库
  57. dao.saveInfos(infos);
  58. //创建一个LoadInfo对象记载下载器的具体信息
  59. LoadInfo loadInfo = new LoadInfo(fileSize, 0, urlstr);
  60. return loadInfo;
  61. } else {
  62. //得到数据库中已有的urlstr的下载器的具体信息
  63. infos = dao.getInfos(urlstr);
  64. Log.v("TAG", "not isFirst size=" + infos.size());
  65. int size = 0;
  66. int compeleteSize = 0;
  67. for (DownloadInfo info : infos) {
  68. compeleteSize += info.getCompeleteSize();
  69. size += info.getEndPos() - info.getStartPos() + 1;
  70. }
  71. return new LoadInfo(size, compeleteSize, urlstr);
  72. }
  73. }
  74. /**
  75. * 初始化
  76. */
  77. private void init() {
  78. try {
  79. URL url = new URL(urlstr);
  80. HttpURLConnection connection = (HttpURLConnection) url.openConnection();
  81. connection.setConnectTimeout(5000);
  82. connection.setRequestMethod("GET");
  83. fileSize = connection.getContentLength();
  84. File file = new File(localfile);
  85. if (!file.exists()) {
  86. file.createNewFile();
  87. }
  88. // 本地访问文件
  89. RandomAccessFile accessFile = new RandomAccessFile(file, "rwd");
  90. accessFile.setLength(fileSize);
  91. accessFile.close();
  92. connection.disconnect();
  93. } catch (Exception e) {
  94. e.printStackTrace();
  95. }
  96. }
  97. /**
  98. * 判断是否是第一次 下载
  99. */
  100. private boolean isFirst(String urlstr) {
  101. return dao.isHasInfors(urlstr);
  102. }
  103. /**
  104. * 利用线程开始下载数据
  105. */
  106. public void download() {
  107. if (infos != null) {
  108. if (state == DOWNLOADING)
  109. return;
  110. state = DOWNLOADING;
  111. for (DownloadInfo info : infos) {
  112. new MyThread(info.getThreadId(), info.getStartPos(),
  113. info.getEndPos(), info.getCompeleteSize(),
  114. info.getUrl()).start();
  115. }
  116. }
  117. }
  118. public class MyThread extends Thread {
  119. private int threadId;
  120. private int startPos;
  121. private int endPos;
  122. private int compeleteSize;
  123. private String urlstr;
  124. public MyThread(int threadId, int startPos, int endPos,
  125. int compeleteSize, String urlstr) {
  126. this.threadId = threadId;
  127. this.startPos = startPos;
  128. this.endPos = endPos;
  129. this.compeleteSize = compeleteSize;
  130. this.urlstr = urlstr;
  131. }
  132. @Override
  133. public void run() {
  134. HttpURLConnection connection = null;
  135. RandomAccessFile randomAccessFile = null;
  136. InputStream is = null;
  137. try {
  138. URL url = new URL(urlstr);
  139. connection = (HttpURLConnection) url.openConnection();
  140. connection.setConnectTimeout(5000);
  141. connection.setRequestMethod("GET");
  142. // 设置范围,格式为Range:bytes x-y;
  143. connection.setRequestProperty("Range", "bytes="+(startPos + compeleteSize) + "-" + endPos);
  144. randomAccessFile = new RandomAccessFile(localfile, "rwd");
  145. randomAccessFile.seek(startPos + compeleteSize);
  146. Log.i("RG", "connection--->>>"+connection);
  147. // 将要下载的文件写到保存在保存路径下的文件中
  148. is = connection.getInputStream();
  149. byte[] buffer = new byte[4096];
  150. int length = -1;
  151. while ((length = is.read(buffer)) != -1) {
  152. randomAccessFile.write(buffer, 0, length);
  153. compeleteSize += length;
  154. // 更新数据库中的下载信息
  155. dao.updataInfos(threadId, compeleteSize, urlstr);
  156. // 用消息将下载信息传给进度条,对进度条进行更新
  157. Message message = Message.obtain();
  158. message.what = 1;
  159. message.obj = urlstr;
  160. message.arg1 = length;
  161. mHandler.sendMessage(message);
  162. if (state == PAUSE) {
  163. return;
  164. }
  165. }
  166. } catch (Exception e) {
  167. e.printStackTrace();
  168. } finally {
  169. try {
  170. is.close();
  171. randomAccessFile.close();
  172. connection.disconnect();
  173. dao.closeDb();
  174. } catch (Exception e) {
  175. e.printStackTrace();
  176. }
  177. }
  178. }
  179. }
  180. //删除数据库中urlstr对应的下载器信息
  181. public void delete(String urlstr) {
  182. dao.delete(urlstr);
  183. }
  184. //设置暂停
  185. public void pause() {
  186. state = PAUSE;
  187. }
  188. //重置下载状态
  189. public void reset() {
  190. state = INIT;
  191. }
  192. }

Dao:

  1. package com.example.downloaderstopsart;
  2. import java.util.ArrayList;
  3. import java.util.List;
  4. import android.content.Context;
  5. import android.database.Cursor;
  6. import android.database.sqlite.SQLiteDatabase;
  7. public class Dao {
  8. private DBHelper dbHelper;
  9. public Dao(Context context) {
  10. dbHelper = new DBHelper(context);
  11. }
  12. /**
  13. * 查看数据库中是否有数据
  14. */
  15. public boolean isHasInfors(String urlstr) {
  16. SQLiteDatabase database = dbHelper.getReadableDatabase();
  17. String sql = "select count(*)  from download_info where url=?";
  18. Cursor cursor = database.rawQuery(sql, new String[] { urlstr });
  19. cursor.moveToFirst();
  20. int count = cursor.getInt(0);
  21. cursor.close();
  22. return count == 0;
  23. }
  24. /**
  25. * 36 * 保存 下载的具体信息 37
  26. */
  27. public void saveInfos(List<DownloadInfo> infos) {
  28. SQLiteDatabase database = dbHelper.getWritableDatabase();
  29. for (DownloadInfo info : infos) {
  30. String sql = "insert into download_info(thread_id,start_pos, end_pos,compelete_size,url) values (?,?,?,?,?)";
  31. Object[] bindArgs = { info.getThreadId(), info.getStartPos(),
  32. info.getEndPos(), info.getCompeleteSize(), info.getUrl() };
  33. database.execSQL(sql, bindArgs);
  34. }
  35. }
  36. /**
  37. * 得到下载具体信息
  38. */
  39. public List<DownloadInfo> getInfos(String urlstr) {
  40. List<DownloadInfo> list = new ArrayList<DownloadInfo>();
  41. SQLiteDatabase database = dbHelper.getReadableDatabase();
  42. String sql = "select thread_id, start_pos, end_pos,compelete_size,url from download_info where url=?";
  43. Cursor cursor = database.rawQuery(sql, new String[] { urlstr });
  44. while (cursor.moveToNext()) {
  45. DownloadInfo info = new DownloadInfo(cursor.getInt(0),
  46. cursor.getInt(1), cursor.getInt(2), cursor.getInt(3),
  47. cursor.getString(4));
  48. list.add(info);
  49. }
  50. cursor.close();
  51. return list;
  52. }
  53. /**
  54. * 更新数据库中的下载信息
  55. */
  56. public void updataInfos(int threadId, int compeleteSize, String urlstr) {
  57. SQLiteDatabase database = dbHelper.getReadableDatabase();
  58. String sql = "update download_info set compelete_size=? where thread_id=? and url=?";
  59. Object[] bindArgs = { compeleteSize, threadId, urlstr };
  60. database.execSQL(sql, bindArgs);
  61. }
  62. /**
  63. * 关闭数据库
  64. */
  65. public void closeDb() {
  66. dbHelper.close();
  67. }
  68. /**
  69. * 下载完成后删除数据库中的数据
  70. */
  71. public void delete(String url) {
  72. SQLiteDatabase database = dbHelper.getReadableDatabase();
  73. database.delete("download_info", "url=?", new String[] { url });
  74. database.close();
  75. }
  76. }

xml如下:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:orientation="vertical"
  4. android:layout_width="fill_parent"
  5. android:layout_height="fill_parent"
  6. android:id="@+id/llRoot">
  7. <ListView android:id="@android:id/list"
  8. android:layout_width="fill_parent"
  9. android:layout_height="fill_parent">
  10. </ListView>
  11. </LinearLayout>

item_list.xml:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:layout_width="fill_parent"
  4. android:layout_height="wrap_content"
  5. android:orientation="vertical" >
  6. <LinearLayout
  7. android:layout_width="fill_parent"
  8. android:layout_height="wrap_content"
  9. android:layout_marginBottom="5dip"
  10. android:orientation="horizontal" >
  11. <TextView
  12. android:id="@+id/tv_resouce_name"
  13. android:layout_width="fill_parent"
  14. android:layout_height="wrap_content"
  15. android:layout_weight="1" />
  16. <Button
  17. android:id="@+id/btn_start"
  18. android:layout_width="fill_parent"
  19. android:layout_height="wrap_content"
  20. android:layout_weight="1"
  21. android:onClick="startDownload"
  22. android:text="下载" />
  23. <Button
  24. android:id="@+id/btn_pause"
  25. android:layout_width="fill_parent"
  26. android:layout_height="wrap_content"
  27. android:layout_weight="1"
  28. android:onClick="pauseDownload"
  29. android:text="暂停" />
  30. </LinearLayout>
  31. </LinearLayout>

记得加权限:

  1. <uses-permission android:name="android.permission.INTERNET"/>
  2.  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

还有在3.0以上的版本记得加上这句话:

  1. StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder().detectDiskReads().detectDiskWrites().detectNetwork().penaltyLog().build());
  2. StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder().detectLeakedSqlLiteObjects().detectLeakedClosableObjects().penaltyLog().penaltyDeath().build());

效果图如下:

android实现断点续传的更多相关文章

  1. android 多线程断点续传下载

    今天跟大家一起分享下Android开发中比较难的一个环节,可能很多人看到这个标题就会感觉头很大,的确如果没有良好的编码能力和逻辑思维,这块是很难搞明白的,前面2次总结中已经为大家分享过有关技术的一些基 ...

  2. Android之断点续传下载

    今天学习了Android开发中比较难的一个环节,就是断点续传下载,很多人看到这个标题就感觉头大,的确,如果没有良好的逻辑思维,这块的确很难搞明白.下面我就将自己学到的知识和一些见解写下供那些在这个环节 ...

  3. Android的断点续传的下载在线文件示例

    Android的断点续传的下载在线文件示例 文件的结构如下: activity_main.xml: <LinearLayout xmlns:android="http://schema ...

  4. Android之断点续传下载(转)

    Android之断点续传下载http://www.cnblogs.com/zxl-jay/archive/2011/10/09/2204195.html

  5. android多线程断点续传下载文件

    一.目标 1.多线程抢占服务器资源下载. 2.断点续传. 二.实现思路. 假设分为三个线程: 1.各个线程分别向服务器请求文件的不同部分. 这个涉及Http协议,可以在Header中使用Range参数 ...

  6. Android开发——断点续传原理以及实现

    0.  前言 在Android开发中,断点续传听起来挺容易,在下载一个文件时点击暂停任务暂停,点击开始会继续下载文件.但是真正实现起来知识点还是蛮多的,因此今天有时间实现了一下,并进行记录.本文原创, ...

  7. [Android实例] Android之断点续传下载

    在我们做开发的时候经常遇到的就是下载了,现在下载的方法有很多很多,那么怎么做到断点续传下载呢!很多人都头疼这个问题,如果我们没有很好的逻辑真不是很容易解决啊.我参考了一下前辈们的资料了整理了一个项目, ...

  8. Android 多线程断点续传同时下载多个大文件

    最近学习在Android环境中一些网络请求方面的知识,其中有一部分是关于网络下载方面的知识.在这里解析一下自己写的demo,总结一下自己所学的知识.下图为demo的效果图,仿照一些应用下载商城在Lis ...

  9. Android多线程断点续传下载

    这个月接到一个项目.要写一个像360助手一样的对于软件管理的APP:当中.遇到了一个问题:多线程断点下载 这个 ,因为之前没有写过这方面的应用功能.所以.不免要自学了. 然后就在各个昂站上收索并整理了 ...

随机推荐

  1. 【VNC】Linux环境VNC服务安装、配置与使用

     [VNC]Linux环境VNC服务安装.配置与使用 2009-06-25 15:55:31 分类: Linux   前言:作为一名DBA,在创建Oracle数据库的过程中一般要使用dbca和netc ...

  2. BI就是报表?

    实际上,报表只是BI的一部分,虽然BI应用的结果通常需要通过报表来展示,但是,BI绝对不仅仅是报表.其实,大家对这些概念的理解,如同15年前的ERP一样.1998年,国内两大巨头金蝶与用友都开始宣称从 ...

  3. 【福利将至】iPhone用户可用Siri发微信了

    北京时间6月14日,苹果WWDC16开发者大会召开.继2015年3月份春季发布会和9月份的秋季新品发布会,苹果和腾讯联手Apple Watch版微信和微信3DTouch功能之后,双方在今年的WWDC上 ...

  4. 微信时代,"邮"你选择 腾讯企业邮箱推新玩法

    近日,腾讯企业邮箱在广州.北京.南京三地举办<微信时代,“邮”你选择>企业邮箱新方向客户见面会,同时也正式宣布将打通微信.“拥抱”移动办公,领航国内办公工具移动之“变”. 据了解,腾讯企业 ...

  5. macOSX 访问 win7共享文件

    macOSX 访问 win7共享文件 macOSX 访问 win7共享文件 2014年1月8日星期三 开年的第一篇写下自己使用macos中遇到的问题.为后来初学者提供一些浅薄经验. 第一步:WINDO ...

  6. XSS攻击:获取浏览器记住的明文密码

    作者:余弦(@evilcos) 0x01. XSS获取明文密码的多种方式 我已经感受到Web潮流带来的巨大革新,尤其是最近HTML5越来越火.浏览器们在客户端瓜分着这个Web OS,只要是对用户体验好 ...

  7. quaternion*Vector3的新理解

    原地址:http://www.cnblogs.com/88999660/p/3262656.html using UnityEngine; using System.Collections; publ ...

  8. mysql启动报错(mac)

    $mysql ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2) ...

  9. ZeroMQ之Request/Response (Java)

    自己最开始是在cloud foundry中接触过消息服务器(nats),或者说是消息中间件,也算是初步知道了一个消息服务器对于分布式的网络系统的重要性,后来自己也曾想过在一些项目中使用它,尤其是在一些 ...

  10. 写时复制技术(Copy-on-write)

    COW技术初窥:        在Linux程序中,fork()会产生一个和父进程完全相同的子进程,但子进程在此后多会exec系统调用,出于效率考虑,linux中引入了"写时复制" ...