7-zip一个正在使用的文件

时间:2015-03-12 17:48:04

标签: batch-file 7zip

我们正在运行许多Apache Tomcat服务器。大部分日志翻转,因为它们应基于小时或当天结束。但是,仍有一些数字仍由Apache Tomcat或Web服务锁定。

实际上已将此记录为 - http://sourceforge.net/p/sevenzip/bugs/1488/

中的错误

已经看过dbenham的awesome post(注意:它是关于如何处理正在使用的文件的第二个“编辑”标题,对于我所指的)。但是,我仍然在使用正在使用的文件。我知道WinZip命令行可能是一个选项,但我真的不想使用它。

我们有一个夜间进程,其功能远不止于此,但为了说明我们将使用以下内容:

    FOR /r "C:\tomcat\logs" %%X IN (*) DO (
    7za a -y D:\17\%%~nxX.zip %%X
    )
    PAUSE

所以,我们看到的结果是一个数字或22字节的空zip文件。是的,我们知道不要压缩“正在使用”的文件,但如果它出现在目录列表中,我们会看到这个问题。

我们可以做些什么吗?

Volume in drive D is New Volume
Volume Serial Number is A476-BD38

Directory of D:\17

03/07/2015 02:05 PM <DIR> .
03/07/2015 02:05 PM <DIR> ..
03/07/2015 02:05 PM 403 catalina.2015-03-06.log.zip
03/07/2015 02:05 PM 22 catalina.2015-03-07.log.zip
03/07/2015 02:05 PM 22 host-manager.2015-02-23.log.zip
03/07/2015 02:05 PM 22 localhost.2015-02-23.log.zip
03/07/2015 02:05 PM 22 manager.2015-02-24.log.zip
03/07/2015 02:05 PM 22 probe.log.zip
6 File(s) 513 bytes
2 Dir(s) 51,783,634,944 bytes free

通常情况下,我不会真正关心22字节文件,但是我们必须看它们,因为它们每晚都会被发送给供应商进行报告处理。

查看我们如何使用它的脚本,我们有:

REM SET VARIABLES
FOR /f "tokens=2-4 delims=.:/ " %%a IN ("%date%") DO SET CurrentDate=%%c-%%a-%%b

SETLOCAL ENABLEDELAYEDEXPANSION
FOR /r "D:\17" %%X IN (*) DO (
    SET FileName=%%~nxX
    FOR /f "tokens=2-4 delims=.:/ " %%a IN ("%%~tX") DO SET FDate=%%c-%%a-%%b
    REM CHECK FOR UNLOCKED FILE
    REM https://stackoverflow.com/a/10520609/1333331
    2>nul (   >>"D:\17\!FileName!" (call )) && (
    REM DO STUFF HERE
    IF "%CurrentDate%" NEQ "!FDate!" (
        IF %%~zX GTR 0 (
            ECHO ARCHIVING "D:\logs\!FileName!" >>%logfile%
            7za.exe -tzip -y a "D:\Archive\some.zip" "D:\17\!FileName!" && DEL "D:\17\!FileName!"
        )
    )
    REM END OF UNLOCKED ZONE
    ) || (
    ECHO FILE IS LOCKED
    )
)
ENDLOCAL

谢谢!

3 个答案:

答案 0 :(得分:1)

我知道该线程很旧,但是最近我遇到了相同的问题,并通过使用7z.exe上的“ -sse”开关解决了该问题。如果正在使用文件,这将阻止创建一个空的存档。

答案 1 :(得分:0)

我已经能够弄清楚这个问题的主要部分。

我们遇到的问题是使用来自cygwin和Unxutils的Touch.exe。

如果您阅读了如何创建零字节文件,那么在搜索此文件时您将看到以下文章。

http://www.computerhope.com/issues/ch001314.htm#linux

结果,这让我觉得这正是我的问题..如果文件不存在或者Tomcat或其他Web服务正在使用它,触摸将创建一个零字节文件无论如何(注意:我确实认为我将前几天处理的文件移到工作文件夹并从那里存档)。结果,使用零字节文件,我们得到了22字节的“air-zip”文件。 DOH !!!

我们使用touch的原因是我们希望使用生成文件的日期对文件重新加时间戳,不一定是文件存档的日期,因为我们已经存档了大约600GB的Web日志数据。我们可以通过使用一个小的PowerShell脚本来解决这个问题,这样我们就可以消除生成错误文件的风险。是的,这可以使用VBScript来完成,但PowerShell我们不需要对脚本进行编码。

REM RE-DATE THE FILES
PowerShell -file D:\work\scripts\redate.ps1

并且重新定义PowerShell脚本的内容是(您的milage可能会有所不同,因为我们将日期变量作为文件名的一部分):

$1dir='D:\logs\Archives\SubLog'
$2dir='D:\logs\Archives\Tomcat'
$3dir='D:\logs\Archives'

if (Test-Path "$1dir\*.zip")
{
$files = Get-ChildItem $1dir *.zip
    foreach ($file in $files)
    {
        $filename = $file.name
        $fullname = $file.FullName
        $DT = $file.name.substring(0, 8)
        $mm = $file.name.substring(4, 2)
        $dd = $file.name.substring(6, 2)
        $yy = $file.name.substring(0, 4)
        $DTNew = [datetime]"$mm/$dd/$yy"
        (dir $fullname).lastwritetime = $DTNew
    }
}

if (Test-Path "$2dir\*.zip")
{
$files = Get-ChildItem $2dir *.zip
foreach ($file in $files)
{
        $filename = $file.name
        $fullname = $file.FullName
        $mm = $filename.Split("-")[2]
        $dd = $filename.Split("-")[3]
        $yy = $filename.Split("-")[4]
        $DateVar = [datetime]"$mm/$dd/$yy"
        (dir $fullname).lastwritetime = $DateVar
}
}

if (Test-Path "$3dir\*.zip")
{
$files = Get-ChildItem $3dir *.zip
foreach ($file in $files)
{
        $filename = $file.name
        $fullname = $file.FullName
        $yy = $filename.Split("-")[1]
        $mm = $filename.Split("-")[2]
        $dd = $filename.Split("-")[3]
        $DateVar = [datetime]"$mm/$dd/$yy"
        (dir $fullname).lastwritetime = $DateVar
}
}

答案 2 :(得分:0)

对于最近的项目,我不得不处理类似的问题,并选择首先使用robocopy克隆源目录,以便避免使用中的文件问题。 Robocopy提供/ z,/ b和/ zb模式,分别复制可重启,备份和备份+可重启模式下的文件。使用/ zb可以将使用中的文件复制到您选择的目标目录中。我还会在robocopy调用中添加“ / r:1 / w:1”,以提高在文件阻塞或空间不足时的性能(/ r:1 =仅重试一次,/ w:1 =仅等待一秒钟重试)。安全胜过遗憾。

这将在复制日志时占用更多空间,但可以为您节省一些使用中的文件的麻烦。将原始代码更改为以下代码将得到您想要的结果(并在压缩后删除文件副本):

robocopy "c:\tomcat\logs" "c:\temp\tomcat\logs" /zb /s /e /mir /r:1 /w:1
FOR /r "C:\temp\tomcat\logs" %%X IN (*) DO (
    7za a -sdel -y D:\17\%%~nxX.zip %%X
)
robocopy "C:\temp\tomcat\logs" "C:\temp\tomcat\logs" /s /move

第一行将logs文件夹复制到temp。 7za更改(-sdel)在压缩时删除temp文件夹中的日志。 最后一行从临时日志文件夹中删除所有空的子目录。

如果您不介意使用多余的空间,而不是每次使用额外的CPU + RAM +时间,则可以在temp文件夹中保留永久缓存,并使用以下方法仅覆盖较新的文件:

robocopy "c:\tomcat\logs" "c:\temp\tomcat\logs" /zb /s /e /mir /r:1 /w:1
FOR /r "C:\temp\tomcat\logs" %%X IN (*) DO (
    7za a -y D:\17\%%~nxX.zip %%X
)