2008-09-19 3 views
14

다운로드 응용 프로그램을 만드는 중이고 실제로 다운로드하기 전에 하드 드라이브에 공간을 미리 할당하고 싶습니다. 잠재적으로 크기가 클 수 있으며 아무도 "이 드라이브가 꽉 찼습니다. 일부 파일을 삭제하고 다시." 그래서 그 빛 속에서 저는 이것을 썼습니다.C#에서 파일 공간을 미리 할당 하시겠습니까?

// Quick, and very dirty 
System.IO.File.WriteAllBytes(filename, new byte[f.Length]); 

그것은 당신이 수백 MB의, 또는 잠재적으로 GB의있는 파일을 다운로드하고 완전히 페이지 파일을 닦은 모두 당신의 시스템 메모리를 죽이지 경우는 탈곡 열풍에 윈도우를 던져이어야 할 때까지 작동합니다. 죄송합니다.

그래서 조금 더 깨달음을 가지고 다음 알고리즘을 설명했습니다.

using (FileStream outFile = System.IO.File.Create(filename)) 
{ 
    // 4194304 = 4MB; loops from 1 block in so that we leave the loop one 
    // block short 
    byte[] buff = new byte[4194304]; 
    for (int i = buff.Length; i < f.Length; i += buff.Length) 
    { 
     outFile.Write(buff, 0, buff.Length); 
    } 
    outFile.Write(buff, 0, f.Length % buff.Length); 
} 

이 방법은 잘 작동하며 마지막 해결 방법의 메모리 문제가 심각하지 않습니다. 여전히 느리지 만 특히 오래된 하드웨어에서는 (잠재적으로 GB의 가치가있는) 데이터를 디스크에 기록하기 때문에 더욱 그렇습니다.

질문은 이것입니다 : 동일한 것을 성취하는 더 좋은 방법이 있습니까? Windows에 x 크기의 파일을 만들고 실제로는 많은 양의 데이터를 쓰는 대신 파일 시스템에 공간을 할당하는 방법이 있습니까? 나는 파일에서 데이터를 초기화하는 것에 신경 쓰지 않는다. (내가 사용하고있는 프로토콜 - bittorrent - 보내는 파일에 해시를 제공한다. 따라서 무작위 초기화되지 않은 데이터에 대해 최악의 경우는 행운의 우연과 파일의 일부를 얻는다. 맞다). 파일을 작성해야하는 경우

답변

23

FileStream.SetLength은 원하는 것입니다. 구문 :

public override void SetLength(
    long value 
) 
+1

예, 내 솔루션보다 쉽습니다. :-) – Mark

5

, 나는 당신이 아마 같은 것을 할 수 있다고 생각 :

using (FileStream outFile = System.IO.File.Create(filename)) 
{ 
    outFile.Seek(<length_to_write>-1, SeekOrigin.Begin); 
    OutFile.WriteByte(0); 
} 

하는 length_to_write가 작성하는 파일의 크기 (바이트) 될 경우. C#의 구문이 올바른지 (테스트 할 컴퓨터가 아님) 확신 할 수는 없지만 C++에서 이와 비슷한 일을 해왔습니다.

+0

거의 작동합니다. 바이트 하나를 적게 쓰면됩니다. 그렇지 않으면 0B 파일로 끝납니다. 아직도 도움이된다. 고마워! 구문도 수정하십시오. 편집을 원한다면 필요한 추가 행은 OutFile.WriteByte (0)입니다. –

+0

이전 의견 당 고정 – Mark

1

불행히도, 당신은 실제로 끝까지 추구하여 이것을 할 수 없습니다. 그것은 파일 길이를 커다란 값으로 설정하지만 실제로는 디스크 블록을 저장 영역에 할당하지 않을 수도 있습니다. 그래서 파일을 쓰려고 할 때, 여전히 실패 할 것입니다.

관련 문제