<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
xmlns:content="http://purl.org/rss/1.0/modules/content/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
xmlns:atom="http://www.w3.org/2005/Atom"
xmlns:wfw="http://wellformedweb.org/CommentAPI/">
<channel>
<title>dwt&#039;s life</title>
<link>https://dwt.life/</link>
<atom:link href="https://dwt.life/feed/" rel="self" type="application/rss+xml" />
<language>zh-CN</language>
<description>Recording everything in my life.</description>
<lastBuildDate>Thu, 10 Oct 2024 23:04:19 +0800</lastBuildDate>
<pubDate>Thu, 10 Oct 2024 23:04:19 +0800</pubDate>
<item>
<title>golang 7zip dll</title>
<link>https://dwt.life/archives/345/</link>
<guid>https://dwt.life/archives/345/</guid>
<pubDate>Thu, 10 Oct 2024 23:04:19 +0800</pubDate>
<dc:creator>Ricky</dc:creator>
<description><![CDATA[创建目录 zipdll代码：unzip.gopackage main/*#include &lt;stdlib.h&gt;// 定义回调类型typedef void (*Callback)(co...]]></description>
<content:encoded xml:lang="zh-CN"><![CDATA[
<p>创建目录 zipdll</p><p>代码：<br>unzip.go</p><pre><code class="lang-go">package 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() {}</code></pre><p>目录下执行 <code>go mod init</code><br><code>go mod tidy</code></p><p>编译：<code>GOOS=windows GOARCH=amd64 go build -o unzip7z_64.dll -buildmode=c-shared unzip.go</code><br><code>GOOS=windows GOARCH=386 go build -o unzip7z_32.dll -buildmode=c-shared unzip.go</code></p>
]]></content:encoded>
<slash:comments>2</slash:comments>
<comments>https://dwt.life/archives/345/#comments</comments>
<wfw:commentRss>https://dwt.life/feed/</wfw:commentRss>
</item>
<item>
<title>gomobile 编译</title>
<link>https://dwt.life/archives/342/</link>
<guid>https://dwt.life/archives/342/</guid>
<pubDate>Sat, 27 Jul 2024 18:38:53 +0800</pubDate>
<dc:creator>Ricky</dc:creator>
<description><![CDATA[gomobile bind -target=android golang.org/x/mobile/example/bind/hellogomobile bind -target=android...]]></description>
<content:encoded xml:lang="zh-CN"><![CDATA[
<pre><code>gomobile bind -target=android golang.org/x/mobile/example/bind/hello
gomobile bind -target=android ./engine</code></pre>
]]></content:encoded>
<slash:comments>0</slash:comments>
<comments>https://dwt.life/archives/342/#comments</comments>
<wfw:commentRss>https://dwt.life/feed/</wfw:commentRss>
</item>
<item>
<title>macOS llvm@14</title>
<link>https://dwt.life/archives/341/</link>
<guid>https://dwt.life/archives/341/</guid>
<pubDate>Sun, 19 May 2024 16:28:22 +0800</pubDate>
<dc:creator>Ricky</dc:creator>
<description><![CDATA[brew install llvm@14  export LDFLAGS=&quot;-L/opt/homebrew/opt/llvm@14/lib&quot;  export CPPFLAGS...]]></description>
<content:encoded xml:lang="zh-CN"><![CDATA[
<pre><code>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;</code></pre>
]]></content:encoded>
<slash:comments>0</slash:comments>
<comments>https://dwt.life/archives/341/#comments</comments>
<wfw:commentRss>https://dwt.life/feed/</wfw:commentRss>
</item>
<item>
<title>armbian/debian/linux 硬盘休眠 </title>
<link>https://dwt.life/archives/338/</link>
<guid>https://dwt.life/archives/338/</guid>
<pubDate>Sun, 03 Mar 2024 01:40:11 +0800</pubDate>
<dc:creator>Ricky</dc:creator>
<description><![CDATA[该篇教程主要讲解设置hdparm让硬盘自动休眠，如果你打算用arm设备作为Linux备份机Tip：该教程只适用相关系统硬盘不能自动休眠或无休眠设置项，设置需要按实际情况设置。查看是否已安装hdp...]]></description>
<content:encoded xml:lang="zh-CN"><![CDATA[
<p>该篇教程主要讲解设置hdparm让硬盘自动休眠，如果你打算用arm设备作为Linux备份机</p><p>Tip：该教程只适用相关系统硬盘不能自动休眠或无休眠设置项，设置需要按实际情况设置。</p><p>查看是否已安装hdparm#<br>hdparm</p><p><img src="https://pic.peo.pw/a/2024/03/03/65e3552b44bd0.png" alt="1935144006.png" title="1935144006.png"></p><pre><code>安装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</code></pre><p>查看你的硬盘ID</p><pre><code>sudo vim /etc/hdparm.conf
/dev/disk/by-id/ata-TOSHIBA_MD04ABA400V_2818KRSKFMYB {
    apm  = 127
    spindown_time = 60
    write_cache = on
}</code></pre><p>然后执行<br>sudo /usr/lib/pm-utils/power.d/95hdparm-apm resume<br>或者重启</p><p>在5分没使用硬盘的情况下, 硬盘会自动休眠了</p><p>ps :</p><p>/dev/disk/by-id/* 自己去看下这个目录下自己的文件名<br>spindown_time 60 计算参考</p><pre><code>
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</code></pre><p>不支持apm的需要设置 force_spindown_time 看文档说的是除了spindown以外参数都正常</p><p><a href="https://blog.csdn.net/lovefengchenlove/article/details/129468283">https://blog.csdn.net/lovefengchenlove/article/details/129468283</a><br><a href="https://www.cnblogs.com/HGNET/p/17077365.html">https://www.cnblogs.com/HGNET/p/17077365.html</a></p>
]]></content:encoded>
<slash:comments>0</slash:comments>
<comments>https://dwt.life/archives/338/#comments</comments>
<wfw:commentRss>https://dwt.life/feed/</wfw:commentRss>
</item>
<item>
<title>Android studio 编译aar</title>
<link>https://dwt.life/archives/336/</link>
<guid>https://dwt.life/archives/336/</guid>
<pubDate>Mon, 26 Feb 2024 23:34:41 +0800</pubDate>
<dc:creator>Ricky</dc:creator>
<description><![CDATA[有时候可能因为交叉编译导致c jni有些头文件路径不对，修改对了以后再执行./gradlew :Tun2socks:assembleDebug即可]]></description>
<content:encoded xml:lang="zh-CN"><![CDATA[
<p>有时候可能因为交叉编译导致c jni有些头文件路径不对，修改对了以后再执行</p><pre><code>./gradlew :Tun2socks:assembleDebug</code></pre><p>即可</p>
]]></content:encoded>
<slash:comments>0</slash:comments>
<comments>https://dwt.life/archives/336/#comments</comments>
<wfw:commentRss>https://dwt.life/feed/</wfw:commentRss>
</item>
<item>
<title>MacOS 编译.net到linux平台</title>
<link>https://dwt.life/archives/335/</link>
<guid>https://dwt.life/archives/335/</guid>
<pubDate>Sun, 19 Nov 2023 20:32:20 +0800</pubDate>
<dc:creator>Ricky</dc:creator>
<description><![CDATA[dotnet publish --configuration Release  --os linux --arch x64]]></description>
<content:encoded xml:lang="zh-CN"><![CDATA[
<p><code>dotnet publish --configuration Release  --os linux --arch x64</code></p>
]]></content:encoded>
<slash:comments>0</slash:comments>
<comments>https://dwt.life/archives/335/#comments</comments>
<wfw:commentRss>https://dwt.life/feed/</wfw:commentRss>
</item>
<item>
<title>MacOS下的openresty编译过程</title>
<link>https://dwt.life/archives/334/</link>
<guid>https://dwt.life/archives/334/</guid>
<pubDate>Mon, 30 Oct 2023 22:56:49 +0800</pubDate>
<dc:creator>Ricky</dc:creator>
<description><![CDATA[其实还是比较简单的，毕竟homebrew已经很方便的安装了依赖，还是记录一下基本依赖我本地的brew是更新过了的，从github下载的最新releasebrew update          ...]]></description>
<content:encoded xml:lang="zh-CN"><![CDATA[
<p>其实还是比较简单的，毕竟<code>homebrew</code>已经很方便的安装了依赖，还是记录一下</p><h2>基本依赖</h2><p>我本地的brew是更新过了的，从github下载的最新release</p><pre><code>brew update                            
brew install pcre openssl</code></pre><h2>configure</h2><p>Linux:</p><pre><code>./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; \
   -j8</code></pre><p>MacOS:</p><pre><code>./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</code></pre><p>这里的路径是我自己找的，brew应该都一样，但是看到别的文章和我的不一样，所以应该先检查include和lib的路径</p><h2>brotli</h2><p>Brotli比我当年编译的简单多了:</p><pre><code>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</code></pre><p>然后make -j8 && make install 就到了<code>/usr/local/openresty</code>下了</p>
]]></content:encoded>
<slash:comments>1</slash:comments>
<comments>https://dwt.life/archives/334/#comments</comments>
<wfw:commentRss>https://dwt.life/feed/</wfw:commentRss>
</item>
<item>
<title>【转载】MySql 外键约束 之CASCADE、SET NULL、RESTRICT、NO ACTION分析和作用</title>
<link>https://dwt.life/archives/333/</link>
<guid>https://dwt.life/archives/333/</guid>
<pubDate>Tue, 20 Jun 2023 19:30:49 +0800</pubDate>
<dc:creator>Ricky</dc:creator>
<description><![CDATA[https://www.cnblogs.com/yzuzhang/p/5174720.htmlMySQL有两种常用的引擎类型：MyISAM和InnoDB。目前只有InnoDB引擎类型支持外键约束...]]></description>
<content:encoded xml:lang="zh-CN"><![CDATA[
<p><a href="https://www.cnblogs.com/yzuzhang/p/5174720.html">https://www.cnblogs.com/yzuzhang/p/5174720.html</a></p><p>MySQL有两种常用的引擎类型：MyISAM和InnoDB。目前只有InnoDB引擎类型支持外键约束。InnoDB中外键约束定义的语法如下：</p><pre><code>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]</code></pre><p>例如：</p><pre><code>ALTER TABLE `user_resource` CONSTRAINT `FKEEAF1E02D82D57F9` FOREIGN KEY (`user_Id`) REFERENCES `sys_user` (`Id`)</code></pre><p>InnoDB也支持使用ALTER TABLE来删除外键：</p><p>ALTER TABLE <code>user_resource</code> DROP FOREIGN KEY <code>FKEEAF1E02D82D57F9</code>;</p><p><em>CASCADE</em><br>在父表上update/delete记录时，同步update/delete掉子表的匹配记录 </p><p><em>SET NULL</em><br>在父表上update/delete记录时，将子表上匹配记录的列设为null (要注意子表的外键列不能为not null)  </p><p><em>NO ACTION</em><br>如果子表中有匹配的记录,则不允许对父表对应候选键进行update/delete操作  </p><p><em>RESTRICT</em><br>同no action, 都是立即检查外键约束</p><p><em>SET NULL</em><br>父表有变更时,子表将外键列设置成一个默认的值 但Innodb不能识别</p><p>NULL、RESTRICT、NO ACTION<br>删除：从表记录不存在时，主表才可以删除。删除从表，主表不变<br>更新：从表记录不存在时，主表才可以更新。更新从表，主表不变</p><p>CASCADE<br>删除：删除主表时自动删除从表。删除从表，主表不变<br>更新：更新主表时自动更新从表。更新从表，主表不变</p><p>SET NULL<br>删除：删除主表时自动更新从表值为NULL。删除从表，主表不变<br>更新：更新主表时自动更新从表值为NULL。更新从表，主表不变</p><p>外键约束属性： RESTRICT | CASCADE | SET NULL | NO ACTION  外键的使用需要满足下列的条件：</p><ol><li>两张表必须都是InnoDB表，并且它们没有临时表。</li><li>建立外键关系的对应列必须具有相似的InnoDB内部数据类型。</li><li>建立外键关系的对应列必须建立了索引。</li><li>假如显式的给出了CONSTRAINT symbol，那symbol在数据库中必须是唯一的。假如没有显式的给出，InnoDB会自动的创建。</li></ol><p>如果子表试图创建一个在父表中不存在的外键值，InnoDB会拒绝任何INSERT或UPDATE操作。如果父表试图UPDATE或者DELETE任何子 表中存在或匹配的外键值，最终动作取决于外键约束定义中的ON UPDATE和ON DELETE选项。InnoDB支持5种不同的动作，如果没有指定ON DELETE或者ON UPDATE，默认的动作为RESTRICT:</p><ol><li>CASCADE: 从父表中删除或更新对应的行，同时自动的删除或更新自表中匹配的行。ON DELETE CANSCADE和ON UPDATE CANSCADE都被InnoDB所支持。</li><li>SET NULL: 从父表中删除或更新对应的行，同时将子表中的外键列设为空。注意，这些在外键列没有被设为NOT NULL时才有效。ON DELETE SET NULL和ON UPDATE SET SET NULL都被InnoDB所支持。</li><li>NO ACTION: InnoDB拒绝删除或者更新父表。</li><li>RESTRICT: 拒绝删除或者更新父表。指定RESTRICT（或者NO ACTION）和忽略ON DELETE或者ON UPDATE选项的效果是一样的。</li><li>SET DEFAULT: InnoDB目前不支持。</li></ol><p>外键约束使用最多的两种情况无外乎：</p><p>1）父表更新时子表也更新，父表删除时如果子表有匹配的项，删除失败；</p><p>2）父表更新时子表也更新，父表删除时子表匹配的项也删除。</p><p>前一种情况，在外键定义中，我们使用ON UPDATE CASCADE ON DELETE RESTRICT；后一种情况，可以使用ON UPDATE CASCADE ON DELETE CASCADE。</p><p>当执行外键检查之时，InnoDB对它照看着的子或父记录设置共享的行级锁。InnoDB立即检查外键约束，检查不对事务提交延迟。</p><p>要使得对有外键关系的表重新载入转储文件变得更容易，mysqldump自动在转储输出中包括一个语句设置FOREIGN_KEY_CHECKS为0。这避免在转储被重新装载之时，与不得不被以特别顺序重新装载的表相关的问题。也可以手动设置这个变量：</p><pre><code>mysql&gt; SET FOREIGN_KEY_CHECKS = 0;

mysql&gt; SOURCE dump_file_name;

mysql&gt; SET FOREIGN_KEY_CHECKS = 1;</code></pre><p>　　如果转储文件包含对外键是不正确顺序的表，这就以任何顺序导入该表。这样也加快导入操作。设置FOREIGN_KEY_CHECKS为0，对于在LOAD DATA和ALTER TABLE操作中忽略外键限制也是非常有用的。</p><p>InnoDB不允许你删除一个被FOREIGN KEY表约束引用的表，除非你做设置SET FOREIGN_KEY_CHECKS=0。当你移除一个表的时候，在它的创建语句里定义的约束也被移除。</p><p>　　如果你重新创建一个被移除的表，它必须有一个遵从于也引用它的外键约束的定义。它必须有正确的列名和类型，并且如前所述，它必须对被引用的键有索引。如果这些不被满足，MySQL返回错误号1005 并在错误信息字符串中指向errno 150。</p>
]]></content:encoded>
<slash:comments>0</slash:comments>
<comments>https://dwt.life/archives/333/#comments</comments>
<wfw:commentRss>https://dwt.life/feed/</wfw:commentRss>
</item>
<item>
<title>巴欧教程正则</title>
<link>https://dwt.life/archives/332/</link>
<guid>https://dwt.life/archives/332/</guid>
<pubDate>Sun, 18 Jun 2023 22:13:54 +0800</pubDate>
<dc:creator>Ricky</dc:creator>
<description><![CDATA[|#&lt;a1&gt;(.?)#is&gt; &#8617;]]></description>
<content:encoded xml:lang="zh-CN"><![CDATA[
<p>|#&lt;a<sup id="fnref-1"><a href="#fn-1" class="footnote-ref">1</a></sup><em>&gt;(.</em>?)</a>#is</p><div class="footnotes"><hr><ol><li id="fn-1">&gt; <a href="#fnref-1" class="footnote-backref">&#8617;</a></li></ol></div>
]]></content:encoded>
<slash:comments>0</slash:comments>
<comments>https://dwt.life/archives/332/#comments</comments>
<wfw:commentRss>https://dwt.life/feed/</wfw:commentRss>
</item>
<item>
<title>nslookup指定端口</title>
<link>https://dwt.life/archives/330/</link>
<guid>https://dwt.life/archives/330/</guid>
<pubDate>Mon, 10 Apr 2023 17:26:00 +0800</pubDate>
<dc:creator>Ricky</dc:creator>
<description><![CDATA[dig google.com @192.168.0.1 -p 65053在线nslookup：https://tool.hi.cn/nslookup/]]></description>
<content:encoded xml:lang="zh-CN"><![CDATA[
<p><code>dig google.com @192.168.0.1 -p 65053</code></p><p>在线nslookup：<a href="https://tool.hi.cn/nslookup/">https://tool.hi.cn/nslookup/</a></p>
]]></content:encoded>
<slash:comments>0</slash:comments>
<comments>https://dwt.life/archives/330/#comments</comments>
<wfw:commentRss>https://dwt.life/feed/</wfw:commentRss>
</item>
</channel>
</rss>