블로그 이미지
훅크선장

카테고리

분류 전체보기 (363)
사진이야기 (23)
펭귄컴퓨팅 (122)
컴퓨터보안 (84)
절름발이 프로그래머 (59)
하드웨어개조 (23)
멀알려줄까 (35)
잡다한것들 (15)
홈베이킹&홈쿠킹 (2)
Total
Today
Yesterday

달력

« » 2025.7
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31

공지사항

태그목록

최근에 올라온 글

델파이에서도 GZip 압축을 풀 수 있습니다.
GZip 압축은 .gz 확장자를 가지는 파일로 볼 수 있습니다.

공개된 zlib를 사용하는 것이 가장 좋습니다.
다만, zlib는 원래 GZip 용이 아니고, .Z 확장자를 가지는 압축파일을 다루는 라이브러리입니다.
델파이용 zlib는 다음 링크에서 받을 수 있습니다.

zlib 사용법에 대해서는 다른 분께서 이미 설명서를 잘 쓰셨습니다.

다만, zlib를 이용하여, GZip 압축을 푸는 방법이 잘 안 알려져 있을 뿐입니다.

다음과 같이 하면, 스트림을 이용하여, GZip 파일 압축을 풀 수 있습니다.
-- 에러 처리를 추가하였습니다. GZ 함수 계열이 모두 procedure 이다보니, 에러처리가 별도로 필요합니다.  --

use ZlibEx, ZlibExGZ;
...
...
procedure TForm1.btn3Click(Sender: TObject);
var
  InputFileName, OutputFilename : string;
  InputStream : TFileStream;
  OutputStream : TMemoryStream;
  OutputSize : Int64;
begin
  InputFileName := edt1.Text;
  OutputFilename := edt2.Text;
  InputStream := TFileStream.Create(InputFileName, fmOpenRead);
  try
    OutputStream := TMemoryStream.Create;
    try
try
      GZDecompressStream(InputStream, OutputStream);
      OutputSize := OutputStream.Size;
except
  on E : Exception do
  begin
mmo1.Lines.Add(E.ClassName+' error raised, with message : '+E.Message);
OutPutSize := 0;
  end;
end;

      mmo1.Lines.Add(IntToStr(OutputSize));

      OutputStream.SaveToFile(OutputFileName);
    finally
      OutputStream.Free;
    end;
  finally
    InputStream.Free;
  end;
end;

굳이 스트림을 사용하는 이유는 파일내용을 단순히 파일로 저장하기 보다는, 스트림으로 다른 곳에서 사용하는 경우가 더 많기 때문입니다.
그래서 일부러 위 예제에서는 메모리 스트림을 사용했습니다. 파일 스트림을 사용해도 결과는 동일합니다만, 스트림 생성때 인자가 틀립니다.

출력파일을 위한 파일스트림은 이렇게 생성합니다.
OutputStream := TFileStream.Create(OutputFileName, fmCreate);

단순히 파일로만 압축을 풀어서 저장하고 싶다면, 간단하게 함수 한번 호출로 끝납니다.

GZDecompressFile(InputFileName, OutputPath);

스트림과는 다르게, 파일에서 파일로 압축해제는 입력값이 압축된 파일과 압축파일이 풀려질 디렉토리  즉 경로만 필요합니다.


Posted by 훅크선장
, |
를 참고했습니다.

python 2.3 이하 버전에서 주로 쓰던 방법은 spawn 계열 함수를 이용합니다. 
python 2.4 이상에서는 Popen 함수 또는 call 함수를 이용합니다.

가능하면,  spawn 계열보다는 Popen이나 call을 이용하기를 권장하고 있습니다.

import Popen from subprocess

P_NOWAIT example:
pid = os.spawnlp(os.P_NOWAIT, "/bin/mycmd", "mycmd", "myarg")
==>
pid = Popen(["/bin/mycmd", "myarg"]).pid

P_WAIT example:
retcode = os.spawnlp(os.P_WAIT, "/bin/mycmd", "mycmd", "myarg")
==>
retcode = call(["/bin/mycmd", "myarg"])

Vector example:
os.spawnvp(os.P_NOWAIT, path, args)
==>
Popen([path] + args[1:])

Environment example:
os.spawnlpe(os.P_NOWAIT, "/bin/mycmd", "mycmd", "myarg", env)
==>
Popen(["/bin/mycmd", "myarg"], env={"PATH": "/usr/bin"})


실제 사용해 보니,
Popen(["c:\progdir\prog.exe", ("%d" % int_val), ("%s" % str_val)], cwd =  "c:\progdir\\")

라고 쓰는게 가장 안정적이다.
cwd 변수는 프로그램의 실행디렉토리를 지정하는 것으로, 프로그램이 그 디렉토리에서 실행되는 효과를 가진다.
Posted by 훅크선장
, |
http://www.torry.net/quicksearchd.php?String=faststrings&Title=Yes
에 있는 FastStrings 모듈을 이용하면, Split() 함수가 있지만,

델파이 2009 이상에서는, 유니코드 지원때문에 위 모듈을 사용할 수 없다.

나중에 알게된 사실이지만, 위의 Split 함수는 TStrings를 사용하므로, 폼과 관련된 객체를 사용하지 않는다면 쓸 수 없다고 합니다. 완벽하게 확인되지는 않았지만, 문제가 발생한 경우를 당해봤습니다.

그래서, 함수를 만들어서 사용할 수 있다.

참고한 곳은

// 문자열을 구분자(문자)를 기준으로, 분해하는 함수
// 사용전에, 반드시 TStringList를 생성하고, 사용후 free 해야됨.
procedure Split(Input: string; const Delimiter: Char; var Strings: TStringList) ;
begin
   Assert(Assigned(Strings)) ;
   Strings.Clear;
   ExtractStrings([Delimiter], [' '], PChar(Input), Strings);
end;

여기까지가 아주 안전한 방법입니다.



-------------------------------------------------------------------------
이것은 이전에 작성한 내용으로 참고할 만하지만, 그렇게 쓸모 있지는 않습니다.

참고한 곳은


procedure Split(const Input: string; const Delimiter: Char; const Strings: TStrings);
begin
  Assert(Assigned(Strings));
  Strings.Clear;
  Strings.Delimiter := Delimiter;
  Strings.DelimitedText := Input;
end;

아예,
http://delphi.about.com/cs/adptips2002/a/bltip0902_2.htm
이렇게 직접 토큰화 함수를 만들어서 할 수도 있군요.


Posted by 훅크선장
, |
ParamCount 와 ParamStr 을 이용하여, 명령어 인자를 처리할 수 있다.

Form이 있건, 없건 상관이 없다.

Console Program의 경우에 대해서, 다음과 같이 소스로 만들면 된다.
Form이 있는 프로그램인 경우에는, 아래 소스를 발췌하여, FormCreate() 함수에 추가하면 된다.

인자 사용법은 실행시에,
c:>  Project1.exe  -a:HERE_IS_A  -b:THRER_IS_B
와 같이 씁니다.

아래소스에는 반드시 FastStrings 모듈을 추가해서 사용해야 합니다.

--------------------------------------------------------------------------------
program Project1;

{$APPTYPE CONSOLE}

uses
  Sysutils,
  Classes,
  Dialogs,
  FastStringFuncs in 'src\FastStringFuncs.pas',
  FastStrings in 'src\FastStrings.pas';

var
   param_idx:integer;
   argumentstr, prefix, realarg : String;
   arguments : TStrings;

begin
  try
    { TODO -oUser -cConsole Main : Insert code here }
     for param_idx := 1 to ParamCount do
   begin
     //ShowMessage(ParamStr(param_idx));
     argumentstr := ParamStr(param_idx);
     if (argumentstr[1] = '-') then
     begin
       Split(Copy(argumentstr, 2, Length(argumentstr) - 1), ':', arguments);
       prefix := arguments[0];
       realarg := arguments[1];
       if ((arguments.Count = 2) and (Length(prefix) = 1)) then
       begin
         Case arguments[0][1] of
            'a' : ShowMessage( 'option a : ' + arguments[1]);
            'b' : ShowMessage( 'option b : ' + arguments[1]);
         else ;
         end;
       end;
     end;

   end;

  except
    on E:Exception do
      Writeln(E.Classname, ': ', E.Message);
  end;
end.
Posted by 훅크선장
, |
http://delphi.about.com/od/objectpascalide/a/delphi-md5-hash.htm
를 참조했습니다.

uses IdHashMessageDigest, idHash;

//returns MD5 has for a file
function MD5(const fileName : string) :string;
var
  idmd5 : TIdHashMessageDigest5;
  fs : TFileStream;
begin
  idmd5 := TIdHashMessageDigest5.Create;
  fs := TFileStream.Create(fileName, fmOpenRead OR fmShareDenyWrite) ;
  try
    result := idmd5.AsHex(idmd5.HashValue(fs)) ;
  finally
    fs.Free;
    idmd5.Free;
  end;
end;

2009 버전 이상에서는, 함수가 변경되어서, 다음과 같이 
//returns MD5 has for a file
function MD5(const fileName : string) :string;
var
  idmd5 : TIdHashMessageDigest5;
  fs : TFileStream;
begin
  idmd5 := TIdHashMessageDigest5.Create;
  fs := TFileStream.Create(fileName, fmOpenRead OR fmShareDenyWrite) ;
  try
    result := idmd5.HashStreamAsHex(fs);
  finally
    fs.Free;
    idmd5.Free;
  end;
end;
로 쓰면 됩니다.
Posted by 훅크선장
, |
아래의 펌글을 참고해서, Connection String을 만든다음,
Query를 통해서, 자료를 하나씩 가져오면 됩니다.

procedure TForm1.Button1Click(Sender: TObject);
var
  fullURL  : string;
  urllist : Tstringlist;
  ADOQuery1: TADOQuery;
begin
  ADOQuery1 := TADOQuery.Create(nil);
  ADOQuery1.ConnectionString := 'Provider=MSDASQL.1;Password=패스워드;Persist Security Info=True;User ID=사용자명;Data Source=데이터베이스 DSN 명칭';
  ADOQuery1.SQL.Text := 'select * from 테이블명';
  ADOQuery1.Open;
  ADOQuery1.First;
  urllist := TStringList.Create;
  while not ADOQuery1.Eof do
  begin
    fullURL := ADOQuery1.FieldByName('필드명').AsString;
    urllist.Add(fullURL);

    ADOQuery1.Next;
  end;

  Memo1.Lines := urllist;

end;
Posted by 훅크선장
, |
http://all4programer.blogspot.com/2008/03/how-to-connect-mysql-to-borland-delphi.html
에서 가져왔습니다.

----------------------------------------------------------------------------------

HOW TO CONNECT MYSQL TO BORLAND DELPHI USING MYODBC

HOW TO CONNECT MYSQL TO BORLAND DELPHI USING MYODBC

  1. Creating MySQL ODBC DataSource

  1. We need to install MyODBC (you can download from www.mysql.com)
  2. install MyODBC or MySQLODBC
  3. Create DSN for accesing trough ODBC, follow the step bellow :
  4. Go To Control Panel>>Administrative Tools>>Data Source (ODBC)
  5. When ODBC Data Source Administrator dialogs showed click Add.. button
  6. Create New Data Source dialog will show, choose MySQL ODBC Driver
  7. Click Finish until MySQL ODBC Driver DSN Configuration dialog showed
  8. Enter Data Source Name as you like
  9. fill all information that needed for connection to be occurred
  10. Click Test Data Source Button to testing the connection to MySQL Server
  11. Connection succeed
  12. MySQL ODBC Data Source created

  1. Connecting Data Source to Delphi using ADOConnection

  1. on your project application pick ADOConnection Component in ADO VCL Tab
  2. Put ADOConnection component into a form
  3. Double Click the ADOConnection on your form until Connection String Dialog Wizard appeared
  4. Choose Use Connection String and then click Build Button
  5. when Data link properties dialog box appeared on the provider tab choose Microsoft OLEDB Provider for ODBC Drivers
  6. Click Next Button
  7. On the Connection Tab, fill all the field
  8. Choose Use Data source name and fill thecombobox with MySQL ODBC Data source that we have been created before in DSN
  9. fill information for username, password, and fill the database that you want access in Combobox Enter initial catalog to use
  10. Test the connection with clicking the Test Connection Button
  11. Connection Succed
Posted by 훅크선장
, |
Visual C++에서는  UNIX에서 제공하는 getopt() 함수가 없습니다.

그런 경우, 간단하게 인자 처리를 하고 싶으면 다음과 같이 합니다.

 char *pszFolder;
 char *pszDLLName;
 bool bUninstall;

 int arg = 1;
 for (; arg < argc && (argv[arg][0] == '-' || argv[arg][0] == '/'); arg++) 
 {
  CHAR *argn = argv[arg] + 1;
  CHAR *argp = argn;
  while (*argp && *argp != ':')
   argp++;
  if (*argp == ':')
   *argp++ = '\0';

  switch (argn[0]) {
  case 'd':                                     // 설치 폴더
  case 'D':
   pszFolder = argp;
   break;

  case 'f':                                     // dll 이름
  case 'F':
   pszDllName = argp;
   break;

  case 'u':
  case 'U':
   bUninstall = TRUE; 
//    RemoveRasAdmin(); 
//    return 0; 
   break; 

  default:
   printf("%s Bad argument: %s\n", argv[0], argv[arg]);
//   Usage( argv[0] ); 
   break;
  }
 }

argp 가 실제 처리된 인자입니다. (당근, 문자열이죠.)

인자사용은
프로그램명   -d:/abc/efg/  -f:who.dll  -u

원본 getopt와는 다르게, 옵션문자뒤에 세미콜론 : 이 있어야합니다. 주의~.
Posted by 훅크선장
, |
str 표준함수 중에 strtoul() 을 사용하면 됩니다.
atoi() 함수는 정수형 int로 바꾸기 때문에, 범위에 한계가 있다고 합니다.

10진수 경우,
#include <stdlib.h>

const char *str = "1234567890";

char *endptr = NULL;

unsigned long value = strtoul( str, &endptr, 10);

16진수 경우,
#include <stdlib.h>

const char *str = "B8000";

char *endptr = NULL;

unsigned long value = strtoul( str, &endptr, 16);

이상입니다.
Posted by 훅크선장
, |
너무 간단한 내용인데,
처음에 이해를 못해서 한참 헤메는 실수를...


type
MyNewType = Integer;


이렇게 하면 됩니다. 새로운 변수 타입이 생긴겁니다.
C 언어 구문으로 보면,
typedef   int    MyNewType;
이 됩니다.

델파이에서 사용할때는,

implementation

function MyFunc(AString: String; AMaxChar: Integer): String;
var
aVar : MyNewType ;
begin
...
end;

아주 간단합니다.
Posted by 훅크선장
, |