Что нового

[Файловая система] Как обрезать файл?

ohos

Новичок
Сообщения
47
Репутация
0
Есть ли какой-то способ обрезать файл (в бинарном виде), кроме создания нового и копирования в него нужной части исходного?

p.s. при размере файла в 500 мегабайт и более копировать файл не так уж и быстро, а при наличии нескольких таких файлов...


решение

Код:
;test.xyz должен уже существовать, главное не забыть слеш в пути к файлу :)
$hFile = _WinAPI_CreateFile(@WorkingDir&'\test.xyz', 2, 4)
 _WinAPI_SetFilePointer($hFile, 1);обрежет до 1 байта
 _WinAPI_SetEndOfFile($hFile)
_WinAPI_CloseHandle($hFile)
 

kaster

Мой Аватар, он лучший самый
Команда форума
Глобальный модератор
Сообщения
4,020
Репутация
622
ohos
как определяется нужный участок файла? где он находится позиционно – начало, середина, конец? каков размер требуемой части файла?
 
Автор
O

ohos

Новичок
Сообщения
47
Репутация
0
Определяется известным заранее размером файла, а обрезать его нужно в конце. К примеру известно, что файл А должен быть 100 метров, а в ходе работы программы может оказаться, что файл А 120 метров, соответственно 20 метров с его конца нужно отрезать :smile:
 
Автор
O

ohos

Новичок
Сообщения
47
Репутация
0
посмотрел ссылку с Как разделить/соеденить файл?, как и ожидал - там предлагается создать новый файл и в него записать нужную часть исходного, это я и так могу сделать, а способа без создания нового файла нету?


Добавлено:
Сообщение автоматически объединено:

поискал реализацию задачи обрезания файла в других языках, сразу же первой ссылкой в гугле нашлось http://www.gamedev.ru/code/forum/?id=124123 , там описано, что файл можно обрезать записав в него блок данных нулевой длинны, а в автоите это возможно?
 

kaster

Мой Аватар, он лучший самый
Команда форума
Глобальный модератор
Сообщения
4,020
Репутация
622
лично мне, решение этой задачи кроме как "копирования нужной части в новый файл" не видится. в сети есть немало средство для выполнения такой операции. сравни скорость выполнения некоторых. если они все медленны для больших файлов, значит по другому никак. на вскидку, попробуй эту с говорящим названием FFSJ: The Fastest File Splitter and Joiner
вот оно как :smile: щас почитаю
 
Автор
O

ohos

Новичок
Сообщения
47
Репутация
0
а функция FileWrite нативная? я что-то не нашел её поиском по файлам в папке Include, просто я уже пробывал писать аля FileWrite($file,'') и FileWrite($file,0), но это не обрезало файл, боюсь что она не рассчитана на запись блока данных нулевой длинны :'(


Добавлено:
Сообщение автоматически объединено:

я уже пробывал писать аля FileWrite($file,'') и FileWrite($file,0)
файл открывал как в 17 моде, так и в 1


Добавлено:
Сообщение автоматически объединено:

если вдруг на автоите не получится, то можно же тогда подружить автоит с Win API функцией обрезания файла http://msdn.microsoft.com/en-us/library/aa365531%28VS.85%29.aspx ;D , в расширении к автоиту к сожалению нет этой Win API http://autoit-script.ru/index.php/topic,47.0.html :(
 

kaster

Мой Аватар, он лучший самый
Команда форума
Глобальный модератор
Сообщения
4,020
Репутация
622
да. нативная. тут либо писать на С, либо попросить человека знающего С написать библиотеку или скомпилировать исполняемый файл, который бы принимал в качестве аргументов путь до файла и размер обрезки, и потом уже вызывать его в AutoIt. С код выглядит довольно простым.
Код:
#include <stdio.h>
#include <fcntl.h>
int fh, result, size;
int main (int argc, char *argv[]){
    if (argc == 2){
        fh=open(argv[1], O_RDWR);
        size = atoi(argv[2]);
        result = chsize(fh, size)
        return result
     }
    else {
        cout << "Error, 2 arguments should be provided" << endl;
    }
}
 
Автор
O

ohos

Новичок
Сообщения
47
Репутация
0
SetEndOfFile я нашел в справке по автоиту, только там она называется _WinAPI_SetEndOfFile, оказывается там она и так была без дополнений, но дополнению отдельное спасибо, если б не оно, может и не наткнулся бы

сейчас посмотрю пример по _WinAPI_SetEndOfFile, может там и есть точный пример обрезания файла :rofl:

читаю справку и... :laugh:

Код:
; 4) truncate file size to 12 bytes
$hFile = _WinAPI_CreateFile($sFile, 2, 4)
_WinAPI_SetFilePointer($hFile, 12)
_WinAPI_SetEndOfFile($hFile)
_WinAPI_CloseHandle($hFile)
ConsoleWrite('4) ' & FileRead($sFile) & @CRLF)


:IL_AutoIt_1:
 

kaster

Мой Аватар, он лучший самый
Команда форума
Глобальный модератор
Сообщения
4,020
Репутация
622
OffTopic:
да, ох уж этот WinAPI :rofl:
столько функций. тут без справки от Yashied не обойтись
 
Автор
O

ohos

Новичок
Сообщения
47
Репутация
0
только вот, что-то он обрезать у меня не хочет, я еще раз конечно попробую, но что-то странно... :scratch:

Код:
;test.xyz уже существует, у меня в нем 8 байт, все функции возвращают успешный результат, но файл не обрезается...  
$hFile = _WinAPI_CreateFile(@WorkingDir&'test.xyz', 2, 4)
consolewrite('_WinAPI_CreateFile_'&$hFile&@lf)
$res = _WinAPI_SetFilePointer($hFile, 1)
consolewrite('_WinAPI_SetFilePointer_'&$res&@lf)
$res = _WinAPI_SetEndOfFile($hFile)
consolewrite('_WinAPI_SetEndOfFile_'&$res&@lf)
$res = _WinAPI_CloseHandle($hFile)
consolewrite('_WinAPI_CloseHandle_'&$res&@lf)


судя по форуму в июне 2010 это работало http://autoit-script.ru/index.php/topic,2019.msg14742.html#msg14742 :'(
 

kaster

Мой Аватар, он лучший самый
Команда форума
Глобальный модератор
Сообщения
4,020
Репутация
622
ohos
а где у тебя файл лежит? точно ли в WorkingDir? может в ScriptDir? и потом, макро от названия надо отделять слешом
Код:
$hFile = _WinAPI_CreateFile(@WorkingDir&'\test.xyz', 2, 4)
$hFile = _WinAPI_CreateFile(@ScriptDir&'\test.xyz', 2, 4)
 
Автор
O

ohos

Новичок
Сообщения
47
Репутация
0
точно, со слешем работает, но на что хендл без слеша он мне возвращал :shok:

Код:
;test.xyz должен уже существовать, главное не забыть слеш в пути к файлу :)
$hFile = _WinAPI_CreateFile(@WorkingDir&'\test.xyz', 2, 4)
 _WinAPI_SetFilePointer($hFile, 1)
 _WinAPI_SetEndOfFile($hFile)
_WinAPI_CloseHandle($hFile)


p.s. нашел на что был хэндл, он просто новый файл сделал :smile:, хотя это и странно, потому-что двойка в функции _WinAPI_CreateFile указывает на "не создавать файл, если он не существует", но это повод уже для другой темы
 
Верх