압축율 : 7z > zip >> lz4

압축속도 : lz4 >> zip >> 7z

압축해제속도 : lz4 >> zip > 7z

 

zip : 일반적으로 무난한 용도

7z(LZMA) : 네트워크로 전송해야 하는 파일

lz4(lz4hc) : 빠른 압축과 해제가 필요한 경우 (멀티코어 활용)

 

참고 링크 : catchchallenger.first-world.info/wiki/Quick_Benchmark:_Gzip_vs_Bzip2_vs_LZMA_vs_XZ_vs_LZ4_vs_LZO

 

 

stackoverflow.com/questions/222030/how-do-i-create-7-zip-archives-with-net

 

How do I create 7-Zip archives with .NET?

How can I create 7-Zip archives from my C# console application? I need to be able to extract the archives using the regular, widely available 7-Zip program. Here are my results with the examples

stackoverflow.com

7z(7-zip)을 c#에서 사용하는 방법을 구글에서 검색하면, 일단 제일 먼저 위의 글을 발견하게 된다.

뭔가 방법이 많은데.. 그만큼 고민이 많다는 뜻이 되겠다.

 

먼저 개념부터 잡고 가자. 7z은 파일을 압축할 때는 LZMA라고 하는 암호화 라이브러리로 압축을 한다. 좀 더 정확하게 말하자면, 파일 하나의 내용물만 압축할 때는 이 LZMA를 사용한다. 하지만, 여러 개의 압축된 파일을 하나로 묶고 싶다면? 이때 필요한 것이 7z이라는 파일 포맷이다. 7z 파일 포맷에는 파일명과 파일 사이즈, 날짜 등 각종 추가 정보도 포함되어 있다. 즉, 알맹이는 LZMA이고 껍데기는 7z이라는 파일의 형태인 것이다. (이런 방식은 zip 등 다른 압축 파일 형식도 유사하다)

 

7-zip 공식 홈페이지를 방문해보자. (www.7-zip.org/)

여기를 자세히 보면 LZMA SDK는 있지만, 7z SDK는 보이지 않는다. NuGet 홈페이지에서 LZMA 패키지(www.nuget.org/packages/LZMA-SDK/)를 살펴봐도 똑같다. 즉, LZMA 라이브러리를 사용하면, '파일 하나의 내용'을 압축할 수 있지만, 딱 거기까지이다. 7z 파일을 만들어 주는 기능이 아닌 것이다.  혹시나 싶어 *. lzma라는 파일 포맷이 따로 있는지 살펴보니 있긴 있는데, 원본 파일의 내용을 압축한 이후에 저장 시에는 파일 헤더에 뭔가를 붙여 넣어야 한다. 자세한 내용은 링크 참고 => svn.python.org/projects/external/xz-5.0.3/doc/lzma-file-format.txt

이런 *.lzma 파일 포맷을 사용하겠다면 헤더를 직접 만들어서 넣어 줘야 하기 때문에 귀찮다. 다행히 *. lzma라는 포맷을 반디집 등에서 압축해제를 지원해주기는 한다. 하지만, 대중화된 포맷이 아니라서 부담스럽다.

 

막상 찾아보니 그리 어렵지는 않다. 아래 코드 참고 바람.

void CompressFile(string outFile, string inFile)
{
	SevenZip.Compression.LZMA.Encoder coder = new SevenZip.Compression.LZMA.Encoder();
	FileStream input = new FileStream(inFile, FileMode.Open);
	FileStream output = new FileStream(outFile, FileMode.Create);

	// Write the encoder properties
	coder.WriteCoderProperties(output);

	// Write the decompressed file size.
	output.Write(BitConverter.GetBytes(input.Length), 0, 8);

	// Encode the file.
	coder.Code(input, output, input.Length, -1, null);
	output.Flush();
	output.Close();
}

void DecompressFile(string inFile, string outFile)
{
	SevenZip.Compression.LZMA.Decoder coder = new SevenZip.Compression.LZMA.Decoder();
	FileStream input = new FileStream(inFile, FileMode.Open);
	FileStream output = new FileStream(outFile, FileMode.Create);

	// Read the decoder properties
	byte[] properties = new byte[5];
	input.Read(properties, 0, 5);

	// Read in the decompress file size.
	byte[] fileLengthBytes = new byte[8];
	input.Read(fileLengthBytes, 0, 8);
	long fileLength = BitConverter.ToInt64(fileLengthBytes, 0);

	coder.SetDecoderProperties(properties);
	coder.Code(input, output, input.Length, fileLength, null);
	output.Flush();
	output.Close();
}

 

그럼, 7z.dll을 로딩해서 사용하는 방법은 어떨까? NuGet을 검색해보면 SevenZipSharp라는 패키지를 발견할 수 있다. 

www.nuget.org/packages/SevenZipSharp

사용 방법은 간단해 보이지만, 파일이 깨진다는 댓글도 있고, DLL 로딩하느라 그런지 느리다는 얘기도 있다. 게다가 유지보수 안 한 지 꽤 오래되어 보인다. 즉, 프로젝트가 중단되었다는 얘기이다. 게다가 이 패키지는 비주얼 스튜디오 내부의 NuGet 브라우저에서 검색도 안된다. NuGet 홈에서 수동으로 다운로드하여야 한다.

 

NuGet에서 다시 검색해 보면, 의외로 가장 인기 있는 패키지는 따로 있다.

www.nuget.org/packages/SharpCompress/ 

SharpCompress 라고 하는 패키지인데, 7z, zip, rar 등 다양한 포맷을 지원하는 걸로 보이고, 다운로드 수도 어마어마하다. 단, 이 패키지는 .Net Standard 2.0 / .Net 5.0 이상만 지원한다. 즉, 예전 윈도에서는 호환성 문제가 있다.

 

마지막으로 살펴 볼 방법은 스택오버플로우 질문 글에서 채택한 답변인데, 아주 간단하다.

그냥 7z.exe를 프로세스로 실행하는 방법이다. 너무 간단해서 허무할 수도 있는데, 그래서 NuGet을 아무리 뒤져 봐도 내가 원하는 심플한 라이브러리를 못 찾은 게 아닌가 싶다.

 

7z.exe를 사용해서 파일 하나를 압축하는 방법을 간단히 c# 콘솔 버전 코드로 작성하자면 이렇다.

        static bool Compress(string output, string input)
        {
            try
            {
                ProcessStartInfo info = new ProcessStartInfo();
                info.FileName = "7za.exe";
                info.Arguments = "a -t7z \"" + output + "\" \"" + input;

                info.WindowStyle = ProcessWindowStyle.Hidden;
                Process P = Process.Start(info);
                P.WaitForExit();

                int result = P.ExitCode;
                if (result != 0)
                {
                    Console.WriteLine("error!! code = " + result);
                    return false;
                }

                return true;
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
                return false;
            }
        }

        static void Main(string[] args)
        {
            if (Compress("d:\\dummy.7z", "d:\\dummy.txt"))
            {
                Console.WriteLine("Success.");
            }
            else
            {
                Console.WriteLine("Failed.");
            }

            Console.ReadKey();
        }

그런데, 본인이 작성한 코드를 자세히 보면 실행파일 이름이 7z.exe가 아니라 7za.exe이다.

 

7za는 NuGet에서 7z으로 검색하면 최상단에 뜨는 공식 패키지에서 설치할 수 있다.

링크 : www.nuget.org/packages/7-Zip.CommandLine/

일반적인 패키지와 달리 클래스 라이브러리는 없고, 저 7za.exe만 실행파일 위치에 복사해서 넣어주는 좀 이상한 패키지이다.

 

7za.exe와 7z.exe는 어떻게 다를까?

 

일단 7-zip 어플을 공식 홈페이지에서 다운로드하여서 설치하면, c:\Program Files\7-zip 혹은 c:\Program Files (x86)\7-Zip\ 폴더에 설치되는데, 거기에 있는 readme.txt를 먼저 읽어 보자.

 

7zFM.exe - 7-Zip File Manager - 압축파일을 다양한 방식으로 다룰 수 있는 UI 툴이다.
7-zip.dll - Plugin for Windows Shell - 탐색기 콘텍스트 메뉴에서 7z을 사용할 수 있게 해주는 dll
7-zip32.dll - Plugin for Windows Shell (32-bit plugin for 64-bit system) - 이건 64비트 윈도용 32비트 버전
7zg.exe - GUI module - 콘솔 버전처럼 사용하는 툴이지만 결과가 팝업 UI로 표시되는 툴
7z.exe - Command line version - 콘솔 버전이다! 개발자에게 필요한 건 이것!
7z.dll - 7-Zip engine module - 7z.exe에서는 사용하는 dll.
7z.sfx - SFX module (Windows version) - 셀프 압축 해제용 실행파일을 만들 때 필요한 모듈 (윈도용)
7zCon.sfx - SFX module (Console version) - 셀프 압축 해제용 실행파일을 만들 때 필요한 모듈 (콘솔용)

 

즉, 위의 내용을 보면 7z.exe 와 7z.dll 최소 두 개의 파일을 내가 개발한 어플에 같이 포함해서 배포해야 한다는 얘기가 된다. 용량은 1.3MB 정도로 얼마 되지는 않는다. 7z.exe가 dll을 따로 분리한 것은 추후 다른 포맷을 쉽게 추가하기 위한 구조로 보면 된다.

 

반면, 7za.exe 확장성은 없지만, 독립(stand alone) 실행이 가능한 버전이다. 7z.exe와 dll을 합쳐 놓은 거라 보면 되고, 용량은 절반 정도로 훨씬 가볍다. 그래도 여전히 다양한 포맷(7z, lzma, zip, 7z, lzma, cab, zip, gzip, bzip2, Z, tar)을 지원한다.

 

그 외에 7zr이라는 것도 있다. 7z 포맷만 필요한 경우에 사용하면 되는 더 가벼운 버전이지만, 리눅스 버전 등은 있지만 윈도용 바이너리는 따로 배포하는 거 같지는 않다. 7-zip 소스 코드를 보니 프로젝트 파일이 존재하기는 한다. 7zr이 꼭 필요하다면 소스를 컴파일해서 만들어서 써야 할 것으로 보인다.

 

길게 설명했지만, 결론은 7za.exe 파일 하나만 첨부하면 된다는 뜻.

 

그리고, NuGet에서 배포 중인 7za의 버전은 현재 16.04 버전이다. 더 최신 버전인 19.00을 다운로드하고 싶다면, 공식 홈페이지에서 다운로드하면 된다.

다운로드 링크 : www.7-zip.org/download.html

 

마지막 고민은 7za를 쓸 것인가 아니면 LZMA를 직접 사용할 것인가이다. 현재 진행 중인 프로젝트에서는 용량은 크지 않지만, 많은 파일을 압축 해제해야 하기 때문에 성능도 중요하다. 7za를 사용하면 호환성이 좋고 코드는 심플해지지만 매번 프로세스를 호출해야 하는 부담이 있다. 반면, LZMA 라이브러리를 사용하면 이미 메모리에 적재된 함수를 사용하는 거라서 아무래도 성능이 더 좋지 않을까 하는 생각이 든다. 다만 이렇게 하면 파일 포맷은 *.7z이 아닌 *.lzma나 혹은 아예 나만의 커스텀 포맷을 써야 한다는 부담이 있다.

 

추가 내용

 

c#용으로 나온 LZMA SDK를 실제로 사용해 보니, 압축속도는 7z.exe를 이용하는 것보다 2배 정도 느렸지만, 압축해제를 할 때는 2배 정도 빨랐다. c++ 코드를 그대로 c#으로 포팅한 것이다 보니 성능은 좀 애매하게 나오는 걸로 보인다.

 

또, 예전 라이브러리 같아서 사용하지 않으려고 했던 SevenZipSharp를 다시 찾아보니, 다른 이름으로 바뀌어서 명맥을 유지하고 있었다. www.nuget.org/packages/Squid-Box.SevenZipSharp/ 이 라이브러리로 테스트를 해보니 7z.exe를 직접 실행하는 것보다 압축과 해제 통틀어 1.4~2배 정도 빨랐다. 아무래도 이걸 써야겠다. 역시 구관이 명관인가 보다.

C#은 가비지 컬렉터(GC)가 메모리를 자동으로 관리한다. 필요 없는 클래스의 인스턴스를 메모리에서 바로 지우는 게 아니라, 조건이 될 때까지 기다렸다가 지우기 때문에 클래스를 지웠다고 해도 그게 실제로 바로 삭제되는 것은 아니다. 일반적인 메모리라면 GC에 맡겨도 상관이 없지만, 관리되지 않는(Unmanaged, Native) 리소스는 즉각 해제해야 하는 경우가 생기는데, 그럴 때 필요한 것이 Dispose이다.

 

그래서, C++의 경우 소멸자에 각종 변수의 메모리를 해제하는 것으로 간단하게 구현이 될 만한 내용이지만, C#에서는 바로 삭제가 필요한 리소스를 해제하기 위해서 Dispose 함수가 필요하다.

 

소멸자와 Dispose의 차이 : stackoverflow.com/questions/339063/what-is-the-difference-between-using-idisposable-vs-a-destructor-in-c?newreg=eff4d2b40e844d5581272cc65983c418

 

What is the difference between using IDisposable vs a destructor in C#?

When would I implement IDispose on a class as opposed to a destructor? I read this article, but I'm still missing the point. My assumption is that if I implement IDispose on an object, I can

stackoverflow.com

그런데, Dispose를 호출하는 걸 깜박하면 어떻게 될까?

그럴 경우에는 GC에서 해당 인스턴스를 제거할 때, (소멸자에서) Dispose를 호출해준다.

큰 문제가 없으면 그냥 냅 둬도 상관없다는 얘기인데, 다만 다음과 같은 부작용이 생길 수 있다고 한다.

 

1.GC가 해당 인스턴스를 언제 지울 지 알 수 없다.

 즉, Dispose가 언제 호출될지 알 수 없다. 애플리케이션이 종료될 때까지 호출이 안될 수도 있다. 중요한 리소스를 사용하거나, 메모리를 많이 먹는 클래스라면 위험할 수도 있겠다.

 

2.GC가 해당 인스터스를 지울 때 Dispose를 호출하게 되면 그 순간 부하가 걸린다.

 즉, 랜덤하게 랙을 유발할 수도 있다. 성능에 예민한 앱이라면 주의가 필요하다.

 

3.GC가 해당 인스턴스를 지울 때 Dispose에서 예외가 발생하면 어플 자체가 크래시 할 수도 있다.

 수동으로 Dispose를 할 때에는 try/catch로 보호할 수 있지만, 자동제거일 경우 예외를 잡을 수 없기 때문에 매우 위험할 수도 있다.

 

참고 링크 : stackoverflow.com/questions/32397248/what-happens-if-i-dont-call-dispose

 

 

매번 Dispose를 호출하기 귀찮을 때는 using 블록을 사용하면 된다. using을 사용하면 자동으로 Dispose를 해준다.

using과 try/catch를 같이 사용해야 할 때에는 using을 try 안쪽에 넣으면 된다.

 

참고 링크 : theeye.pe.kr/archives/2736

 

Unity C# – IDisposable 알아보기 | 아이군의 블로그

이번에는 IDisposable 인터페이스에 대해서 알아보겠습니다. C#은 가비지콜랙터(Garbage Collector)를 가지고 있습니다. 이 GC는 기본적으로 관리되는 모든 객체들의 참조 링크를 관리하며 더이상 참조되

theeye.pe.kr

 

Dispose 기능이 필요한 커스텀 클래스를 만들어야 할 때에는 IDisposal을 상속 받아서 만들면 된다.

 

참고 링크  : medium.com/dotnetdev/idisposable-%ED%8C%A8%ED%84%B4%EC%9D%98-%EC%98%AC%EB%B0%94%EB%A5%B8-%EA%B5%AC%ED%98%84-%EB%B0%A9%EB%B2%95-4fa0fcf0e67a

 

IDisposable 패턴의 올바른 구현 방법

.NET Framework에서 새로운 클래스를 만들 때 여러가지 메모리 관리 디자인 패턴과 기법을 적용할 수 있지만, 한시적으로 사용해야 할 필요가 있는 자원들을 묶어서 관리할 때에는 IDisposable 패턴을

medium.com

참고 링크 2 : codeless.tistory.com/entry/C-Disposable-%ED%8C%A8%ED%84%B4

 

C# Disposable 패턴

public class MyResourceHog : IDisposable { private bool alreadyDisposed = false; public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } protected virtual void Dispose(bool isDisposing)..

codeless.tistory.com

 

먼저 새로운 깃 서버에서 빈 저장소를 하나 생성한다.

(이때 아무것도 없는 깨끗한 상태의 빈 저장소이어야 한다.)

 

본인 PC 로컬에 새로운 폴더를 하나 만든다.

콘솔창을 열고 해당 폴더로 이동한다.

 

해당 폴더에서 기존 서버 저장소의 내용을 내려 받는다.

 

git clone --mirror <기존 저장소 주소> .\

 

기존 서버와 연결을 끊는다.

 

git remote rm origin

 

새로운 저장소 주소로 연결한다.

 

git remote add origin <새 저장소 주소>

 

새 저장소로 전부 업로드한다.

git push --mirror

 

다른 폴더에서 클론을 받아서 로그, 태그, 브랜치 등을 확인한다.

WPF 윈도우 타입을 None으로 하면 테두리와 타이틀바도 사라져서 깔끔해지지만, 최소화 및 닫기 등 시스템 버튼도 사라져서 불편해진다. 그래서, None 스타일을 유지하면서도 이런 시스템 버튼을 다시 추가하고 싶은 경우가 있다.

 

닫기 버튼은 x 글자를 넣고, 최소화 버튼은 언더바( _ ) 글자로 대신 넣어도 되지만, 최대화 및 복구버튼은 딱히 방법이 없다. 그래서 찾아보니, 예전부터 윈도우에는 이런 특수한 기호를 표현하기 위한 폰트가 이미 존재하고 있었다.

 

해당 폰트의 이름은 "Webdings"이다. 이미 윈도우 98부터 사용되고 있었다고 하니 호환성 걱정은 필요 없다.

자세한 내용은 위키 참고 => en.wikipedia.org/wiki/Webdings

 

Webdings - Wikipedia

Webdings is a TrueType dingbat typeface developed in 1997. It was initially distributed with Internet Explorer 4.0, then as part of Core fonts for the Web, and is included in all versions of Microsoft Windows since Windows 98. All of the Webding glyphs tha

en.wikipedia.org

 

위와 같이 기호만 들어 있는 폰트인데, 시스템 버튼에 필요한 내용은 빨간 박스 안에 있는 4개이다.

각각, 다음과 같다.

 

0 : 최소화

1 : 최대화

2 : 복귀

r : 닫기

 

xaml 코드는 대략 다음과 같다.

            <Button FontFamily="Webdings"
                    x:Name="ChangeViewButton"
                    Content="2"/>
            <Button FontFamily="Webdings"
                    x:Name="MinimizeButton"
                    Content="0"/>
            <Button FontFamily="Webdings"
                    x:Name="MaximizeButton"
                    Content="1"/>
            <Button FontFamily="Webdings"
                    x:Name="CloseButton"
                    Content="r"/>

하지만 이렇게만 만들어서 넣으면 이쁘지 않다.

Webdings 폰트를 이용해서 시스템 버튼을 다시 추가한 이미지

 

테두리와 배경색을 없애는 스타일을 만들어서 사용하면 더 이쁘게 나온다.

    <Style x:Key="SystemButton" TargetType="{x:Type Button}">
        <Setter Property="FontFamily" Value="Webdings"/>
        <Setter Property="FontSize" Value="16"/>
        <Setter Property="Foreground" Value="Gray"/>
        <Setter Property="MinWidth" Value="40"/>
        <Setter Property="Margin" Value="0"/>
        <Setter Property="Background" Value="{x:Null}"/>
        <Setter Property="BorderBrush" Value="{x:Null}"/>
    </Style>

위와 같은 스타일을 만들고,

            <Button Style="{DynamicResource SystemButton}" 
                    x:Name="ChangeViewButton"
                    Content="2"/>
            <Button Style="{DynamicResource SystemButton}" 
                    x:Name="MinimizeButton"
                    Content="0"/>
            <Button Style="{DynamicResource SystemButton}" 
                    x:Name="MaximizeButton"
                    Content="1"/>
            <Button Style="{DynamicResource SystemButton}" 
                    x:Name="CloseButton"
                    Content="r"/>

버튼에서 해당 스타일을 가져다 쓰자.

 

그러면 이렇게 이쁘게 나온다.

'개발 > WPF' 카테고리의 다른 글

[WPF] BackgroundWork 사용 예제  (0) 2021.03.27
[WPF] 기본 버튼의 스타일을 바꾸는 방법  (0) 2020.12.26
[WPF] 테마와 스킨  (0) 2020.12.24

링크 : stackoverflow.com/questions/29917705/how-can-i-change-the-default-style-of-wpf-controls-for-a-single-assembly

스킨은 UI 컨트롤의 색상과 이미지 정도만 바꾸는 것이고, 테마(Theme)은 스킨에 더해 컨트롤의 크기나 연출 방식 까지도 바뀌는 걸 의미한다. (더 큰 개념)

 

WPF 어플에서 테마나 스킨을 사용하려면 다음과 같은 것을 고려해야 한다.

 

1. 윈도우의 기본 테마 중 하나를 가져다 쓰기.

2. 프로그램 내부에 테마나 스킨을 미리 세팅하기 vs 외부 파일(*.xaml)로 저장해서 그 중 하나를 읽어 오기 (내장 혹은 외부 파일)

3. 프로그램 구동시 정해진 테마나 스킨 중 하나를 선택하기(static) vs 프로그램 구동 중에 바꿀 수 있게 하기(dynamic)

 

등 여러가기 경우가 있기 때문에 이 중 어떤 방식을 사용할 것인가에 따라 구현 방식도 달라진다.

자세한 내용은 아래의 링크를 참고하자.

 

michaelscodingspot.com/wpf-complete-guide-themes-skins/

 

WPF complete guide to Themes and Skins - Michael's Coding Spot

In WPF we define a UI resource system (mostly in XAML resource dictionaries) which includes colors, templates, icons, styles and so on. Sometimes, we need the ability to change our application’s look and feel dynamically, allowing different Themes or Sk

michaelscodingspot.com

위의 블로그를 가보면 내부분의 내용은 이미지나 글로 설명이 되어 있고, 실제 구동하는 소스는 아래쪽에 링크가 첨부 되어 있다.

 

윈도우 7 내장 테마를 적용하는 방법

stackoverflow.com/questions/2075720/windows-7-theme-for-wpf

 

Windows 7 theme for WPF?

Is there any way to make a WPF app look like it's running on Windows 7 even if it's running on XP? I'm looking for some kind of theme I can just paste in. I'm aware of the themes project on Codeplex (

stackoverflow.com

 

코드 내부에 정의된 스킨 사용 예제

www.codeproject.com/Articles/19782/Creating-a-Skinned-User-Interface-in-WPF

 

Creating a Skinned User Interface in WPF

Reviews the basics of creating a WPF user interface with various visual styles.

www.codeproject.com

 

윈도우 테마와 내부 테마 파일로 정의된 테마까지 다 사용하는 테마 스킨 엔진 예제

www.codeproject.com/Articles/22575/WPF-Themes-and-Skins-Engine

 

WPF Themes and Skins Engine

In this article, I will talk about different techniques to load WPF themes and skins. I will also provide a helper class for loading and unloading themes.

www.codeproject.com

 

위와 같이 솔루션 이름 뒤에 브랜치 이름을 붙일 수 있는 플러그인 발견했다.

 

플러그인 다운로드 경로 : marketplace.visualstudio.com/items?itemName=mayerwin.RenameVisualStudioWindowTitle

 

Customize Visual Studio Window Title - Visual Studio Marketplace

Extension for Visual Studio - This lightweight extension allows changing the window title of Visual Studio to include a folder tree with a configurable min depth and max depth distance from the solution/project file, and the use of special tags to help wit

marketplace.visualstudio.com

 

git을 사용하면 경우엔 위와 같은 식으로 설정하면 된다.

 

*경고* 스포를 원치 않으시면 나가주세요~

 

 

 영화 '포드 v 페라리'를 보면 1966년 르망24시 경주에서 세 대의 GT40이 나란히 결승점을 통과한다. 눈 크게 뜨고 봐도 1cm의 오차도 없어 보일 정도로... 그런데, 동시에 들어 올 경우 공동 우승이 아니라, 경기 시작시 좀더 뒤에서 출발한 차가 이긴다는 숨은(?) 규칙 때문에 주인공인 켄 마일즈 대신 멕라렌이 우승하게 된다.

 

 저렇게 정확하게 운전하면서 들어왔다고? 이해는 잘 안되었지만, 그냥 그런가보다 하고 넘어갔다가 나중에 인터넷에 돌아다니는 다른 글들 때문에 헷갈리기 시작했다. 영화와는 다르게 실제로는 '결승점 바로 앞에서 멕라렌이 약속을 깨고 먼저 들어가는 바람에 순위가 바뀌었다'라는 주장이었다. 맥라렌이 나쁜 짓(?)을 했지만, 영화에서 사실대로 묘사하면 너무 욕을 먹을까봐 적당히 각색해서 찍었다는 추론이 가능한 주장이다. 나는 그가 정말로 그러했는지 궁금해서 당시 기록 영상을 찾아봤다.

 

12분 즈음에 결승 통과하는 장면 나옴.

 

영상을 찾아보니 정말로 그렇게 보였다. 영상에서 하늘색 1번이 켄 마일즈의 차량이고, 검정색 2번이 멕라렌이 운전한 차량이었는데 결승점을 통과할 때 확실히 검정색의 2번 맥라렌 차량이 먼저 들어온다. 영화와는 다른 점이다. 그렇다면 그 주장이 사실인 것일까?

 

 그래서 좀더 검색을 해보았다. 그런데, 뭔가 이상하다. 실제 경기를 설명하는 글들을 읽어 보니 영화와 별로 다르지 않다. 켄 마일즈가 속도를 일부러 늦춘 것도 사실이고, 경기 결과도 1차적으론 무승부(dead heat)였지만, 무승부일 경우 가장 먼 거리를 주행한 차가 우승한다는 룰 때문에 승부가 뒤집어진 것도 사실이라는 글들을 발견했다. 그렇다면 왜 저런 오해가 생긴 것일까?

 

 그것은 르망24시 경주만의 독특한 룰 때문이었다.

 

 당시 르망 24시에서 순위를 가르는 기준은 다른 레이싱 경기와 달리 시간이 아닌 거리였다. 이론적으론 24시간을 지난 시점 딱 그 시점의 주행 거리이다. 하지만, 24시간이 경과했을 때 모든 차의 위치를 정확히 기록할 수는 있는 방법이 당시엔 없었기에, 24시간이 지난 후 결승선을 통과했을 때를 기준으로 총 몇 바퀴를 돌았는지를 비교했다. 굉장히 부정확해 보이지만 이게 가능했던 이유는, 그 당시까지만 해도 1등과 2등 차이가 최소 2~4바퀴 이상 크게 벌어졌기 때문이다. 그래서, 두 대 이상의 차가 같은 바퀴 수를 돌고 들어오는 바람에 그걸 무승부로 간주하고 시작 위치까지 따지는 숨은 룰을 적용해야 했던 적은 한번도 없었던 걸로 보인다. 1966년 포드 GT40 세 대가 거의 동시에 결승선을 통과하기 전 까지는... 

 

참고로, 1966년 당시 순위는 이렇다. (1, 2위가 같은 바퀴 수를 돌았다.)

1위 : 360 바퀴 - Ford GT40 Mk.II - Bruce McLaren, Chris Amon

2위 : 360 바퀴 - Ford GT40 Mk.II - Ken Miles, Hulme

3위 : 348 바퀴 - Ford GT40 Mk.II - Ronnie Bucknum, Dick Hutcherson

 

 이전에 그런 사례가 없었기 때문에 당시의 레이서들도 그런 숨은 룰이 있다는 걸 모르고 경주를 했던 거 같다. 포드 팀에서는 마지막 랩에 들어서야 그런 룰이 있다는 걸 뒤늦게 발견했지만 레이서에게 알릴 방법이 없었다고 한다. 동시에 들어오자는 아이디어가 현장에서 즉흥적으로 나온 거라서 충분히 검토할 시간이 부족했던 거 같다. 결국 그 아이디어는 켄 마일즈가 3관왕을 못하는 참사로 이어졌다. 르망24의 이 애매한 규정은 1971년에 롤링 스타트가 도입 되면서 고쳐졌는데, 바퀴 수가 동일할 경우 총 주행시간이 짧은 차, 즉 지금 우리에게 익숙한 방식인 '결승선에 먼저 들어오는 차가 우승'하는 방식으로 바뀌었다.

 

 결국, 영화에서 차량 3대가 동시에 들어오는 것처럼 보여 준 이유는 지금의 상식으로는 잘 이해되지 않는 당시의 룰을 제한된 시간 안에 관람객들에게 효과적으로 전달할 수 있는 방법을 고민하다가 지금의 룰과 비슷하게 연출하여 관객들의 혼란을 줄이려 한 일종의 궁여지책으로 보인다.

 

사족1. 영화를 보면 켄 마일즈가 페라리를 추월하는 장면이 두번 나온다. 첫번째 추월에서는 상대 페라리 드라이버가 그냥 기분 나빠하는 정도이지만, 두번째에는 크게 당황하는데 한바퀴 이상 벌어지면 순위가 확실히 바뀌기 때문이다.

 

사족2. 당시 우승한 맥라렌은 우리가 아는 유명한 슈퍼카의 그 맥라렌이 맞다. 안타깝게도 켄 마일즈처럼 맥라렌도 1970년에 신형 자동차를 서킷에서 테스트하다 사고로 사망했다. 

 

참고 링크 : https://en.wikipedia.org/wiki/1966_24_Hours_of_Le_Mans

 

1966 24 Hours of Le Mans - Wikipedia

This article is about the race. For the 2019 film released internationally as Le Mans '66, see Ford v Ferrari. The 1966 24 Hours of Le Mans was the 34th Grand Prix of Endurance, and took place on 18 and 19 June 1966.[1][2] It was also the seventh round of

en.wikipedia.org

참고 링크 : https://www.thewrap.com/ford-v-ferrari-fact-check-did-le-mans-66-really-end-that-way/

 

'Ford v Ferrari': Did All 3 Cars Cross the Finish Line at the Same Time at Le Mans '66?

James Mangold's film starring Matt Damon and Christian Bale opens this weekend

www.thewrap.com

참고 링크 : https://en.wikipedia.org/wiki/24_Hours_of_Le_Mans#Classification

 

24 Hours of Le Mans - Wikipedia

From Wikipedia, the free encyclopedia Jump to navigation Jump to search Sports car race held in France The 24 Hours of Le Mans (French: 24 Heures du Mans) is the world's oldest active sports car race in endurance racing, held annually since 1923 near the t

en.wikipedia.org

 

'기타' 카테고리의 다른 글

스타트렉에 먼저 등장했던 삼체인?  (0) 2024.04.15
각종 미세먼지 마스크 사용후기  (0) 2018.12.22

크리스마스 선물에 감동 받은 펭수

'그림' 카테고리의 다른 글

펭수 표정 모음  (0) 2019.12.18
펭수 어이없음  (0) 2019.12.18
나무 한번 그려봄  (0) 2019.11.24
태권브이를 개조해 보았다  (0) 2019.03.11

+ Recent posts