安卓应用安全指南 4.6.1 处理文件 示例代码

原书:Android Application Secure Design/Secure Coding Guidebook

译者:飞龙

协议:CC BY-NC-SA 4.0

如上所述,文件原则上应该是私有的。 但是,由于某些原因,有时文件应该由其他应用直接读写。 按照安全角度分类和比较中文件类型如表 4.6-1 所示。 它们根据文件存储位置或其他应用的访问权限分为四类。 下面展示了每个文件类别的示例代码,并在其中添加了每个的解释。

表 4.6-1 按照安全角度的文件类别和比较

文件类别 其它应用的访问权限 储存位置 概述
私有文件 NA 应用目录中 (1)只能在应用中读写,(2)可以处理敏感数据,(3)文件原则上应该是这个类型
只读公共文件 应用目录中 (1)其它应用和用户可读,(2)可以处理公开给应用外部的信息
读写公共文件 读写 应用目录中 (1)其它应用和用户可以读写,(2)从安全和应用设计角度来看,不应该使用
外部存储设备(读写文件) 读写 外部存储设备,例如 SD 卡 (1)没有访问控制,(2)其它应用和用户总是可以读写或删除文件,(3)应该以最小需求使用,(4)可以处理很大的文件

4.6.1.1 使用私有文件

这种情况下使用的文件,只能在同一个应用中读取/写入,并且这是使用文件的一种非常安全的方式。 原则上,无论存储在文件中的信息是否是公开的,尽可能使用私有文件,当与其他应用交换必要的信息时,应该使用另一个 Android 系统(内容供应器,服务)来完成。

要点:

1) 文件必须在应用目录中创建。

2) 文件的访问权限必须设置为私有模式,以免其他应用使用。

3) 可以存储敏感信息。

4) 对于存储在文件中的信息,请仔细和安全地处理文件数据。

PrivateFileActivity.java

package org.jssec.android.file.privatefile;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
public class PrivateFileActivity extends Activity {private TextView mFileView;private static final String FILE_NAME = "private_file.dat";@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.file);mFileView = (TextView) findViewById(R.id.file_view);}/*** Create file process** @param view*/public void onCreateFileClick(View view) {FileOutputStream fos = null;try {// *** POINT 1 *** Files must be created in application directory.// *** POINT 2 *** The access privilege of file must be set private mode in order not to be used by other applications.fos = openFileOutput(FILE_NAME, MODE_PRIVATE);// *** POINT 3 *** Sensitive information can be stored.// *** POINT 4 *** Regarding the information to be stored in files, handle file data carefully and securely.// Omitted, since this is a sample. Please refer to "3.2 Handling Input Data Carefully and Securely."fos.write(new String("Not sensotive information (File Activity)¥n").getBytes());} catch (FileNotFoundException e) {mFileView.setText(R.string.file_view);} catch (IOException e) {android.util.Log.e("PrivateFileActivity", "failed to read file");} finally {if (fos != null) {try {fos.close();} catch (IOException e) {android.util.Log.e("PrivateFileActivity", "failed to close file");}}}finish();}/*** Read file process** @param view*/public void onReadFileClick(View view) {FileInputStream fis = null;try {fis = openFileInput(FILE_NAME);byte[] data = new byte[(int) fis.getChannel().size()];fis.read(data);String str = new String(data);mFileView.setText(str);} catch (FileNotFoundException e) {mFileView.setText(R.string.file_view);} catch (IOException e) {android.util.Log.e("PrivateFileActivity", "failed to read file");} finally {if (fis != null) {try {fis.close();} catch (IOException e) {android.util.Log.e("PrivateFileActivity", "failed to close file");}}}}/*** Delete file process** @param view*/public void onDeleteFileClick(View view) {File file = new File(this.getFilesDir() + "/" + FILE_NAME);file.delete();mFileView.setText(R.string.file_view);}
}

PrivateUserActivity.java

package org.jssec.android.file.privatefile;import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;public class PrivateUserActivity extends Activity {private TextView mFileView;private static final String FILE_NAME = "private_file.dat";@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.user);mFileView = (TextView) findViewById(R.id.file_view);}private void callFileActivity() {Intent intent = new Intent();intent.setClass(this, PrivateFileActivity.class);startActivity(intent);}/*** Call file Activity process** @param view*/public void onCallFileActivityClick(View view) {callFileActivity();}/*** Read file process** @param view*/public void onReadFileClick(View view) {FileInputStream fis = null;try {fis = openFileInput(FILE_NAME);byte[] data = new byte[(int) fis.getChannel().size()];fis.read(data);// *** POINT 4 *** Regarding the information to be stored in files, handle file data carefully and securely.// Omitted, since this is a sample. Please refer to "3.2 Handling Input Data Carefully and Securely."String str = new String(data);mFileView.setText(str);} catch (FileNotFoundException e) {mFileView.setText(R.string.file_view);} catch (IOException e) {android.util.Log.e("PrivateUserActivity", "failed to read file");} finally {if (fis != null) {try {fis.close();} catch (IOException e) {android.util.Log.e("PrivateUserActivity", "failed to close file");}}}}/*** Rewrite file process** @param view*/public void onWriteFileClick(View view) {FileOutputStream fos = null;try {// *** POINT 1 *** Files must be created in application directory.// *** POINT 2 *** The access privilege of file must be set private mode in order not to be used by other applications.fos = openFileOutput(FILE_NAME, MODE_APPEND);// *** POINT 3 *** Sensitive information can be stored.// *** POINT 4 *** Regarding the information to be stored in files, handle file data carefully and securely.// Omitted, since this is a sample. Please refer to "3.2 Handling Input Data Carefully and Securely."fos.write(new String("Sensitive information (User Activity)¥n").getBytes());} catch (FileNotFoundException e) {mFileView.setText(R.string.file_view);} catch (IOException e) {android.util.Log.e("PrivateUserActivity", "failed to read file");} finally {if (fos != null) {try {fos.close();} catch (IOException e) {android.util.Log.e("PrivateUserActivity", "failed to close file");}}}callFileActivity();}
}

4.6.1.2 使用公共只读文件

这是使用文件向未指定的大量应用公开内容的情况。 如果通过遵循以下几点来实现,那么它也是比较安全的文件使用方法。 请注意,在 API 级别 1 7及更高版本中,不推荐使用MODE_WORLD_READABLE变量来创建公共文件,并且在 API 级别 24 及更高版本中,会触发安全异常; 因此使用内容供应器的文件共享方法更可取。

要点:

1) 文件必须在应用目录中创建。

2) 文件的访问权限必须设置为其他应用只读。

3) 敏感信息不得存储。

4) 对于要存储在文件中的信息,请仔细和安全地处理文件数据。

PublicFileActivity.java

package org.jssec.android.file.publicfile.readonly;import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;public class PublicFileActivity extends Activity {private TextView mFileView;private static final String FILE_NAME = "public_file.dat";@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.file);mFileView = (TextView) findViewById(R.id.file_view);}/*** Create file process** @param view*/public void onCreateFileClick(View view) {FileOutputStream fos = null;try {// *** POINT 1 *** Files must be created in application directory.// *** POINT 2 *** The access privilege of file must be set to read only to other applications.// (MODE_WORLD_READABLE is deprecated API Level 17,// don't use this mode as much as possible and exchange data by using ContentProvider().)fos = openFileOutput(FILE_NAME, MODE_WORLD_READABLE);// *** POINT 3 *** Sensitive information must not be stored.// *** POINT 4 *** Regarding the information to be stored in files, handle file data carefully and securely.// Omitted, since this is a sample. Please refer to "3.2 Handling Input Data Carefully and Securely."fos.write(new String("Not sensitive information (Public File Activity)¥n").getBytes());} catch (FileNotFoundException e) {mFileView.setText(R.string.file_view);} catch (IOException e) {android.util.Log.e("PublicFileActivity", "failed to read file");} finally {if (fos != null) {try {fos.close();} catch (IOException e) {android.util.Log.e("PublicFileActivity", "failed to close file");}}}finish();}/*** Read file process** @param view*/public void onReadFileClick(View view) {FileInputStream fis = null;try {fis = openFileInput(FILE_NAME);byte[] data = new byte[(int) fis.getChannel().size()];fis.read(data);String str = new String(data);mFileView.setText(str);} catch (FileNotFoundException e) {mFileView.setText(R.string.file_view);} catch (IOException e) {android.util.Log.e("PublicFileActivity", "failed to read file");} finally {if (fis != null) {try {fis.close();} catch (IOException e) {android.util.Log.e("PublicFileActivity", "failed to close file");}}}}/*** Delete file process** @param view*/public void onDeleteFileClick(View view) {File file = new File(this.getFilesDir() + "/" + FILE_NAME);file.delete();mFileView.setText(R.string.file_view);}
}

PublicUserActivity.java

package org.jssec.android.file.publicuser.readonly;import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import android.app.Activity;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager.NameNotFoundException;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;public class PublicUserActivity extends Activity {private TextView mFileView;private static final String TARGET_PACKAGE = "org.jssec.android.file.publicfile.readonly";private static final String TARGET_CLASS = "org.jssec.android.file.publicfile.readonly.PublicFileActivity";private static final String FILE_NAME = "public_file.dat";@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.user);mFileView = (TextView) findViewById(R.id.file_view);}private void callFileActivity() {Intent intent = new Intent();intent.setClassName(TARGET_PACKAGE, TARGET_CLASS);try {startActivity(intent);} catch (ActivityNotFoundException e) {mFileView.setText("(File Activity does not exist)");}}/*** Call file Activity process** @param view*/public void onCallFileActivityClick(View view) {callFileActivity();}/*** Read file process** @param view*/public void onReadFileClick(View view) {FileInputStream fis = null;try {File file = new File(getFilesPath(FILE_NAME));fis = new FileInputStream(file);byte[] data = new byte[(int) fis.getChannel().size()];fis.read(data);// *** POINT 4 *** Regarding the information to be stored in files, handle file data carefully and securely.// Omitted, since this is a sample. Please refer to "3.2 Handling Input Data Carefully and Securely."String str = new String(data);mFileView.setText(str);} catch (FileNotFoundException e) {android.util.Log.e("PublicUserActivity", "no file");} catch (IOException e) {android.util.Log.e("PublicUserActivity", "failed to read file");} finally {if (fis != null) {try {fis.close();} catch (IOException e) {android.util.Log.e("PublicUserActivity", "failed to close file");}}}}/*** Rewrite file process** @param view*/public void onWriteFileClick(View view) {FileOutputStream fos = null;boolean exception = false;try {File file = new File(getFilesPath(FILE_NAME));// Fail to write in. FileNotFoundException occurs.fos = new FileOutputStream(file, true);fos.write(new String("Not sensitive information (Public User Activity)¥n").getBytes());} catch (IOException e) {mFileView.setText(e.getMessage());exception = true;} finally {if (fos != null) {try {fos.close();} catch (IOException e) {exception = true;}}}if (!exception)callFileActivity();}private String getFilesPath(String filename) {String path = "";try {Context ctx = createPackageContext(TARGET_PACKAGE,Context.CONTEXT_RESTRICTED);File file = new File(ctx.getFilesDir(), filename);path = file.getPath();} catch (NameNotFoundException e) {android.util.Log.e("PublicUserActivity", "no file");}return path;}
}

4.6.1.3 创建公共读写文件

这是一种文件用法,它允许未指定的大量应用的读写访问。

未指定的大量应用可以读写,意思不用多说了。 恶意软件也可以读取和写入,因此数据的可信度和安全性将永远不会得到保证。 另外,即使在没有恶意的情况下,也不能控制文件中的数据格式或写入的时间。 所以这种类型的文件在功能方面几乎不实用。

如上所述,从安全性和应用设计的角度来看,不可能安全地使用读写文件,因此应该避免使用读写文件。

要点:

不要创建允许来自其他应用的读写操作的文件。

4.6.1.4 使用外部存储器(公共读写)文件

将文件存储在 SD 卡等外部存储器中时,就是这种情况。当存储比较庞大的信息(放置从 Web 下载的文件)或者将信息带出到外部时(备份等)时,应该使用它。

对于未指定的大量应用,“外部存储器文件(公共读写)”与“公共读写文件“有相同特性。另外,对于声明使用android.permission.WRITE_EXTERNAL_STORAGE权限的应用,它和“公共读写文件”具有相同的特性。因此,应尽可能减少“外部存储器(公共读写)文件”的使用。

按照 Android 应用的惯例,备份文件很可能是在外部存储器中创建的。但是,如上所述,外部存储器中的文件存在被其他应用(包括恶意软件)篡改/删除的风险。因此,在输出备份的应用中,为了最小化应用规范或设计方面的风险,一些设计是必要的,例如显示“尽快将备份文件复制到 PC 等安全位置”。

要点:

1) 不得存储敏感信息。

2) 文件必须存储在每个应用的唯一目录中。

3) 对于要存储在文件中的信息,请仔细和安全地处理文件数据。

4) 请求应用的文件写入应该按照规范禁止。

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"package="org.jssec.android.file.externalfile" ><!-- declare android.permission.WRITE_EXTERNAL_STORAGE permission to write to the external strage --><!-- In Android 4.4 (API Level 19) and later, the application, which read/write only files in its specificdirectories on external storage media, need not to require the permission and it should declarethe maxSdkVersion --><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"android:maxSdkVersion="18"/><application
        android:icon="@drawable/ic_launcher"android:label="@string/app_name"android:allowBackup="false" ><activity
            android:name=".ExternalFileActivity"android:label="@string/app_name"android:exported="true" ><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity></application>
</manifest>

ExternalFileActivity.java

package org.jssec.android.file.externalfile;import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;public class ExternalFileActivity extends Activity {private TextView mFileView;private static final String TARGET_TYPE = "external";private static final String FILE_NAME = "external_file.dat";@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.file);mFileView = (TextView) findViewById(R.id.file_view);}/*** Create file process** @param view*/public void onCreateFileClick(View view) {FileOutputStream fos = null;try {// *** POINT 1 *** Sensitive information must not be stored.// *** POINT 2 *** Files must be stored in the unique directory per application.File file = new File(getExternalFilesDir(TARGET_TYPE), FILE_NAME);fos = new FileOutputStream(file, false);// *** POINT 3 *** Regarding the information to be stored in files, handle file data carefully and securely.// Omitted, since this is a sample. Please refer to "3.2 Handling Input Data Carefully and Securely."fos.write(new String("Non-Sensitive Information(ExternalFileActivity)¥n").getBytes());} catch (FileNotFoundException e) {mFileView.setText(R.string.file_view);} catch (IOException e) {android.util.Log.e("ExternalFileActivity", "failed to read file");} finally {if (fos != null) {try {fos.close();} catch (IOException e) {android.util.Log.e("ExternalFileActivity", "failed to close file");}}}finish();}/*** Read file process** @param view*/public void onReadFileClick(View view) {FileInputStream fis = null;try {File file = new File(getExternalFilesDir(TARGET_TYPE), FILE_NAME);fis = new FileInputStream(file);byte[] data = new byte[(int) fis.getChannel().size()];fis.read(data);// *** POINT 3 *** Regarding the information to be stored in files, handle file data carefully and securely.// Omitted, since this is a sample. Please refer to "3.2 Handling Input Data Carefully and Securely."String str = new String(data);mFileView.setText(str);} catch (FileNotFoundException e) {mFileView.setText(R.string.file_view);} catch (IOException e) {android.util.Log.e("ExternalFileActivity", "failed to read file");} finally {if (fis != null) {try {fis.close();} catch (IOException e) {android.util.Log.e("ExternalFileActivity", "failed to close file");}}}}/*** Delete file process** @param view*/public void onDeleteFileClick(View view) {File file = new File(getExternalFilesDir(TARGET_TYPE), FILE_NAME);file.delete();mFileView.setText(R.string.file_view);}
}

使用的示例代码:

ExternalFileUser.java

package org.jssec.android.file.externaluser;import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager.NameNotFoundException;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;public class ExternalUserActivity extends Activity {private TextView mFileView;private static final String TARGET_PACKAGE = "org.jssec.android.file.externalfile";private static final String TARGET_CLASS = "org.jssec.android.file.externalfile.ExternalFileActivity";private static final String TARGET_TYPE = "external";private static final String FILE_NAME = "external_file.dat";@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.user);mFileView = (TextView) findViewById(R.id.file_view);}private void callFileActivity() {Intent intent = new Intent();intent.setClassName(TARGET_PACKAGE, TARGET_CLASS);try {startActivity(intent);} catch (ActivityNotFoundException e) {mFileView.setText("(File Activity does not exist)");}}/*** Call file Activity process** @param view*/public void onCallFileActivityClick(View view) {callFileActivity();}/*** Read file process** @param view*/public void onReadFileClick(View view) {FileInputStream fis = null;try {File file = new File(getFilesPath(FILE_NAME));fis = new FileInputStream(file);byte[] data = new byte[(int) fis.getChannel().size()];fis.read(data);// *** POINT 3 *** Regarding the information to be stored in files, handle file data carefully and securely.// Omitted, since this is a sample. Please refer to "3.2 Handling Input Data Carefully and Securely."String str = new String(data);mFileView.setText(str);} catch (FileNotFoundException e) {mFileView.setText(R.string.file_view);} catch (IOException e) {android.util.Log.e("ExternalUserActivity", "failed to read file");} finally {if (fis != null) {try {fis.close();} catch (IOException e) {android.util.Log.e("ExternalUserActivity", "failed to close file");}}}}/*** Rewrite file process** @param view*/public void onWriteFileClick(View view) {// *** POINT 4 *** Writing file by the requesting application should be prohibited as the specification.// Application should be designed supposing malicious application may overwrite or delete file.final AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);alertDialogBuilder.setTitle("POINT 4");alertDialogBuilder.setMessage("Do not write in calling appllication.");alertDialogBuilder.setPositiveButton("OK",new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {callFileActivity();}});alertDialogBuilder.create().show();}private String getFilesPath(String filename) {String path = "";try {Context ctx = createPackageContext(TARGET_PACKAGE,Context.CONTEXT_IGNORE_SECURITY);File file = new File(ctx.getExternalFilesDir(TARGET_TYPE), filename);path = file.getPath();} catch (NameNotFoundException e) {android.util.Log.e("ExternalUserActivity", "no file");}return path;}
}

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"package="org.jssec.android.file.externaluser" ><!-- In Android 4.0.3 (API Level 14) and later, the permission for reading external storageshas been defined and the application should decalre that it requires the permission.In fact in Android 4.4 (API Level 19) and later, that must be declared to read other directoriesthan the package specific directories. --><uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /><application
        android:icon="@drawable/ic_launcher"android:label="@string/app_name"android:allowBackup="false" ><activity
            android:name=".ExternalUserActivity"android:label="@string/app_name"android:exported="true" ><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity></application>
</manifest>

安卓应用安全指南 4.6.1 处理文件 示例代码相关推荐

  1. 安卓应用安全指南 4.5.1 使用 SQLite 示例代码

    安卓应用安全指南 4.5.1 使用 SQLite 示例代码 原书:Android Application Secure Design/Secure Coding Guidebook 译者:飞龙 协议: ...

  2. 安卓应用安全指南 4.6.3 处理文件 高级话题

    安卓应用安全指南 4.6.3 处理文件 高级话题 原书:Android Application Secure Design/Secure Coding Guidebook 译者:飞龙 协议:CC BY ...

  3. 安卓应用安全指南 4.6.2 处理文件 规则书

    安卓应用安全指南 4.6.2 处理文件 规则书 原书:Android Application Secure Design/Secure Coding Guidebook 译者:飞龙 协议:CC BY- ...

  4. 安卓应用安全指南 4.4.3 创建/使用服务高级话题

    安卓应用安全指南 4.4.3 创建/使用服务高级话题 原书:Android Application Secure Design/Secure Coding Guidebook 译者:飞龙 协议:CC ...

  5. 安卓应用安全指南 4.5.2 使用 SQLite 规则书

    安卓应用安全指南 4.5.2 使用 SQLite 规则书 原书:Android Application Secure Design/Secure Coding Guidebook 译者:飞龙 协议:C ...

  6. 安卓应用安全指南 4.4.2 创建/使用服务 规则书

    安卓应用安全指南 4.4.2 创建/使用服务 规则书 原书:Android Application Secure Design/Secure Coding Guidebook 译者:飞龙 协议:CC ...

  7. android 存储盘 dcim,DCIM是个啥?安卓图片存储位置指南

    DCIM是个啥?安卓图片存储位置指南 一般安卓手机的相机功能都会有固定的存放路径,这个位置默认为:/sdcard/DCIM/100Andro或者/sdcard/DCIM/Camera,这里的sdcar ...

  8. 【荣耀开发者服务平台—百亿曝光扶持等你来】智慧服务安卓卡片接入指南

    荣耀开发者服务平台(HONOR Developers)是荣耀面向开发者的统一生态入口,通过聚合周边内外部系统,分全球多站点部署,为全球开发者提供业务全生命周期的商业支撑服务. 平台可为软硬件合作伙伴带 ...

  9. 安卓应用安全指南 5.6.3 密码学 高级话题

    5.6.3 密码学 高级话题 原书:Android Application Secure Design/Secure Coding Guidebook 译者:飞龙 协议:CC BY-NC-SA 4.0 ...

最新文章

  1. 推荐7款冷门但是非常值得推荐的windows软件
  2. 挑战杯科展上的智能车作品
  3. linux安装google chrome
  4. 解决不是有效的win32应用程序
  5. java pdf水印排布问题_Java实现pdf文件添加水印,铺满全页。
  6. mysql 存guid类型_从C#在MySQL中存储GUID
  7. jvm内存参数配置_idea中设置JVM参数,简单理解JVM常见参数,JVM调优简单入门
  8. hdu5247 找连续数
  9. 用计算机打字英语单词,常用计算机专业英语词汇-前401-500单词
  10. MySQL左关联、右关联、内关联查询
  11. com/mysql/jdbc/statementimpl_com.mysql.jdbc.异常.jdbc4。通信异常:通信链路故障
  12. .net 启动mysql数据库连接,ASP.NET实战002:MySQL数据库连接
  13. Cisco交换机设置管理IP
  14. python new方法_Python中的__new__()方法的使用
  15. Sql Server 导出数据库表结构的SQL查询语句
  16. 20191121每日一句
  17. 如何选择VC界面库产品?(二)– DSkinLite界面库介绍
  18. Atom markdown-pdf 插件错误 Markdown-pdf: Error. Check console for more information.
  19. Python的pandas安装超级详细
  20. 2021 年职业院校技能大赛“网络安全”项目 江西省比赛任务书

热门文章

  1. (10)System Verilog 关联数组
  2. 0603 0402 0805 电阻封装寸尺
  3. 完成端口可用回射服务器
  4. nand linux bbt存储,Linux NAND BBT管理
  5. STM32 ADC模数转换
  6. 数据结构与算法分析(四)——C++实现栈
  7. [C++] - C++11 多线程 - Thread
  8. 合并有序数组java
  9. HDFS-HA-federation的机制和功能组件
  10. spring-mvc笔记1