inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

Windows 시스템 프로그래밍 - 기본

파일 매핑 객체와 memcpy를 활용한 파일 복사 중, 왜 READ와 WRITE가 동시에 필요한가요?

해결된 질문

463

곽도훈

작성한 질문수 1

0

안녕하십니까, 윈도우 시스템 프로그래밍 강의 듣고 있는 학생입니다. 메모리 맵 강의에서 소개해주신 숙제를 수행하던 중에 접근 모드를 설정하는 부분에 사소한 의문이 있어서 질문드립니다.

작성한 코드의 흐름은 대략 다음과 같습니다.

  1. CreateFile()

    src파일과 dst파일의 핸들을 획득.

  2. GetFileSizeEx()

    src파일의 크기를 획득

  3. SetFilePointer()

    dst파일의 크기를 설정, 2번의 값을 활용

  4. CreateFileMapping()

    각 파일의 매핑 객체 생성

  5. MapViewOfFile()

    각 파일 매핑 객체에 대한 포인터를 획득

  6. memcpy()

    각 파일에 대한 매핑 객체의 포인터와 파일의 크기로 파일의 복사

첫 시도에서 다음과 같이 1번과 4번을 수행했습니다.

<실패>

// 1번. dst 파일 생성 
	HANDLE hDst = CreateFile(
		TEXT("복사 대상 파일의 절대 경로"),
		GENERIC_WRITE,	
		0,
		NULL,
		CREATE_ALWAYS,
		FILE_ATTRIBUTE_NORMAL,
		NULL
	);
HANDLE hDstMap = 
CreateFileMapping(hDst, NULL, PAGE_WRITECOPY, 0, llFileSize.LowPart, NULL);
	if (hDstMap == NULL)
	{
		wprintf(L"Failed to create Dst file mapping obj [ERROR CODE: %d]\n",
			::GetLastError());

		CloseHandle(hSrcMap);
		CloseHandle(hSrc);
		CloseHandle(hDst);
		return 0;
	}

수행 결과, Dst파일에 대한 맵뷰 객체를 생성하는데 실패했고, ERROR_ACCESS_DENIED에러 코드를 받았습니다.

MSDN에서 CreateFileMapping()에 대해서 찾아본 결과, PAGE_WRITECOPY플래그가 PAGE_READONLY와 동일하다는 점을 확인하고 다음과 같이 수정하여 실행에 성공했습니다.

<성공>

HANDLE hDst = CreateFile(
		TEXT("복사 대상 파일의 절대 경로"),
		GENERIC_WRITE | GENERIC_READ,	// 왜 GENERIC_WRITE만 설정하면 ERROR_ACCESS_DENIED인가요?
		0,
		NULL,
		CREATE_ALWAYS,
		FILE_ATTRIBUTE_NORMAL,
		NULL
	);
HANDLE hDstMap 
= CreateFileMapping(hDst, NULL, PAGE_READWRITE, 0, llFileSize.LowPart, NULL);
	if (hDstMap == NULL)
	{
		wprintf(L"Failed to create Dst file mapping obj [ERROR CODE: %d]\n",
			::GetLastError());

		CloseHandle(hSrcMap);
		CloseHandle(hSrc);
		CloseHandle(hDst);
		return 0;
	}

MSDN에서 문제를 해결했지만, dst 파일에는 복사한 내용을 써넣기만 하는데 왜 dst파일에 대한 READ가 필요한지 의문이 들어서 이에 질문드립니다. 긴 글 읽어주셔서 감사드립니다.

c system-programming vc++

답변 1

0

널널한 개발자

MapViewOfFile() 함수 호출 시 적용된 FILE_MAP_WRITE는 Read/Write 접근 권한을 모두 요구하기 때문입니다. 정확한 것은 알 수 없지만 어느 정도 추측은 할 수 있습니다. 파일에 쓰기 매핑을 하기 위해서 대상 파일에 대한 사전 읽기 접근이 내부적으로 필요하기 때문일 것으로 보입니다.

MapViewOfFile()함수가 포인터를 반환해주기 때문에 2차 메모리에 해당하는 파일을 1차 메모리 처럼 쓸 수 있습니다. 이 과정에서 대상 파일에 대한 정보를 가져오려면 대상에 대한 기본 정보를 읽는 것은 어쩔 수 없이 수반된다 하겠습니다. 참고하시기 바랍니다.

1

곽도훈

답변 감사합니다. 좋은 하루 되시기 바랍니다!

세마포어 개수에 따른 스레드 점유상태

0

61

2

메모리 맵과 비동기 입/출력 조합 #2 수업내용에 질문있습니다.

0

96

2

힙 메모리 블럭 관리 방법 질문

0

97

2

MapViewOfFile 원리 관련 질문있습니다

0

102

1

가상 메모리 시스템 영역 구분

0

96

2

스택 크기 결정 단계

0

75

2

시스템프로그래밍-응용편

0

130

2

바이트와 관련된 유튜브 영상을 못 찾겠어요ㅠㅠ

0

94

2

파일 복사에 관한 질문입니다

0

114

2

세마포어 예제에 대한 질문이 있습니다.

0

111

2

메모장 쓰레기값 ?

0

133

2

64 bit 운영체제라면 가상메모리가

0

180

2

alertable Wait 상태 질문있습니다

0

226

1

GetCurrentDirectory 관련 질문

0

169

2

세마포어 예제중 형변환에 대한 질문

0

162

2

강사님 dll 지연로딩 관련하여 질문 드립니다

0

205

3

선장님 , _beginThreadEx() 함수 원리는 어디서 정보를 얻을 수 있을까요?

0

286

2

메모리 맵 강의 예제의 결과가 이상합니다.

0

227

1

강사님 파일입출력(Callback함수)와 관련하여 질문 드립니다.

0

348

2

dll 명시적 링크 오류 (원인 및 해결 방법이 필요 합니다)

0

968

2

static 영역의 rw 가능한 곳은 어떤 데이터가 담기는지 궁금합니다.

0

223

1

TerminanteProcess 와 관련하여 질문 드립니다.

0

172

1

강사님 스레드 관련 질문 드립니다.

0

226

1

강사님 메뉴얼 중 이것도 궁금해서 여쭤봅니다.

0

210

2