파일을 더 많은 파일로 분할한다는 것은 반드시 전체 콘텐츠의 일부/전체가 원래 위치에 있지 않음을 의미합니까?

파일을 더 많은 파일로 분할한다는 것은 반드시 전체 콘텐츠의 일부/전체가 원래 위치에 있지 않음을 의미합니까?

나는 특정 크기의 파일이 주어지면 모든 바이트가 디스크에서 연속되지는 않을 것이라고 추측합니다. (또는 그럴까요? "디스크 조각 모음"이라는 문구가 존재하기 때문에 그럴 것이라고 생각하지 않습니다). 그러나 적어도 애플리케이션 관점에서는 그렇습니다. 즉, head -c [-]n+를 사용하여 tail -c [-]n파일의 일부를 추출하여 연속된 바이트 시퀀스로 처리할 수 있습니다.

파일 길이가 10바이트이고 모두 동일한 바이트를 포함한다고 가정합니다.

$ cat someFile
AAAAAAAAAA

someFile.part1이렇게 2개의 파일로 나눌 수 있나요 someFile.part2?

$ cat someFile.part1
AAAAA
$ cat someFile.part2
AAAAA

실제로 어떤 바이트도 어디로도 이동되지 않았습니다. 즉, 해당 10바이트가 여전히 이전 위치에 그대로 있다는 의미입니까?

결국 이름은 someFile콘텐츠가 실제로 시작되는 물리적 위치(디스크 또는 OS(또는 커널?)가 처리할 수 있는 일종의 가상 메모리)에 어떻게든 매핑되어야 합니다. 어떤 면에서는 / someFile와 같은 포인터와 길이에는 큰 차이가 없다고 생각합니다 . 반면 대상 파일은 / 및 / 입니다 . 아마도 나는 C++ 경험과 실제로 존재하지 않는 파일 시스템에 대한 경험에 영향을 받았을 것입니다. :D0xabc100xabc50xac15


나는 그 일 자체에는 관심이 없습니다. 프로그램이 어떻게 작동하는지 궁금합니다.lxsplit직업과 그들의 강점은 무엇인지. 주로 호기심에서 비롯된 것이지만 어쩌면 직접 작성해 보는 것도 좋습니다.

답변1

일반적으로 파일을 분할하면 항상 파일 내용이 복사됩니다. 내가 아는 한, Linux는 파일 분할을 위한 다른 메커니즘을 제공하지 않습니다.

이것이 거의 모든 이야기입니다. 그러나 완전하지는 않습니다...

Linux는 파일 시스템 드라이버를 사용하여 디스크에 있는 파일을 관리합니다. 디스크에 기록된 파일 시스템은 때때로 다른 프로그램에 의해 조작될 수 있습니다.대개파일 시스템은 Linux에서 마운트되지 않습니다. 예를 들어디버그 파일ext2/ext3/ext4의 경우

그러나 프로그램이 파일 시스템 자체의 바이트에서 작동하는 경우 수행할 수 있는 작업에는 엄격한 제한이 있습니다.

배경

대부분의(모두?) 파일 시스템에서 파일 및 디렉터리 이름은 파일 데이터와 별도로 저장됩니다. 파일 소유권 및 타임스탬프와 같은 메타데이터는 종종 "Inode"라고 불리는 별도의 위치에 저장될 수도 있습니다.

이를 통해 동일한 파일에 두 개의 파일 이름을 추가할 수 있습니다(하드 링크라고도 함).


파일 데이터는 블록에 저장됩니다. ext4의 기본 블록 크기는 4KiB(4096바이트)입니다.. 일반적으로 1바이트만 저장하려면 전체 블록이 필요하지만, 블록이 가득 찰 때까지 "무료"로 더 많은 바이트를 파일에 저장할 수 있습니다.

첫 번째 블록이 가득 차서 더 많은 바이트를 써야 하면 파일 시스템은 새(사용 가능한) 블록을 찾아야 합니다. 그 다음에:

  • 다른 파일이 이를 사용하려고 시도하지 않도록 새 블록을 사용할 수 없는 것으로 표시합니다.
  • 파일에 블록의 위치를 ​​기록합니다.

파일 시스템마다 이 두 가지에 대한 기술이 다르지만 요구 사항은 항상 동일합니다. 파일 시스템 드라이버는 새 블록이 파일의 이전 블록 바로 뒤에 오도록 최선을 다하지만 이것이 보장되지는 않습니다. 조각화는 다음 블록이 다른 파일에 할당될 때 발생합니다.

파일은 언제 일부 블록을 조용히 공유할 수 있나요?

일부 파일 시스템과 일부 블록 수준 스토리지에는 중복 제거를 수행하는 기능이 있습니다. 한 블록에 기록된 정확한 내용이 다른 블록의 정확한 내용과 일치하는 경우 하나의 블록만 보존될 수 있습니다. 때로는 이는 중복 항목이 기록되지 않는다는 것을 의미하기도 하고, 때로는 소급하여 제거된다는 의미이기도 합니다.

~처럼마커스 뮐러는 지적했다.일부 파일 시스템은 중복 제거를 수행할 수 있습니다.

그것은 또한LVM의 특징이는 파일 시스템에 대한 지식 외부의 블록 수준에서 발생합니다.

하드 제한

가정적으로, 새 inode를 생성하고 해당 inode에 파일 이름을 추가한 다음 한 inode에서 다른 inode로 블록을 재할당하여 파일 시스템을 작동할 수 있습니다.

다시 말하지만, Linux에는 이 메커니즘이 없지만 방법을 알고 있다면 하드 드라이브의 실제 바이트를 사용하여 이 작업을 수행하는 데 아무런 방해가 없습니다.

바이트를 이동하지 않고 어디에서나 파일을 분할하는 것은 [일반적으로] 불가능합니다. 블록 크기는 협상할 수 없습니다. 대부분의 파일 시스템에서는 파일 중간에 절반만 사용된 블록이 있을 수 없습니다.

이는 귀하의 예에서 10바이트가 4096의 배수 또는 기타 일반적인 블록 크기가 아니기 때문에 새 블록이 (거의) 확실히 기록된다는 것을 의미합니다.

그러나 파일 시스템마다 기능이 다릅니다. 예를 들어 BTRFS는 테일 패킹을 지원합니다.

답변2

일반적으로 아니요 - 불가능합니다. 파일 시스템(매우 특수한 반례 제외)은 파일이 데이터 블록과 메타데이터로 구성되는 블록 지향 스토리지 시스템(디스크, SSD, NVME...)용으로 설계되었습니다. 메타데이터에는 권한, ACL 등이 포함되지만 특히 파일 길이와 정렬된 파일 블록 목록이 포함됩니다. 좀 더 발전된 파일 구성이 있지만 모두 데이터 블록의 길이와 정렬된 목록으로 구문 분석할 수 있습니다.

표시된 예에서 somefile은 잘림을 통해 somefile.part1로 변환될 수 있습니다. 자르기에는 파일 길이 메타데이터를 변경하고 차단 목록에서 더 이상 필요하지 않은 블록을 할당 취소하는 작업이 포함됩니다. 이 작업은 모든 사본에서 수행할 수 있습니다. somefile.part2를 만드는 것이 어렵습니다. 예에서 문자 5 - 10 "AAAAA"는 블록의 시작 부분에 있지 않으므로(블록의 크기는 2바이트의 거듭제곱, 일반적으로 512B 또는 4096B) 다음 위치로 복사되지 않는 한 파일의 첫 번째 부분이 될 수 없습니다. 블록의 시작.

블록 경계에서 파일 데이터를 분할하려는 경우에도 커널 파일 시스템 코드는 이러한 기능을 사용자 공간에 노출하지 않으므로 커널 파일 시스템을 수정해야 합니다.

관련 정보