兼容

这是一场不停的追逐!


  • Home

  • About

  • Tags

  • Archives

NDK常用代码示例

Posted on 2016-08-12

常用的代码示例

Talk is cheap, show me code!
主要记录数据java端与c++端的数据交互

c++端调试接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// log.h
#ifndef __DEBUG_LOG_H__
#define __DEBUG_LOG_H__

#include <android/log.h>

#ifndef TAG
#define TAG "JniDemo"
#endif

#define LOGD_D(...) __android_log_print(ANDROID_LOG_DEBUG,TAG, __VA_ARGS__)
#define LOGD_E(...) __android_log_print(ANDROID_LOG_ERROR,TAG, __VA_ARGS__)
#define LOGD_I(...) __android_log_print(ANDROID_LOG_INFO, TAG, __VA_ARGS__)
#endif

Java示例类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
package com.dasea.jni;
public class JniData {
public boolean bData;
public double dData;
public int iData;
public byte cData;
public String sData;
public byte byteArr[];
public int intArr[];

public TestSetData() {
// TODO Auto-generated constructor stub
bData = true;
dData = 100.11;
iData = 333;
cData = 100;
sData = "20150204";
byteArr = new byte[10];
for (int i = 0; i < byteArr.length; i++) {
byteArr[i] = '2';
}

intArr = new int[10];
for (int i = 0; i < intArr.length; i++) {
intArr[i] = i * 10;
}
}
}

Java Native接口类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package com.dasea.jni;
public class JniDemo {
// 测试基本数据类型
public native void testBasicData(boolean bData, int iData, double dData, String sData);
// 测试Object类型
public native void testObjectData(JniData data);
// 测试基本类型的数组类型
public native void testBasicArrData(int[] data);
// 测试Object的数组类型
public native void testStringArrData(String[] str);
public native void testObjectArrData(JniData[] data);
// ...
其他具体请看github代码
}

对应接口c++ 端的实现

具体请看github代码
代码仓库

Java层与Jni层数据传递之Direct Buffer

Posted on 2016-08-12

基本

  • 共享内存的方式进行数据交换
  • 比普通数组传递效率高
  • 构造, 析构, 维护成本高, 所以适合长期频繁访问的大块内存区域
  • 关于Direct Buffer的内存情况查考:
    text

实现

  • java实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
// 主要用于测试Direct Buffer
public class DirectBufferOnClickListener implements OnClickListener {
@Override
public void onClick(View arg0) {
if (null == directBuffer) {
// 首先分配, 然后调用进行设置
directBuffer = ByteBuffer.allocateDirect(1024);
if (null == directBuffer) {
Log.d("JniDemo", "分配Direct Buffer失败!");
return ;
}

directBuffer.putChar('a');
directBuffer.putChar('c');
directBuffer.putChar('d');
directBuffer.putChar('d');
directBuffer.putChar('w');
directBuffer.putChar('j');
directBuffer.putChar('l');
jniDemo.setDirectBuffer(directBuffer, directBuffer.capacity());
}else{
// 测试数据是否设置进去了
directBuffer.putChar(';');
directBuffer.putChar('a');
directBuffer.putChar('h');
directBuffer.putChar('t');
directBuffer.putChar('6');
directBuffer.putChar('2');
directBuffer.putChar('8');
jniDemo.testDirectBufferContext(7);
}
}
}

//
  • C++端实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
unsigned char* g_directBuff = NULL;
int g_bufferLen = 0;
// 测试Direct Buffer
JNIEXPORT void JNICALL Java_com_dasea_ndkjnidemo_JniDemo_setDirectBuffer(
JNIEnv* env, jobject obj, jobject jdirectBuff, jint jcapacity) {
void* buffer = env->GetDirectBufferAddress(jdirectBuff);
if (NULL == buffer) {
LOGD_D("natilayer->setImageDirectBuffer ->Invalid buffer!");
return ;
}
g_bufferLen = static_cast<int>(jcapacity);
g_directBuff = static_cast<unsigned char*>(buffer);

// 一个put进去的字符占俩个字节, 所以%s不能直接显示, 所以需要循环显示
for(int i = 0; i < 20; ++i) {
LOGD_D("Buffer里面的数据为: %d", g_directBuff[i]);
}
LOGD_D("Buffer里面的数据为: %s, 容量为: %d", g_directBuff, g_bufferLen);
}

JNIEXPORT void JNICALL Java_com_dasea_ndkjnidemo_JniDemo_testDirectBufferContext(
JNIEnv* env, jobject obj, jint jlen) {
int len = jlen;
LOGD_D("有效数据长度为: %d", len);
for(int i = 0; i < 40; ++i) {
LOGD_D("Buffer里面的数据为: %d", g_directBuff[i]);
}
}

NDK动态注册方法

Posted on 2016-08-12

java的方法与c/c++代码的函数对应方式

静态方式

  • 通过Java_[包名]_[类名]_[方法名]的形式对应
  • 缺点是又臭又长, 不适合管理

动态方式

  • 采用自己喜欢的函数名定义方法
  • 简单, 漂亮

实现参考

静态

静态方法定义文件

动态

  • 需要在JNI_OnLoad里面完成注册
  • 头文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#ifndef __DYNAMIC_JNIDEMO_H__
#define __DYNAMIC_JNIDEMO_H__

#include <jni.h>

#ifdef __cplusplus
extern "C" {
#endif

jstring testDynamicRegister(JNIEnv* env, jobject obj);

#ifdef __cplusplus
}
#endif
#endif // __DYNAMIC_JNIDEMO_H__
  • 实现文件
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    #include "dynamic_jnidemo.h"
    #include "log.h"

    #include <cstdio>

    /**
    * 方法对应表
    */
    static JNINativeMethod gMethods[] = {
    {"testDynamicRegister", "()Ljava/lang/String;", (void*)testDynamicRegister},//绑定
    };

    // 注册方法
    static int registerNatives(JNIEnv* env);
    static int registerNativeMethods(JNIEnv* env, const char* className,
    JNINativeMethod* gMethods, int numMethods);

    /*
    * System.loadLibrary("lib")时调用
    * 如果成功返回JNI版本, 失败返回-1
    */
    JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved) {
    JNIEnv* env = NULL;
    jint result = -1;

    if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
    return -1;
    }

    if (NULL == env) {
    LOGD_D("获取env失败!");
    return -1;
    }

    if (!registerNatives(env)) {//注册
    return -1;
    }
    LOGD_D("注册方法成功");
    //成功
    result = JNI_VERSION_1_4;

    return result;
    }
    /*
    * 为某一个类注册本地方法
    */
    int registerNativeMethods(JNIEnv* env, const char* className,
    JNINativeMethod* gMethods, int numMethods) {
    jclass clazz;
    clazz = env->FindClass(className);
    if (clazz == NULL) {
    LOGD_D("不能找到类: %s", className);
    return JNI_FALSE;
    }
    if (env->RegisterNatives(clazz, gMethods, numMethods) < 0) {
    return JNI_FALSE;
    }

    return JNI_TRUE;
    }


    /*
    * 为所有类注册本地方法
    */
    static int registerNatives(JNIEnv* env) {
    const char* kClassName = "com/dasea/ndkjnidemo/JniDemo";//指定要注册的类
    return registerNativeMethods(env, kClassName, gMethods,
    sizeof(gMethods) / sizeof(gMethods[0]));
    }

    // native 方法
    jstring testDynamicRegister(JNIEnv* env, jobject obj)
    {
    LOGD_D("JAVA 调用这个方法了, 并且c++端会返回一个响应!");
    return env->NewStringUTF("动态注册JNI");
    }

NDK内存使用问题

Posted on 2016-08-12

避免内存泄露

主要讲述了NDK编程中可能的内存泄露!

文章收录

在Jni编程中避免内存泄露

需要释放的内容

后续整理

批处理之if语句

Posted on 2016-08-11

if语句

判断俩个字符串是否相等

if "string1" == "string2" command 语句 例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
@echo off
:: /p 选项会要求用户从终端输入数据
set /p var1=请输入字符串1:
set /p var2=请输入字符串2:
if %var1% == %var2% (
echo 输入的字符串相等
) else echo 输入的字符串不相等

set var3="hello"
set var4="hello"
if %var4% == %var3% (
echo 输入的字符串相等
) else echo 输入的字符串不相等

if "a" == "A" (
echo 输入的俩个字符相同
) else echo 输入的俩个字符不同

:: 加/i可以不区分大小写
if /i "a" == "A" (
echo 输入的俩个字符相同
) else echo 输入的俩个字符不同

pause

判断俩个数值是否相等

if 数值1 equ 数值2 command 语句

其他关系符号:

中文含义 关系符 英文解释
等于 equ equal
大于 gtr greater than
大于或等于 geq greater than or equal
小于 lss less than
小于或等于 leq less than or equal
不等于 neq no equal

例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
set /p num1=请输入数字:
if %num1% geq 10 (
echo 此数大于10
) else (
echo 此数小于10
)

:: 字符串比较而不是数字
if "12" lss "4" (
echo 12竟然会小于4!
) else (
echo 12当然不会小于4
)

if 12 lss 4 (
echo 12竟然会小于4!
) else (
echo 12当然不会小于4
)

判断驱动器是否存在

if [not] exist filename command

例子:

1
2
3
4
5
6
7
8
9
10
11
if exist "e:" (echo e盘存在) else echo e盘不存在

if exist d:\123.bat (echo 123.bat文件存在) else echo 123.bat文件不存在

dir /a-d d:\123.bat >nul 2>nul
if %errorlevel%==0 (echo 123.bat文件存在!) else echo 123.bat文件不存在

:: 判断文件夹是否存在
if exist test\ (echo test是文件夹) else echo test是文件
if exist test\. (echo test是文件夹) else echo test是文件
if exist test\nul (echo test是文件夹) else echo test是文件

判断变量是否定义

if defined 变量 command 语句 例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
if defined a (echo 变量a已定义) else echo 变量a没被定义

echo a=
set a=
if defined a (echo 变量a已定义) else echo 变量a没被定义

echo a=10
set a=10
if defined a (echo 变量a已定义) else echo 变量a没被定义
:: 判断的时候不能写为%var%
set var5=5
if defined var5 (echo 变量var5已定义) else (echo 变量var5没有被定义)
set /p var6=请输入一个数字:
if defined %var6% (echo 变量var6已定义) else (echo 变量var6没有被定义)

set var7=5
if defined var7 (echo 变量var7已定义) else (echo 变量var7没有被定义)
set /p var8=请输入一个数字:
if defined var8 (echo 变量var8已定义) else (echo 变量var8没有被定义)

判断命令返回值

if errorlevel语句特点:

  • if errorlevel 0 cmmand, 含义是:如果返回的错误码值大于或等于0的时,将执行cmmand操作
  • if %errorlevel%==0 cmmand,含义是:如果返回的错误码值等于0的时候,将执行cmmand操作

例子:

1
2
3
4
5
6
7
net user
if %errorlevel% ==0 (echo neu user执行成功) else (echo net user命令执行失败)

set /p input=请输入任意一条命令:
if errorlevel 0 (echo %input% 命令执行成功) else (echo %input% 命令执行失败)

:: 一般0表示成功,其他失败, 错误码范围0-255

if not语句

  • 否的意思, 失败的时候先执行
  • if not “字符串1”==”字符串2” command 语句;
  • if not数值1 equ 数值2 command 语句;
  • if not exist filename command 语句;
  • if not defined 变量 command 语句;
  • if not errorlevel 数值 command 语句。

常用的一些cmd命令

Posted on 2016-08-11

创建空文件的几种方式

  • cd .>a.txt
  • copy nul b.txt
  • type nul>c.txt
  • echo a 2>d.txt
  • fsutil file createnew e.txt 0
  • 其他, 无输出, 且重定向文件即可

文件,文件夹相关命令

  • dir 显示目录和文件
  • cd 进入目录
  • attrib 显示和更改文件属性

    • /d 必须和 /s一起使用
    • attrib h d:\123 /s /d”和”attrib h d:\123. /s /d
    • 前一个只有d:\123以及他同名的子目录设置了隐藏;
    • 后一个将所有文件和子目录设置了隐藏, 但是d:\123本身没有隐藏
  • del 删除文件

  • copy 复制文件, 而不能复制文件夹

    • 合并文件: copy /b 文件1+文件2+文件3 合并后的文件
    • copy /b(二进制)[/a(文本)] d:\1.mp3 d::\2.mp3 e:\3.mp3 -> 1.mp3和2.mp3合并为3.mp3
  • xcopy 复制文件夹

    • /s 复制非空的目录和子目录, 如果省略,只在一个目录中工作
    • /e 复制所有子目录, 包括空目录
    • /h 复制具有隐藏和系统文件属性的文件
    • /t 只复制子目录结构, 不复制文件, 要复制空目录, 加/e
    • /y 禁止提示确认要覆盖现存的目标文件
    • 区别: xcopy /e d:\123 e:\kkk\ 和 xcopy /e d:\123 e:\kkk
    • 俩个都是复制123目录下的所有文件(夹)到kkk, 但是前者不会询问你目标e:\kkk是目录名还是文件名
  • md 创建文件夹, 创建单个文件夹

    • 对于文件名有空格的情况, 用双引号,如: md “c:\Documents and setting\123”
    • 创建多个目录, 如: md abc d:\game\123 abd
  • rd 删除空目录(目录中不能有子目录和文件)

    • /s 除目录本身外, 还将删除指定目录下的所有子目录和文件,用于删除目录树
    • /q 安静模式, 带/s删除目录树是不要求确认
  • ren 重命名文件夹

    • ren [path]filename1 filenam2 -> filenam2不能带路径
  • move 移动文件夹, 重命名文件夹

    • /y 取消确认改写一个现有目标文件的提示
    • /-y 对确认改写一个现有目标文件发出提示
    • move 命令可以跨区移动文件, 却不可以跨分区移动文件夹
    • 对于跨区移动文件, 如果目标位置存在和将要移动的文件同名是, 系统会提示: “文件存在”, 命令不会执行
    • 对于隐藏或系统属性的文件, 只有去除他们的属性后, move才能执行

字符串查找

  • find 字符串查找

    • find “echo” dir.bat
  • findstr 字符串查找增强

    • 支持正则

常用网络命令

  • ping 测试ip连接

    • -n count 发送数据包个数
    • -w timeout 超时间隔,毫秒
    • ping 1 -n 1 -w 10000 2>nul 1>nul : 批处理中可以用于延时10秒
  • ipconfig 查看ip配置

  • arp 显示和修改”地址解析协议(arp)”缓存中的项目

    • -a or -g : 显示所有项目
    • -s : 手工输入一个静态项目
    • -d : 使用本命令能够人工删除一个静态项目
  • start 开启命令

    • start “title” filename
    • start www.baidu.com : 打开百度
    • start “” “%windir%\system32\NOTEPAD.EXE” “%userprofile%\桌面\abc.txt”
    • start “” “%userprofile%\桌面\abc.doc”
    • /min 和 /max 窗口的最大化和最小化
  • shutdown 关闭和重启计算机

    • shutdown -l :该命令只能注销本机用户,对远程计算机不适用。
    • at 12:00 shutdown -s :通过-s参数,在12:00执行关闭计算机。
    • shutdown -r -t 60 :60秒后重启计算机。这里是设置重启倒计时为60秒。如果没有设置时间则默认为30秒。
    • shutdown -f -s -t 300 :通过-f参数强制计算机300秒后关闭。
    • shutdown -a :放弃系统关机
  • taskkill 关闭指定进程

  • tasklist 显示本地或远程机器上的当前运行的进程列表

常用特殊符号

重定向

  • > 传递且覆盖
  • >> 将结果追加到指定的设备

命令管道符 |

  • 它之前的命令或语句的执行结果作为在它之后的命令或语句的处理对象
  • 例1: tasklist | find /i “qq.exe” && taskkill /f /im qq.exe
  • 例2: echo Y | rd /s c:\abc

组合命令 & && ||

  • & : 按顺序执行多条命令, 互不影响
  • && : 只有前一个命令没有错, 才执行下一个
  • || : 前一个命令执行失败后, 才执行下一个, 否则不执行下一个
  • ^ : 转义字符
1
2
3
4
5
6
7
8
9
10
11
1, 在cmd环境中,有些字符具备特殊功能,如 >、>>表示重定向,| 表示管道,&、&&、|| 表示语句连接……它
们都有特定的功能,如果需要把它们作为字符输出的话,echo >、echo | ……之类的写法就会出错——cmd解释器会
把它们作为具有特殊功能的字符对待,而不会作为普通字符处理,这个时候,就需要对这些特殊字符做转义处理,
在每个特殊字符前加上转义字符, 因此,要输出这些特殊字符,就需要用 echo ^>、echo ^|、echo ^|^|、echo ^^……
之类的格式来处理;
2, 此转义字符还可以用作续行符号;
3, @echo off
echo 这是^
一个^
句子
Pause

变量引导符

  • 当百分号成对出现,并且其间包含非特殊字符时,一般做变量引用处理,比如:%var%、%str%;
  • 百分号作为变量引用还有一种特殊形式,那就是对形式参数的引用,此时,单个百分号后面紧跟0~9这10
    个数字,如%0、%1、%2
  • %0 表示批处理文件本身,包括完整的路径和扩展名
  • %1至%9 表示第一个参数至第九个参数
  • 出现在 set /a 语句中时,表示两数相除取余数,也就是所谓的模运算,它在命令行窗口和批处理文件中的写法
  • 略有差异:在命令行窗口中,只需要单个的%,在批处理文件中,需要连续两个百分号,写成%%
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@echo off
set /a num=4%%2
echo 4除以2的余数为 %num%

:: 处理当前批处理常用的
%~0: 取文件名(名+扩展名)
%~f0:取全路径
%~d0:取驱动器名
%~p0:只取路径(不包驱动器)
%~n0:只取文件名
%~x0:只取文件扩展名
%~s0:取缩写全路径名
%~a0:取文件属性
%~t0:取文件创建时间
%~z0:取文件大小
pause
  • 转义符号:如果要显示%本身时,需要在前面用%来转义
1
2
3
4
5
@echo off
echo 一个百分号:%%
echo 两个百分号:%%%%
echo 三个百分号:%%%%%%
pause

界定符 “”

  • 在表示带有空格或特殊符号的路径时常要用" "来将路径括起来
  • 表示其中的内容是一个完整的字符串
1
2
3
4
5
6
7
8
9
cd /d cd "d:\program files\^%*abc"
@echo off
set "var=abc 123"
echo %var%
pause

c:\>cd “Program Files”
c:\>cd progra~1
c:\>cd pro*

批处理之for语句

Posted on 2016-08-11

for基本用法

  • cmd窗口: for %i in (command1) do command2
  • 批处理中: for %%i in (command1) do command2

基本要素:

  1. or、in和do是for语句的关键字,它们三个缺一不可;
  2. %%I是for语句中对形式变量的引用,就算它在do后的语句中没有参与语句的执行,也是必须出现的;
  3. in之后,do之前的括号不能省略;
  4. command1和command2表示字符串、变量或命令语句;
  5. command1之间的元素需要用空格键, tab键, 逗号, 分号, 或等号分割;

例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
for %%i in (bbs.bathome.cn) do (
echo %%i
)

for %%i in (bbs,bathome,cn) do (
echo %%i
)

set str=c d e f g h i j k l m n o p q r s t u v w x y z
echo 当前硬盘的分区有:
for %%i in (%str%) do if exist %%i: echo %%i:

echo ====列出所有文件====
for %%i in (*.*) do (
echo "%%i"
)

echo ====列出txt类型的文件====
for %%i in (*.txt) do (
echo "%%i"
)

echo ====列出文件名只有3个字符的bat文件====
for %%i in (???.bat) do (
echo "%%i"
)

echo ====循环建立三个空文件====
for %%i in (1,2,3) do (
type nul>test%%i.txt
)

文本解析: for /f

基本用法

例子:

1
2
3
4
5
rem 每次读取文本的一行数据
for /f %%i in (test1.txt) do (
echo ===========
echo %%i
)

切分字符串: delims=

例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
echo -----------------------------------------
:: 如果没有用delims, 默认会以空格或者tab键为分割符
for /f %%i in (test1.txt) do (
echo ===========
echo %%i
)

echo -----------------------------------------
:: 这里以逗号为分割符
for /f "delims=," %%i in (test1.txt) do (
echo ===========
echo %%i
)
echo -----------------------------------------
:: 这里以点号和逗号为分割符, 截取前面的内容
for /f "delims=.," %%i in (test1.txt) do (
echo ===========
echo %%i
)

定点提取: tokens=

辅助delims, 用于提取具体的一段
例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
:: 默认是以空格为分割符
for /f "tokens=1-3" %%i in (test2.txt) do (
echo %%i
echo %%j
echo %%k
)

echo -----------------------------------------------
for /f "delims=, tokens=2-5" %%i in (test3.txt) do (
echo %%i
echo %%j
echo %%k
echo %%l
)
echo -----------------------------------------------
for /f "delims=, tokens=2,3-5" %%i in (test3.txt) do (
echo %%i
echo %%j
echo %%k
echo %%l
)

跳过无关内容, 直奔主题: skip=n

跳过n行, 从n+1行开始
例子:

1
for /f "skip=2" %%i in (test3.txt) do echo %%i

忽略以指定字符打头的行: eol=

例子:

1
2
3
4
5
6
7
echo -----------------------------------------------
:: 忽略以;开头的行
for /f "eol=;" %%i in (test4.txt) do echo %%i

echo -----------------------------------------------
:: eol后面只能指定一个字符
for /f "eol=," %%i in (test4.txt) do echo %%i

使用哪种格式?

  1. for /f %%i in (文件名) do (…)
  2. for /f %%i in (‘命令语句’) do (…)
  3. for /f %%i in (“字符串”) do (…)
  4. for /f “usebackq” %%i in (“文件名”) do (……)
  5. for /f “usebackq” %%i in (命令语句) do (……)
  6. for /f “usebackq” %%i in (‘字符串’) do (……) 

例子:

1
2
3
echo -----------------------------------------------
:: 先找到文件,在逐个输出
for /f %%i in ('dir /a-d /b test*.txt') do echo %%i

当路径中包含特殊字符时,需要使用usebackq, 它是一个增强型参数, 使用后, command1需要变动如下:

  1. 如果第一个括号里的对象是一条命令语句的话,原来的单引号’要改为后引号 `
  2. 如果第一个括号里的对象是字符串的话,原来的双引号”要改为单引号’
  3. 如果第一个括号里的对象是文件名的话,要用双引号”括起来

例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
@echo off
echo ------------------------------------------------
:: 找不到文件
for /f %%i in (test .txt) do echo %%i
:: 当成字符串处理
for /f %%i in ("test .txt") do echo %%i
:: 错误
for /f %%i in ('test .txt') do echo %%i
:: 找不到文件
for /f %%i in (`test .txt`) do echo %%i

echo ------------------------------------------------
:: for /f "delims==" %%i in ('set') do echo %%i

echo ------------------------------------------------
:: 使用usebakq时候需要将(command1)的单引号改为 反引号 `(1旁边的)
:: for /f "usebackq delims==" %%i in (`set`) do echo %%i

echo ------------------------------------------------
for /f "usebackq" %%i in ("test .txt") do echo %%i
pause

批处理中常用的变量

Posted on 2016-08-11

预定义的变量

下面是些已经被底层定义好可以直接使用的变量:不会出现在 SET 显示的变量列表中

  • %CD% - 扩展到当前目录字符串。
  • %DATE% - 用跟 DATE 命令同样的格式扩展到当前日期。
  • %TIME% - 用跟 TIME 命令同样的格式扩展到当前时间。
  • %RANDOM% - 扩展到 0 和 32767 之间的任意十进制数字。
  • %ERRORLEVEL% - 扩展到当前 ERRORLEVEL 数值。
  • %CMDEXTVERSION% - 扩展到当前命令处理器扩展名版本号。
  • %CMDCMDLINE% - 扩展到调用命令处理器的原始命令行。
  • %0 bat的完整路径名如”C:\Windows\system32\xxx.bat”
  • %1 bat参数1依次类推%2参数2…
  • %path% - 当前的环境变量。以分号隔开的路径列表,路径可包含空格,可以以’\’结尾, 可以以双引号包围之。

扩展变量

与%i相关的变量(bat参数或者for循环的%i)

假设文件为C:\Documents and Settings\jinsun\桌面\ParseSinglePkgs.bat

  • %0 C:\Documents and Settings\jinsun\桌面\ParseSinglePkgs.bat
  • %~dp0 C:\Documents and Settings\jinsun\桌面\
  • %cd% C:\Documents and Settings\jinsun\桌面
  • %~nx0 ParseSinglePkgs.bat
  • %~n0 ParseSinglePkgs
  • %~x0 .bat

与%VAR%相关的变量

  • %VAR:str1=str2% 会将VAR中的str1替换为str2(str2如果为空则可以达到删除的效果,str1前可以加_,变量%ABC:_B=%是C)
  • %VAR:~0,-2% 会提取VAR 变量的所有字符,除了最后两个
  • %VAR:~-2% 会提取VAR 变量的最后两个

系统变量

他们的值由系统将其根据事先定义的条件自动赋值,我们只需要调用而已

  • %ALLUSERSPROFILE% (allusersprofile)本地 返回”所有用户”配置文件的位置。 C:Documents and SettingsAll Users
  • %APPDATA% (appdata)本地返回默认情况下应用程序存储数据的位置。 C:Documents and SettingsAdministratorApplication Data
  • %CD% (cd)本地返回当前目录字符串。 C:Documents and SettingsAdministrator桌面
  • %CMDCMDLINE% (cmdcmdline)本地返回用来启动当前的 Cmd.exe 的准确命令行。 cmd /c “”C:Documents and SettingsAdministrator桌面a.bat” “
  • %CMDEXTVERSION%(cmdextversion)系统返回当前的”命令处理程序扩展”的版本号。2
  • %COMPUTERNAME% (computername)系统返回计算机的名称。 xxxx
  • %COMSPEC% (comspec) 系统返回命令行解释器可执行程序的准确路径。 C:WINDOWSsystem32cmd.exe
  • %DATE% 系统返回当前日期。使用与 date /t 命令相同的格式。由 Cmd.exe 生成。有关 date 命令的详细信息,请参阅 Date。
  • %ERRORLEVEL% (errorlevel) 系统返回上一条命令的错误代码。通常用非零值表示错误。
  • %HOMEDRIVE% (homedrive)系统返回连接到用户主目录的本地工作站驱动器号。基于主目录值而设置。用户主目录是在”本地用户和组”中指定的。 C:
  • %HOMEPATH% (homepath) 系统返回用户主目录的完整路径。基于主目录值而设置。用户主目录是在”本地用户和组”中指定的。 Documents and SettingsAdministrator
  • %HOMESHARE% (homeshare) 系统返回用户的共享主目录的网络路径。基于主目录值而设置。用户主目录是在”本地用户和组”中指定的。
  • %LOGONSERVER% (logonserver) 本地返回验证当前登录会话的域控制器的名称 \ xxxx
  • %NUMBER_OF_PROCESSORS% (numeer_of_processors) 系统指定安装在计算机上的处理器的数目。
  • %OS% (os)系统返回操作系统名称。Windows 2000 显示其操作系统为 Windows_NT。 Windows_NT
  • %PATH% (path)系统指定可执行文件的搜索路径
  • %PATHEXT% (pathext)系统返回操作系统认为可执行的文件扩展名的列表。 .COM .EXE .BAT .CMD .VBS .VBE .JS .JSE .WSF .WSH
  • %PROCESSOR_ARCHITECTURE% (processor_architecture) 系统返回处理器的芯片体系结构。值:x86 或 IA64 基于Itanium x86
  • %PROCESSOR_IDENTFIER% (processor_identfier)系统返回处理器说明。
  • %PROCESSOR_LEVEL% (processor_level)系统返回计算机上安装的处理器的型号。 15
  • %PROCESSOR_REVISION% (processor_revision)系统返回处理器的版本号。 4f02
  • %PROMPT% (prompt)本地 返回当前解释程序的命令提示符设置。由 Cmd.exe 生成。$P$G
  • %RANDOM% (random)系统返回 0 到 32767 之间的任意十进制数字。由 Cmd.exe 生成。 30580
  • %SYSTEMDRIVE% (systemdrive)系统返回包含 Windows server operating system 根目录(即系统根目录)的驱动器。 C:
  • %SYSTEMROOT% (systemroot)系统返回 Windows server operating system 根目录的位置。C:WINDOWS
  • %TEMP%(temp) 系统和用户返回对当前登录用户可用的应用程序所使用的默认临时目录。有些应用程序需要 TEMP,而其他应用程序则需要 TMP。
  • %TIME% 系统 返回当前时间。使用与 time /t 命令相同的格式。由 Cmd.exe 生成。有关 time 命令的详细信息,请参阅 Time。
  • %USERDOMAIN% (userdomain)本地返回包含用户帐户的域的名称。 xxxx
  • %USERNAME% (username)本地返回当前登录的用户的名称。 Administrator
  • %USERPROFILE% (userprofile)本地返回当前用户的配置文件的位置。 C:Documents and SettingsAdministrator
  • %WINDIR%(windir) 系统 返回操作系统目录的位置。 C:WINDOWS

批处理之 set语句

Posted on 2016-08-11

set语句

用set设置自定义变量

set [vaiable=[string]]
例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
:: 设置的时候等号俩边不能有空格
set var=abcd
echo var的值为%var%

:: 清除变量,使其成为未定义状态
set var=
if defined var (echo var的值为%var%) else echo var没有赋值

set var1=""
if defined var1 (echo var1的值为%var1%) else echo var1没有赋值

:: set还可以提供一个交互界面,让用户自己输入变量的值,
:: 然后我们在来根据这个值来做相应操作,只需要加一个"/P"参数就可以了!
set /p var2=请输入变

用set进行字符串处理

  1. 字符串替换
    %PATH:STR1=STR2% : 将字符串变量%PATH%中的str1替换为str2
    例子:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    set a= bbs. bathome.cn
    echo 替换前为:"%a%"

    :: 删除里面的空格
    set var=%a: =%
    echo 替换后为: %var%

    set var1= %a:.=逗号%
    echo 替换后为: %var1%
  2. 字符串截取
    %a:~[m[,n]]% : ~偏移, m为偏移量(从0开始), n为截取长度

例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
set a=www.github.com
echo 源字符串为: %a%
set var=%a:~3,5%
echo 截取的一点: %var%

:: 倒数从-1开始
:: 从第一个到倒数第三个之前的(ww.github.)
set var3=%a:~1,-3%
echo %var3%

:: 倒数第三个之后的(com)
set var4=%a:~-3%
echo %var4%

:: 从倒数第三个开始取俩个字符(co)
set var1=%a:~-3,2%
echo %var1%

::从第三个开始到结束(.github.com)
set var2=%a:~3%
echo %var2%

  1. 综合实例之求字符串长度
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    @echo off
    set /p str=请输入任意长度的字符串:
    echo 你输入了字符串: "%str%"
    call :stringlenth "%str%" num
    echo 字符串长度: %num%
    pause

    :stringlenth
    :: echo %1
    :: 字符串计算子程序
    set substr=%~1
    :: echo %substr%
    :: 参数%1 为字符串"%str%", %~1则为去掉双引号
    if not defined substr goto :eof
    set Ret=0

    :stringlenth_continue
    set /a Ret +=1
    set substr=%substr:~0,-1%
    echo %substr%
    if defined substr goto stringlenth_continue
    if not "%2"=="" set %2=%Ret%
    goto :eof

用set进行简单计算

set /a expression

  1. 运算符:
1
2
3
4
5
6
7
8
9
10
11
( )             分组
! ~ - 一元运算符
* / % 算数运算符
- 算数运算符
<< >> 二进制逻辑移位
& 二进制按位“与”
^ 二进制按位“异”
| 二进制按位“或”
= *= /= %= = -= 算数赋值
&= ^= |= <<= >>= 二进制运算赋值
, 表达式分隔符
  1. 不支持浮点数
  2. 求余运算符 %%
  3. 逻辑或取余操作符, 需要用双引号括起来或者用转义字符^:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    set /a var= 1 " " 1  异运算
    set /a var= 1 "%" 1 取模运算
    set /a var= 3 "<<" 2 左移位运算, 3 的二进制为11,左移2 位为 1100,换成十进制就是12,自行验证
    set /a var= 4 ">>" 2 右移位运算,4 的二进制为100,右移动2 位为 1,结果为1

    @echo off
    set /p n=请输入2 的几次方:
    set /a num=1^<^<n
    echo %num%
    pause

gtags的使用

Posted on 2016-08-06

是啥?

类似于ctags, 为代码添加标签, 但是对于c++, c语言, 更精确.

使用

生成文件列表

1
2
3
4
5
6
:: windows
> dir [path] /a-d /b /s *.cpp *.h > filelist.txt

:: windows
> find [path] -type f -regex ".*\(\.cpp\|\.c\)$" > filelist.txt
> find . -type f \( -name "*.java" -o -name "*.cpp" -o -name "*.h" \)

生成标签

1
2
3
4
5
6
7
8
9
10
> gtags
:: 根据文件列表生成
> gtags -f filelist
:: 可以使用ctags解析gtags不支持的语言
> gtags -f filelist --gtagslabel ctags

:: 生成的文件的含义
:: GTAGS:所有变量,函数定义的相关信息
:: GRTAGS:所有变量,函数被引用的相关信息
:: GPATH:源代码中每个文件的信息

查看文件内容

1
2
3
> gtags --dump GPATH
> gtags --dump GTAGS
> gtags --dump GRTAGS

更新单个文件

1
> gtags --single-update filename

基本用法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 查找函数
$ global func1
# 话说支持Posix 正则, 待验证
$ global 'func[1-3]' # func1, func2, func3 match
# 引用
$ global -r func
# 显示详细信息 (显示定义行的信息)
$ global -x func
# 显示匹配的内容的文件的完整路径(绝对路径)
$ global -a func
# 显示不在GTAGS里面定义的symbols(感觉没屌用)
$ global -s X
# 使用指定的模式定位(没懂啥意思, 懂了补充)
$ global -g '#ifdef'
# 定位某个文件(可以用正则, 没多大屌用)
$ global -P fileB | '1/' | '\.c$'
# 查看某一个文件的tags
$ global -f path/filename
# 在当前文件夹下检索
$ global -l func
# 如果你忘了symbol名字, 可以用-c进行提示
$ global -c create
1…3456

DaSea

Fucking Code!

51 posts
25 tags
GitHub
© 2018 DaSea
Powered by Hexo v3.7.1
|
Theme — NexT.Gemini v6.3.0