2014-11-18 3 views
1

WCE 앱에서 파일 이름 (특정 파일의 이름/경로) 만 특정 메모리 주소로 복사 할 수있는 방법을 찾고 있습니다. Copy data from from IntPtr to IntPtr파일의 메모리 주소를 얻는 방법

[DllImport("kernel32.dll", EntryPoint = "CopyMemory", SetLastError = false)] 
public static extern void CopyMemory(IntPtr dest, IntPtr src, uint count); 
static void Main() 
{ 
    const int size = 200; 
    IntPtr memorySource = Marshal.AllocHGlobal(size); 
    IntPtr memoryTarget = Marshal.AllocHGlobal(size); 
    CopyMemory(memoryTarget,memorySource,size); 
} 

: 파일은 제한된 자원으로, I 메모리 (바이트 배열)에 전체 파일을 읽는 피하기 위해 기대했다 그래서,이 게시물에서 답을 사용하여, large'ish ~ 40메가바이트 오히려입니다 그로 인해 2 가지 문제가 생깁니다. 우선 : 어떻게 메모리 주소를 IntPtr에 할당합니까?, 종류 : int* startAddr = &0x00180000

둘째로 : 파일의 메모리 주소는 어떻게 얻을 수 있습니까? 즉 그것에 대해가는 유효한 방법이 될 것인가

[DllImport("kernel32.dll", EntryPoint = "CopyMemory", SetLastError = false)] 
public static extern void CopyMemory(IntPtr dest, IntPtr src, uint count); 
private unsafe void CopyFile() 
{ 
    try 
    { 
     fixed (Int32* startAddr = /*0x00180000*/) 
     { 
      fixed(Int32* fileAddr = /*Memory Address of file*/) 
      { 
       CopyMemory(new IntPtr(startAddr), new IntPtr(fileAddr), (uint)new FileInfo("File name").Length); 
      } 
     } 
    } 
    catch { } 
} 

:이 두 질문

내 코드가 같이 보일 것이다 대답?

도움을 주시면 감사하겠습니다. 미리 감사드립니다 !!

업데이트 : CopyMemory는 그 방법이 아닙니다. 그러니 무시하십시오.

또한 죄송합니다. 기본적으로 디스크의 파티션 시작 부분으로 파일을 옮기고 싶습니다. IntPtr이 디스크 주소를 가리킬 수도 있다고 생각했지만 회상에서 볼 수있는 것은 물론 볼 수 없습니다. 어쨌든 혼란을 드려 죄송합니다.

+0

당신은 단순히에게 주소를 할당 할 IntPtr''의의 ctor를 사용할 수'새를 IntPtr을 (0x00180000)', 두 번째 부분 들어, 파일에는로드 할 때까지 메모리 주소가 없습니다. RAM에있는 것이 아니라 디스크에 있습니다. – aevitas

+0

@aevitas 물론. 고마워. 당신이 옳습니다. CopyMemory가 최선의 방법이 아닐 수도 있습니다. – Viking

답변

1

파일에는 메모리에 주소가 없습니다. 그래서 당신이 요구하는 것은 비 sequitur의 무언가입니다.

내가 알 수있는 한, 안전하지 않은 코드는 전혀 필요하지 않습니다. CopyMemory으로 전화 할 필요가 없습니다. 그리고 한 번에 전체 파일을로드 한 다음 복사 할 필요가 없습니다. 수행 할 수있는 작업은 다음과 같습니다.

  1. 표준 파일 스트림을 사용하여 파일을 읽습니다.
  2. 파일을 작은 청크로 작은 버퍼에 읽습니다. 그냥 구체적으로 말하자면, 8KB 청크로 파일을 읽을 수 있습니다.
  3. 파일의 청크를 읽을 때마다 Marshal.Copy을 호출하여 관리되지 않는 메모리 위치로 복사하십시오.

코드는 다음과 같습니다

static void CopyStreamToMemory(Stream stream, IntPtr addr, int bufferSize) 
{ 
    byte[] buffer = new byte[bufferSize]; 
    long bytesLeft = stream.Length - stream.Position; 
    while (bytesLeft > 0) 
    { 
     int bytesToCopy = (int)Math.Min(bufferSize, bytesLeft); 
     stream.Read(buffer, 0, bytesToCopy); 
     Marshal.Copy(buffer, 0, addr, bytesToCopy); 
     addr += bytesToCopy; 
     bytesLeft -= bytesToCopy; 
    } 
} 
+0

그 일을하는 좋은 간단한 방법이 될 것입니다. 그걸 생각하지 않았습니까? 나는 그것에게 시도를 줄 것이고, 나는 내가 생각해 낼 것 인 것을 게시한다. 고마워. – Viking

+0

BTW, 그래서 당신이 말하는 것은 IntPtr이 RAM 메모리만을 가리킬 수 있다는 것입니다. 그래서 '새로운 IntPtr (0x00180000)'는 주소 0x00180000에있는 디스크에 대한 포인터를 제공하지 않습니까? – Viking

+0

맞습니다. 포인터는 메모리를 나타냅니다. 파일은 메모리에 매핑 될 수 있지만 다소 복잡한 작업입니다.그리고 네가 여기서 필요로하는 것은 내가 믿는다. –

관련 문제