파일,하지만이 다소 고급 물건이기 때문에 나는 코드가 제공됩니다. 이제 os.walk()를 사용하여 재귀 적으로 원하는 디렉토리를 탐색하고 slicefile() 함수를 적용 할 수 있습니다.
이 코드는 다음 작업을 수행합니다
시작과 끝 인수의 유효성을 확인 후에는 열린 파일의 상단에 메모리 맵을 만듭니다. mmap()은 파일이 작성된 파일 시스템의 일부를 매핑하는 메모리 맵 객체를 만듭니다. 이 객체는 move()와 같은 몇 가지 추가 메서드를 사용하여 문자열 형 및 파일 형 인터페이스를 노출합니다. 따라서 메모리 맵을 문자열이나 파일로 취급하거나 size(), move(), resize() 또는 필요한 추가 메서드를 사용할 수 있습니다.
우리는 시작과 끝 사이의 거리를 계산합니다. 즉, 우리가 결국 얼마나 많은 바이트를 가질지를 계산합니다.
바이트의 스트림을 시작 위치에서부터 시작하여 0으로 이동합니다. 즉, 시작점으로 표시된 바이트 수만큼 뒤로 이동합니다.
나머지 파일은 폐기합니다. 나는. 우리는 그것을 바이트의 끝에서 시작 크기로 조정합니다. 그래서 남은 것은 새로운 문자열입니다.
파일 크기가 클수록 작업 시간이 길어집니다. 불행히도 그것에 대해 할 수있는 일은별로 없습니다. 파일이 크면 가장 좋은 방법입니다. 이 절차는 메모리를 너무 많이 차지하지 않도록 버퍼링해야한다는 점을 제외하고는 메모리 내 배열의 시작/중간에서 항목을 제거 할 때와 동일합니다.
파일이 사용 가능한 RAM 공간의 1/3보다 작은 경우 f.read()를 사용하여 문자열 전체에로드 한 다음로드 된 내용 (s = s [start : end]) 그리고 다시 열어 f.write (s)를 수행하여 파일에 다시 기록하십시오. 디스크 공간이 충분하면 다른 파일을 열고 원본 파일에서 원하는 시작 지점을 찾은 다음 청크로 읽고이를 새 파일에 쓸 수 있습니다. 아마도 shutil.copyfileobj()를 사용했을 수도 있습니다. 그런 다음 원본 파일을 제거하고 os.rename()을 사용하여 새 파일을 그 위치에 저장합니다. 이것들은 오직 3 가지 옵션입니다. 전체 파일을 RAM에 저장합니다. 뒤로 버퍼링하고 크기를 조정하여 이동하십시오. 다른 파일로 복사 한 다음 이름을 바꿉니다. 두 번째 옵션은 가장 보편적이며 작거나 큰 파일의 경우 실패하지 않습니다. 그러므로 나는 그것을 사용했다.
좋아요, 3 가지 옵션뿐입니다. 네 번째 옵션이 있습니다. 저수준 조작을 사용하여 파일 시스템 자체를 조작하여 파일의 시작 부분부터 N 개의 바이트 수를 줄일 수 있습니다. truncate() 함수의 일종을 작성하여 끝 대신 시작 부분을 자릅니다. 그러나 이것은 꽤 자살 할 것입니다. 결국 메모리 조각화가 발생하고 전체 엉망이 발생합니다. 당신은 어쨌든 그런 속도가 필요하지 않습니다. 스크립트 작성이 완료 될 때까지 기다릴 것입니다. : D
왜 mmap()을 사용 했습니까?
완전히 새로운 코드가 아닌 OS에서 구현 된 메모리 맵을 사용하기 때문에. 이렇게하면 열린 파일을 처리하는 데 필요한 시스템 호출 수가 줄어 듭니다. 작업량의 절반은 운영 체제에 집중되어 Python은 쉽게 숨을 쉴 수 있습니다.
대부분 C 언어로 작성 되었기 때문에 순수한 Python 구현보다 빠릅니다.
필요로하는 move()를 구현했기 때문에. 버퍼링 및 모든 것은 이미 작성되었으므로 대신 (수동) 솔루션이 될 부피가 큰 while 루프가 필요하지 않습니다.
등등
... 어떻게 지금까지 시도
from mmap import mmap
def slicefile (path, start=0, end=None):
f = open(path, "r+b") # Read and write binary
f.seek(0, 2)
size = f.tell()
start = 0 if start==None else start
end = size if end==None else end
start = size+start if start<0 else start
end = size+end if end<0 else end
end = size if end>size else end
if (end==size and start==0) or (end<=start):
f.close()
return
# If start is 0, no need to move anything, just cut off the rest after end
if start==0:
f.seek(end)
f.truncate()
f.close()
return
# Modify in place using mapped memory:
newsize = end-start
m = mmap(f.fileno(), 0)
m.move(0, start, newsize)
m.flush()
m.resize(newsize)
m.close()
f.close()
코드는 어디에 있습니까? + 파일의 데이터 샘플을 제공합니다. 질문이 너무 광범위합니다. – Yahya
파이썬에서이 파일을 시작할 수있는 실마리가 없습니다. 파일은 현재 16 진수에서만 볼 수 있습니다. 최대한 빨리 처음 4 바이트 정도를 제거하고 16 진수 편집기를 사용하여 끝에있는 몇 개를 제거하면 gzip 파일이 생깁니다. – JoeyD
파일 끝에서 바이트를 쉽게 제거 할 수 있지만 파일 시작 부분 (또는 중간 부분)에서 바이트를 제거 할 수는 없습니다. 다른 바이트로 대체하거나 보관하려는 바이트를 읽고 원래 파일 또는 새 파일에 다시 써야합니다. –