找回密码
 加入
搜索
查看: 7965|回复: 14

[效率算法] 一个任意文件,如何快速删除前三个字节然后保存。【已解决】

 火.. [复制链接]
发表于 2012-11-19 17:27:34 | 显示全部楼层 |阅读模式
本帖最后由 sanmoking 于 2012-11-27 09:53 编辑

除了用fileopen,fileread,filewrite。还有其他什么快速的方法么?
各位网友请原谅我孤陋寡闻,谢谢。

我现在用的这个:

$x = FileOpen("1111.doc",16)
$y = FileRead ($x)
FileClose($x)

$x = FileOpen("1111-1.doc",26)
FileWrite($x,BinaryMid($y,4))
FileClose($x)

发表于 2012-11-19 18:01:59 | 显示全部楼层
fileflush
filesetpos
 楼主| 发表于 2012-11-22 21:33:55 | 显示全部楼层
fileflush
filesetpos
netegg 发表于 2012-11-19 18:01



    看了一下帮助文件里面这两个函数,感觉不是我想要的,我的意思是,我要把很多个文件的前面三个字节如果是指定的数据的话就删掉。用来解决某个程序生成的文件因为前面多了三个多余字节造成文件无法打开的问题。
发表于 2012-11-22 21:39:11 | 显示全部楼层
$hfile = fileread($txt, 2)
filesetpos($hfile, 3)
filewrite($txt1, fileread($hfile))
不知道行不行
 楼主| 发表于 2012-11-22 21:48:10 | 显示全部楼层
回复 5# netegg


    需要二进制读取。因为不是txt文件。
发表于 2012-11-22 21:53:37 | 显示全部楼层
本帖最后由 ppzpph 于 2012-11-22 21:55 编辑

期待高手支招高速的方法
发表于 2012-11-22 23:06:40 | 显示全部楼层
本帖最后由 netegg 于 2012-11-22 23:12 编辑

回复 6# sanmoking
那就open,16
对了,还必须用2进制,setpos是好像是字节位移动,不是字符位
 楼主| 发表于 2012-11-22 23:26:17 | 显示全部楼层
回复 8# netegg


    试了setpos,没有成功,实际这个函数我自己也是一知半解的,目前来说还是我一楼写的那个有效。
发表于 2012-11-22 23:37:12 | 显示全部楼层
传个二进制文本上来,试试看
发表于 2012-11-22 23:37:15 | 显示全部楼层
传个二进制文本上来,试试看
 楼主| 发表于 2012-11-23 15:08:30 | 显示全部楼层
本帖最后由 sanmoking 于 2012-11-23 15:11 编辑

回复 11# netegg



上面的文件是我直接用word保存了个doc文件,然后用winhex在整个文件前面加了三个字节[0x0B0B0B],我说的那种文件就是这种效果,文件前面有多余的三个字节。

我需要au3自动检测文档的二进制最前面三个字节是不是【0B0B0B】,如果是就删掉这三个字节并保存成新的文件。
因为太多这种文件,所以不能手动来弄。

Local Const $sFile = "1111.doc"
FileCopy("0.doc",$sFile,1)
$hFile = FileOpen($sFile,16)
$tFile = FileRead ($hFile)
FileClose($hFile)
If BinaryMid($tFile,1,3) = Binary("0x0B0B0B") Then

$hFile = FileOpen($sFile,26)
FileWrite($hFile,BinaryMid($tFile,4))
FileClose($hFile)
MsgBox(0,0,"已修复。")
Else
MsgBox(0,0,"没有发现特征符。")
EndIf

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?加入

×
发表于 2012-11-27 03:21:04 | 显示全部楼层
本帖最后由 edisonx 于 2012-11-27 03:25 编辑

回复 8# netegg


回复 12# sanmoking


我講個結論吧。

目前檔案系統裡,任何檔案之讀寫,均沒有快速的算法、作法能進行刪除(delete)或插入(insert)前面幾個 bytes,但可以做修改其中幾個 bytes, fsetpos 也只能做到先定位 byte,再去修改。

以樓主 sanmoking 所提之情況而言,若偵測到前 3 bytes 為 0x0b0b0b,必須把後面所有的數值再往前挪 3 bytes 即可。
聽出盲點了嗎?這作法是要同時 Read / Write 進行,這在其它部份程式語言辦得到,但 AU3 裡之 FileOpen flag 設得不好



0 = Read mode (default)
  1 = Write mode (append to end of file)

16 = Force binary mode (See Remarks).




Flag 不能設 0+1+16,這和 1+16 是同義,故不支援同時做 Read / Write。


樓主使用的 code 在 AutoIt 來講已算是不錯之解決了,當然相信多了一份 0.doc 是做備份用的,那行拿掉的話速度會更快。


AutoIt 確實不易快,硬要快的話也只剩調用 API 一路,下面參考就好。


[0] 取得檔案大小 : 有內建


FileGetSize


或是要用 Win32 API : GetFileSize 也行,只是比較麻煩。
_WinAPI_GetFileSizeEx 這個是適合下面各 API 配合使用的。


[1] 記憶體(memory,內存)配置 與 釋放 : 無內建


HeapAllocate
HeapFree


[2] 開關檔 : 有內建


_WinAPI_CreateFile
_WinAPI_CloseHandle


_WinAPI_CreateFile 要講一下,MSDN裡可看到,dwDesiredAccess 可以設成 (GENERIC_READ | GENERIC_WRITE). ,也就是可以同時讀寫 (但別忘了上面說的限制,不可以插入或刪除,只可以修改)。


[3] 定位 : 有內建


_WinAPI_SetFilePointer

-------------------

ok,這些是低階上的操作,但以您的例子而言可能不適用,為何?假定原本之內容為 "0b 0b 0b 01 02 03 04",原地讀寫後會變成 "01 02 03 04 02 03 04" ,最後的那 3 bytes 是完全沒辦法蓋掉的,也就是說沒辦法在已存在之文件,直接將其縮小、刪除某些 bytes。

-------------------


最後結論是,為結省開發時間,就用您原本的作法吧。

希望我的回覆能幫助到您
                  by EdisonX
发表于 2012-11-27 03:53:18 | 显示全部楼层
本帖最后由 netegg 于 2012-11-27 05:00 编辑

[au3]#include <Constants.au3>

Local Const $sFile = "1.txt"
Local $hFile = FileOpen($sFile, 1)
FileSetPos($hFile, 3, $FILE_BEGIN)
$res = FileRead($hFile)
$hFile = FileOpen($sFile, 2)
FileWrite($hFile, $res)
;FileSetPos($hFile, 0, $FILE_BEGIN)
;MsgBox(4096, "", FileRead($hFile))
FileClose($hFile)

[/au3]
帮助里的例子改了改,不过执行你那个文件提示内存溢出了
 楼主| 发表于 2012-11-27 09:52:27 | 显示全部楼层
多谢各位回复,长见识不少。
发表于 2012-12-19 12:58:08 | 显示全部楼层
回复 12# edisonx
学习了,高人,看来是专业人士啊!
您需要登录后才可以回帖 登录 | 加入

本版积分规则

QQ|手机版|小黑屋|AUTOIT CN ( 鲁ICP备19019924号-1 )谷歌 百度

GMT+8, 2024-11-21 20:25 , Processed in 0.084068 second(s), 24 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表