<?xml version="1.0" encoding="UTF-8"?>
<rdf:RDF
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns="http://purl.org/rss/1.0/"
xmlns:dc="http://purl.org/dc/elements/1.1/">
<channel rdf:about="https://dwt.life/feed/rss/">
<title>dwt&#039;s life</title>
<link>https://dwt.life/</link>
<description>Recording everything in my life.</description>
<items>
<rdf:Seq>
<rdf:li resource="https://dwt.life/archives/345/"/>
<rdf:li resource="https://dwt.life/archives/342/"/>
<rdf:li resource="https://dwt.life/archives/341/"/>
<rdf:li resource="https://dwt.life/archives/338/"/>
<rdf:li resource="https://dwt.life/archives/336/"/>
<rdf:li resource="https://dwt.life/archives/335/"/>
<rdf:li resource="https://dwt.life/archives/334/"/>
<rdf:li resource="https://dwt.life/archives/333/"/>
<rdf:li resource="https://dwt.life/archives/332/"/>
<rdf:li resource="https://dwt.life/archives/330/"/>
</rdf:Seq>
</items>
</channel>
<item rdf:about="https://dwt.life/archives/345/">
<title>golang 7zip dll</title>
<link>https://dwt.life/archives/345/</link>
<dc:date>2024-10-10T23:04:19+08:00</dc:date>
<description>创建目录 zipdll代码：unzip.gopackage main

/*
#include &lt;stdlib.h&gt;

// 定义回调类型
typedef void (*Callback)(const char*);
// 将 call_callback 声明为 static
static void call_callback(void (*cb)(const char*), const char* message) {
    if (cb != NULL) {
        cb(message);
    }
}

*/
import &quot;C&quot;
import (
    &quot;fmt&quot;
    &quot;io&quot;
    &quot;os&quot;
    &quot;path/filepath&quot;
    &quot;github.com/bodgit/sevenzip&quot;
)

// 计算 7z 文件的总大小
func calculate7zTotalSize(reader *sevenzip.Reader) int64 {
    var totalSize int64
    for _, file := range reader.File {
        totalSize += int64(file.UncompressedSize)
    }
    return totalSize
}

// 解压 7z 文件并调用回调
//export Unzip7zWithCallback
func Unzip7zWithCallback(archivePath *C.char, destDir *C.char, cb C.Callback) {
    goArchivePath := C.GoString(archivePath)
    goDestDir := C.GoString(destDir)

    // 打开 7z 文件
    file, err := os.Open(goArchivePath)
    if err != nil {
        C.call_callback(cb, C.CString(&quot;Failed to open 7z file&quot;))
        return
    }
    defer file.Close()

    // 获取文件信息
    fileInfo, err := file.Stat()
    if err != nil {
        C.call_callback(cb, C.CString(&quot;Failed to get file info&quot;))
        return
    }

    // 创建 7z 读取器
    reader, err := sevenzip.NewReader(file, fileInfo.Size())
    if err != nil {
        C.call_callback(cb, C.CString(&quot;Failed to create 7z reader&quot;))
        return
    }

    // 计算总大小以跟踪进度
    totalSize := calculate7zTotalSize(reader)
    if totalSize == 0 {
        C.call_callback(cb, C.CString(&quot;Empty 7z file&quot;))
        return
    }

    var processedSize int64
    progressStep := totalSize / 200 // 0.5% 对应的字节数
    nextProgressTrigger := progressStep

    // 解压文件
    for _, file := range reader.File {
        path := filepath.Join(goDestDir, file.Name)

        // 检查是否是目录
        if file.FileHeader.FileInfo().IsDir() {
            os.MkdirAll(path, 0755)
            continue
        }

        // 创建解压目标文件
        if err := os.MkdirAll(filepath.Dir(path), 0755); err != nil {
            C.call_callback(cb, C.CString(fmt.Sprintf(&quot;Failed to create directory: %s&quot;, err.Error())))
            return
        }

        destFile, err := os.Create(path)
        if err != nil {
            C.call_callback(cb, C.CString(fmt.Sprintf(&quot;Failed to create file: %s&quot;, err.Error())))
            return
        }
        defer destFile.Close()

        // 打开 7z 内部文件
        rc, err := file.Open()
        if err != nil {
            C.call_callback(cb, C.CString(fmt.Sprintf(&quot;Failed to open entry in 7z: %s&quot;, err.Error())))
            return
        }
        defer rc.Close()

        // 复制文件并更新进度
        buffer := make([]byte, 1024*64) // 每次读取 64KB
        for {
            n, err := rc.Read(buffer)
            if err != nil &amp;&amp; err != io.EOF {
                C.call_callback(cb, C.CString(fmt.Sprintf(&quot;Failed to read file: %s&quot;, err.Error())))
                return
            }
            if n == 0 {
                break
            }

            if _, err := destFile.Write(buffer[:n]); err != nil {
                C.call_callback(cb, C.CString(fmt.Sprintf(&quot;Failed to write file: %s&quot;, err.Error())))
                return
            }

            // 更新处理的字节数
            processedSize += int64(n)

            // 每 0.5% 调用一次回调
            if processedSize &gt;= nextProgressTrigger {
                progress := float64(processedSize) / float64(totalSize) * 100
                C.call_callback(cb, C.CString(fmt.Sprintf(&quot;Progress: %.2f%%&quot;, progress)))
                nextProgressTrigger += progressStep
            }
        }
    }

    C.call_callback(cb, C.CString(&quot;7z extraction completed successfully&quot;))
}

func main() {}目录下执行 go mod initgo mod tidy编译：GOOS=windows GOARCH=amd64 go build -o unzip7z_64.dll -buildmode=c-shared unzip.goGOOS=windows GOARCH=386 go build -o unzip7z_32.dll -buildmode=c-shared unzip.go</description>
</item>
<item rdf:about="https://dwt.life/archives/342/">
<title>gomobile 编译</title>
<link>https://dwt.life/archives/342/</link>
<dc:date>2024-07-27T18:38:53+08:00</dc:date>
<description>gomobile bind -target=android golang.org/x/mobile/example/bind/hello
gomobile bind -target=android ./engine</description>
</item>
<item rdf:about="https://dwt.life/archives/341/">
<title>macOS llvm@14</title>
<link>https://dwt.life/archives/341/</link>
<dc:date>2024-05-19T16:28:22+08:00</dc:date>
<description>brew install llvm@14
  export LDFLAGS=&quot;-L/opt/homebrew/opt/llvm@14/lib&quot;
  export CPPFLAGS=&quot;-I/opt/homebrew/opt/llvm@14/include&quot;</description>
</item>
<item rdf:about="https://dwt.life/archives/338/">
<title>armbian/debian/linux 硬盘休眠 </title>
<link>https://dwt.life/archives/338/</link>
<dc:date>2024-03-03T01:40:11+08:00</dc:date>
<description>该篇教程主要讲解设置hdparm让硬盘自动休眠，如果你打算用arm设备作为Linux备份机Tip：该教程只适用相关系统硬盘不能自动休眠或无休眠设置项，设置需要按实际情况设置。查看是否已安装hdparm#hdparm安装hdparm#
sudo apt-get install hdparm
查看硬盘是否支持写入缓存，有* (星号)，表示支持#
sudo hdparm -I /dev/sda | grep &#039;Write cache&#039;
让硬盘进入待机模式#
hdparm -y /dev/sda1
让硬盘进入睡眠模式#
hdparm -Y /dev/sda1
设置定时休眠#
5分钟无操作休眠（参数是5的倍数，比如60*5是300秒也就是5分钟）

hdparm -S 60 /dev/sda1
修改hdparm配置#
ls /dev/disk/by-id查看你的硬盘IDsudo vim /etc/hdparm.conf
/dev/disk/by-id/ata-TOSHIBA_MD04ABA400V_2818KRSKFMYB {
    apm  = 127
    spindown_time = 60
    write_cache = on
}然后执行sudo /usr/lib/pm-utils/power.d/95hdparm-apm resume或者重启在5分没使用硬盘的情况下, 硬盘会自动休眠了ps :/dev/disk/by-id/* 自己去看下这个目录下自己的文件名spindown_time 60 计算参考
0 = disabled
1..240 = multiples of 5 seconds (5 seconds to 20 minutes)
241..251 = 1..11 x 30 mins
252 = 21 mins
253 = vendor defined (8..12 hours)
254 = reserved
255 = 21 mins + 15 secs
write_cache 写缓存自己决定是否要开启,可以使用off不支持apm的需要设置 force_spindown_time 看文档说的是除了spindown以外参数都正常https://blog.csdn.net/lovefengchenlove/article/details/129468283https://www.cnblogs.com/HGNET/p/17077365.html</description>
</item>
<item rdf:about="https://dwt.life/archives/336/">
<title>Android studio 编译aar</title>
<link>https://dwt.life/archives/336/</link>
<dc:date>2024-02-26T23:34:41+08:00</dc:date>
<description>有时候可能因为交叉编译导致c jni有些头文件路径不对，修改对了以后再执行./gradlew :Tun2socks:assembleDebug即可</description>
</item>
<item rdf:about="https://dwt.life/archives/335/">
<title>MacOS 编译.net到linux平台</title>
<link>https://dwt.life/archives/335/</link>
<dc:date>2023-11-19T20:32:20+08:00</dc:date>
<description>dotnet publish --configuration Release  --os linux --arch x64</description>
</item>
<item rdf:about="https://dwt.life/archives/334/">
<title>MacOS下的openresty编译过程</title>
<link>https://dwt.life/archives/334/</link>
<dc:date>2023-10-30T22:56:49+08:00</dc:date>
<description>其实还是比较简单的，毕竟homebrew已经很方便的安装了依赖，还是记录一下基本依赖我本地的brew是更新过了的，从github下载的最新releasebrew update                            
brew install pcre opensslconfigureLinux:./configure \                          
   --with-cc-opt=&quot;-I/usr/local/opt/openssl/include/ -I/usr/local/opt/pcre/include/&quot; \
   --with-ld-opt=&quot;-L/usr/local/opt/openssl/lib/ -L/usr/local/opt/pcre/lib/&quot; \
   -j8MacOS:./configure \                     
   --with-cc-opt=&quot;-I/opt/homebrew/include/openssl/ -I/opt/homebrew/include/&quot; \
   --with-ld-opt=&quot;-L/opt/homebrew/lib/&quot; \
   -j8这里的路径是我自己找的，brew应该都一样，但是看到别的文章和我的不一样，所以应该先检查include和lib的路径brotliBrotli比我当年编译的简单多了:git clone https://github.com/google/ngx_brotli.git`
cd ngx_brotli/deps/brotli
git clone https://github.com/google/brotli.git
cd ..
./configure \                      
   --with-cc-opt=&quot;-I/opt/homebrew/include/openssl/ -I/opt/homebrew/include/&quot; \
   --with-ld-opt=&quot;-L/opt/homebrew/lib/ --add-module=/路径/ngx_brotli&quot; \
   -j8然后make -j8 && make install 就到了/usr/local/openresty下了</description>
</item>
<item rdf:about="https://dwt.life/archives/333/">
<title>【转载】MySql 外键约束 之CASCADE、SET NULL、RESTRICT、NO ACTION分析和作用</title>
<link>https://dwt.life/archives/333/</link>
<dc:date>2023-06-20T19:30:49+08:00</dc:date>
<description>https://www.cnblogs.com/yzuzhang/p/5174720.htmlMySQL有两种常用的引擎类型：MyISAM和InnoDB。目前只有InnoDB引擎类型支持外键约束。InnoDB中外键约束定义的语法如下：ALTER TABLE tbl_name
    ADD [CONSTRAINT [symbol]] FOREIGN KEY
    [index_name] (index_col_name, ...)
    REFERENCES tbl_name (index_col_name,...)
    [ON DELETE reference_option]
    [ON UPDATE reference_option]例如：ALTER TABLE `user_resource` CONSTRAINT `FKEEAF1E02D82D57F9` FOREIGN KEY (`user_Id`) REFERENCES `sys_user` (`Id`)InnoDB也支持使用ALTER TABLE来删除外键：ALTER TABLE user_resource DROP FOREIGN KEY FKEEAF1E02D82D57F9;CASCADE在父表上update/delete记录时，同步update/delete掉子表的匹配记录 SET NULL在父表上update/delete记录时，将子表上匹配记录的列设为null (要注意子表的外键列不能为not null)  NO ACTION如果子表中有匹配的记录,则不允许对父表对应候选键进行update/delete操作  RESTRICT同no action, 都是立即检查外键约束SET NULL父表有变更时,子表将外键列设置成一个默认的值 但Innodb不能识别NULL、RESTRICT、NO ACTION删除：从表记录不存在时，主表才可以删除。删除从表，主表不变更新：从表记录不存在时，主表才可以更新。更新从表，主表不变CASCADE删除：删除主表时自动删除从表。删除从表，主表不变更新：更新主表时自动更新从表。更新从表，主表不变SET NULL删除：删除主表时自动更新从表值为NULL。删除从表，主表不变更新：更新主表时自动更新从表值为NULL。更新从表，主表不变外键约束属性： RESTRICT | CASCADE | SET NULL | NO ACTION  外键的使用需要满足下列的条件：两张表必须都是InnoDB表，并且它们没有临时表。建立外键关系的对应列必须具有相似的InnoDB内部数据类型。建立外键关系的对应列必须建立了索引。假如显式的给出了CONSTRAINT symbol，那symbol在数据库中必须是唯一的。假如没有显式的给出，InnoDB会自动的创建。如果子表试图创建一个在父表中不存在的外键值，InnoDB会拒绝任何INSERT或UPDATE操作。如果父表试图UPDATE或者DELETE任何子 表中存在或匹配的外键值，最终动作取决于外键约束定义中的ON UPDATE和ON DELETE选项。InnoDB支持5种不同的动作，如果没有指定ON DELETE或者ON UPDATE，默认的动作为RESTRICT:CASCADE: 从父表中删除或更新对应的行，同时自动的删除或更新自表中匹配的行。ON DELETE CANSCADE和ON UPDATE CANSCADE都被InnoDB所支持。SET NULL: 从父表中删除或更新对应的行，同时将子表中的外键列设为空。注意，这些在外键列没有被设为NOT NULL时才有效。ON DELETE SET NULL和ON UPDATE SET SET NULL都被InnoDB所支持。NO ACTION: InnoDB拒绝删除或者更新父表。RESTRICT: 拒绝删除或者更新父表。指定RESTRICT（或者NO ACTION）和忽略ON DELETE或者ON UPDATE选项的效果是一样的。SET DEFAULT: InnoDB目前不支持。外键约束使用最多的两种情况无外乎：1）父表更新时子表也更新，父表删除时如果子表有匹配的项，删除失败；2）父表更新时子表也更新，父表删除时子表匹配的项也删除。前一种情况，在外键定义中，我们使用ON UPDATE CASCADE ON DELETE RESTRICT；后一种情况，可以使用ON UPDATE CASCADE ON DELETE CASCADE。当执行外键检查之时，InnoDB对它照看着的子或父记录设置共享的行级锁。InnoDB立即检查外键约束，检查不对事务提交延迟。要使得对有外键关系的表重新载入转储文件变得更容易，mysqldump自动在转储输出中包括一个语句设置FOREIGN_KEY_CHECKS为0。这避免在转储被重新装载之时，与不得不被以特别顺序重新装载的表相关的问题。也可以手动设置这个变量：mysql&gt; SET FOREIGN_KEY_CHECKS = 0;

mysql&gt; SOURCE dump_file_name;

mysql&gt; SET FOREIGN_KEY_CHECKS = 1;　　如果转储文件包含对外键是不正确顺序的表，这就以任何顺序导入该表。这样也加快导入操作。设置FOREIGN_KEY_CHECKS为0，对于在LOAD DATA和ALTER TABLE操作中忽略外键限制也是非常有用的。InnoDB不允许你删除一个被FOREIGN KEY表约束引用的表，除非你做设置SET FOREIGN_KEY_CHECKS=0。当你移除一个表的时候，在它的创建语句里定义的约束也被移除。　　如果你重新创建一个被移除的表，它必须有一个遵从于也引用它的外键约束的定义。它必须有正确的列名和类型，并且如前所述，它必须对被引用的键有索引。如果这些不被满足，MySQL返回错误号1005 并在错误信息字符串中指向errno 150。</description>
</item>
<item rdf:about="https://dwt.life/archives/332/">
<title>巴欧教程正则</title>
<link>https://dwt.life/archives/332/</link>
<dc:date>2023-06-18T22:13:54+08:00</dc:date>
<description>|#&lt;a1&gt;(.?)#is&gt; &#8617;</description>
</item>
<item rdf:about="https://dwt.life/archives/330/">
<title>nslookup指定端口</title>
<link>https://dwt.life/archives/330/</link>
<dc:date>2023-04-10T17:26:00+08:00</dc:date>
<description>dig google.com @192.168.0.1 -p 65053在线nslookup：https://tool.hi.cn/nslookup/</description>
</item>
</rdf:RDF>