2010-06-15 7 views
2

저는 소프트웨어 프로그래머가 아니기 때문에 엔지니어이며, 제발 내 잘못을 용서해주십시오.Delphi 이진/텍스트 파일 필요성

2 개의 디지털 온도계에 연결된 USB 포트에서 "실제"데이터 유형을 읽는 델파이 (7SE) 프로그램을 작성했습니다.

나는이 프로그램을 많이 마쳤습니다.

내가 이진 파일 (들)이 "진짜"데이터를 저장하려면 : 아직 따라 설명 나는이 완료되지 않은 어떤

. 텍스트 파일도 괜찮 으면 좋겠지 만 큰 데이터 파일을 가지고 있을까 걱정됩니다.

또한이 데이터를 이진/텍스트 파일에서 다시 읽고 내 Delphi 응용 프로그램을 사용하여 데이터를 표시하고자합니다.

나는 이것이 너무 어려울 것이라고 생각하지 않습니다. 현재 .CSV 형식으로 내 데이터를 저장합니다.

이진 파일에는 내 응용 프로그램 사용자가 시작한 여러 세션의 데이터가 들어 있어야합니다.

"역사적인"데이터라고하는 단추를 클릭하면 이전에 시작한 다른 세션 시간 인 &이 표시되는 새 창/폼이 나타납니다. 그런 다음 세션이 선택되고 표시를 위해 데이터가 검색됩니다.

하나의 이진 파일에서 수행 할 수 있습니까? 아니면 두 개의 파일을 사용해야합니까? 하나는 "실제"데이터를 나타내고 다른 하나는 다른 세션 시간을 인덱싱합니까?

이진 데이터를 저장하는이 방법에 대한 필자의 요구 사항은 필자가 파일 이름을 계속 입력하지 않아도되므로 많은 데이터 파일을 추적 할 필요가 없다는 것입니다. thermo.hst (기록 데이터)와 thermo.idx (인덱스 파일) 파일 등의 실제 온도 데이터, 판독 데이터의 타임 세션으로 모든 정보를 포함하는 것, 예를 들어

시작 등

& 종말

유용한 포인터와 자세한 내용으로 작성된 코드가 크게 도움이 될 것입니다.

+4

데이터 파일에 저장할 세션은 몇 개입니까? 그것의 다량 인 경우에 당신은 1 개를 사용하지 않을 이유가없는 한 당신은 데이타베이스 사용을 고려하고 싶을 수도 있습니다? 나는 그것이 훨씬 더 많은 일을 알고 있지만 장기적으로 번거롭지 않게 될 것입니다. – Re0sless

+0

Re0sless와 완전히 동의합니다. 이와 같은 응용 프로그램의 경우 데이터베이스로 interbase를 사용할 수 있습니다. – Bharat

답변

3

이 샘플 코드가 너무 늦어서 도움이되지 않았기를 바랍니다.

은 (내가 깨끗하게 코드를 나열 할 수 있도록 내에서 다른 응답으로이 추가되었습니다.이 또는 내 이전 게시물이 귀하의 질문에 응답하면, 그래서 명성 포인트를 획득 대답 아이콘을 클릭 해주세요!)

다음은 ini 파일의 섹션을 읽고 가장 큰 파일 이름을 찾는 방법을 보여주는 대략적인 코드입니다. 나는 그것이 컴파일되고 유효한 값을 반환하는 것으로 보이지만, 필요한 것이 무엇인지 확인해야합니다.당신에게 아이디어를 보여줄 것이 많습니다 ...

데이터 파일 이름에 확장자가있는 경우, 다음과 같은 것을 사용하여 샘플 코드에서 확장명을 제거하는 코드를 추가해야합니다. FileName : = ChangeFileExt (Filename, ').

// Call with an open inifile. Returns the name of the next filename, or '' if trouble 
    Function GetNextFileName(const IniFile: TInifile):String; 
    const 
    BASE_FILENAME = 'File.'; // sections in the ini file will be [File.1], [File.2], ... [File.100], etc. 
    var 
    Sections: TStringList; 
    NumericPartAsString: String; 
    NumericPartAsInteger: Integer; 
    ListIndex: Integer; 
    LargestFileNumberSeenSoFar: Integer; 
    begin 
    Result := ''; 
    Sections := TStringList.Create; 
    IniFile.ReadSections(Sections); // fills StringList with the names of all sections in the ini file 
    if(Sections.Count = 0) then 
     Result := BASE_FILENAME + '1' 
    else 
     begin // find largest extension 
     LargestFileNumberSeenSoFar := -1; 
     ListIndex := 0; 
     while ListIndex <= (Sections.Count - 1) do // for every string (which is also a filename) in the string list: 
      begin 
      NumericPartAsString := StringReplace(Sections.Strings[ListIndex], BASE_FILENAME, '', []); // remove base filename 
      if (NumericPartAsString <> '') then 
       begin 
       NumericPartAsInteger := StrToIntDef(NumericPartAsString, -1); 
       if (NumericPartAsInteger > LargestFileNumberSeenSoFar) then 
        LargestFileNumberSeenSoFar := NumericPartAsInteger; 
       end; 
      inc(ListIndex); 
      end; 
     if (LargestFileNumberSeenSoFar > -1) then 
      Result := BASE_FILENAME + IntToStr(LargestFileNumberSeenSoFar + 1); 
     end; 
    Sections.Free; 
    end; { GetNextFileName } 

    procedure TForm1.Button1Click(Sender: TObject); 
    var 
    IniFile: TInifile; 
    NewFileName: String; 
    begin 
    IniFile := TInifile.Create('c:\junk\ini.ini'); 
    NewFileName := GetNextFileName(Inifile); 
    if (NewFileName = '') then 
     ShowMessage('Error finding new filename') 
    else 
     ShowMessage('New filename is ' + NewFileName); 
    IniFile.Free; 
    end; 
+0

로버트 너무 늦지 않았습니다. 나는 첫 번째 답을 코드에 넣으려고 내 머리카락을 꺼내왔다. 나는 마침내 거기에 도착했다. 그런 다음 두 번째 대답과 코드로 응답했습니다. 나는 당신의 솔루션이 제 자신의 코드를 훨씬 초과했다고 말해야합니다. 정말로 우아한. 나는 그것을 행동에 투입하고 절대적으로 완벽하게 작동합니다. 참으로 많은 감사드립니다. 나는 또한 당신의 대답을 투표하려고 노력했지만 아무 소용이 없습니다. 분명히 당신은 투표에 대한 명성이 필요합니다, 결과적으로 stackoverflow는 로그인 후에도 나를 허용하지 않을 것입니다. 그러나 나는 "당신의 대답을 수락"할 수있었습니다.이 작업에 대한 당신의 통찰력을 다시 한번 감사드립니다. – jdsdesign

+0

나는 당신을 돕기 위해 매우 기쁘다. 그리고 내가 당신에게 머리를 끌어 당기는 약간을 절약하기 위해 더 일찍 로그인했으면 좋겠다! :-) 다른 질문이 있으면 주저하지 말고이 글에 게시하십시오. 우리가 도울 수있는 문제를 해결하기 위해 고군분투하는 것에는 거의 의미가 없습니다! – RobertFrank

0

데이터를 인터리브 할 수 있습니다. 블록을 식별하고 그 길이를 포함하는 헤더로 모든 블록 (히스토리 집합)을 시작하십시오. 독서를하면 쉽게 분리 할 수 ​​있습니다.

필요한 경우 빠른 액세스를 위해이 옆에 추가 색인 파일을 저장할 수 있지만이 경우 일부 내장 데이터베이스를 연구하기 시작합니다. (TDBF, sqlite 또는 임베디드 파이어 버드).

내 쿼리가 앞으로 더 복잡해질 것으로 예상되면 데이터베이스 방향으로 향할 것입니다.

로깅에 관한 모든 것이 데이터가 거대하지 않고 뷰의 성능이 좋으면 바이너리 파일을 보존하고 사용자가 databsae 솔루션을 설치하고 유지 관리하는 번거 로움을 피할 수 있습니다. (TDBF는 완전히 정적으로 연결되어 있으므로 예외 일 수 있습니다.)

+0

Marco, Bharat 및 Re0sless 감사합니다. 인터리빙 데이터의 사운드가 마음에 들지만이 비교적 간단한 데이터 로그 파일에는 데이터베이스가 필요하지 않다고 생각합니다. 데이터의 인터리빙을 구현하는 방법을 정확히 모르겠습니다. 나를 명확하게하기 위해 몇 줄의 코드를 작성해 주시겠습니까? 많은 다른 입력뿐만 아니라 감사합니다. – jdsdesign

2

데이터베이스를 사용하면 "파일 이름을 입력하고 많은 데이터 파일을 추적"에서 부분적으로 문제의 이름이 변경되었습니다. ""데이터 세트 이름을 입력하고 많은 데이터 세트를 추적하십시오."

두 경우 모두 사용자 또는 프로그램 중 하나가 새 파일/데이터 세트 이름을 만들고 나중에 열려면 파일/데이터 세트 목록에서 선택해야합니다. 두 경우 모두 "DeleteDataSet"과 같은 함수를 호출 할 수 있습니다.

실제로 데이터베이스가 필요한지 다시 고려할 수 있습니다 (API에 대한 학습 곡선, 데이터 구조를 정의하는 방법, 변경, 뷰어에서 데이터 탐색, 프로그래밍 방식으로 데이터 액세스, 독점 형식, 데이터베이스 유지 관리, 복구 도구, 설치 등) 나는이 모든 것을 배울 수 있고 향후 프로젝트에서 유용 할 수 있다고 확신합니다. , 아마 더 간단한 접근 방식이이 1 회성 프로젝트에 더 적절하고 적절할 것입니다. 비 소프트웨어 엔지니어.

많은 독창적 인 독립형 데이터 파일이 하나의 폴더에 확산되는 경우 데이터 세트 당 하나의 CSV 파일을 사용하는 것이 좋습니다. CSV 파일에 대한 좋은 점 중 하나는 편집자가 파일을 보거나 편집 할 수 있다는 것입니다 (CSV 파일에 대한 속도 또는 크기 문제는 지금까지 하나의 데이터 세트를 포함하고 있었습니까? ...

그런 다음 파일 이름과 기타 설명 정보가 포함 된 두 번째 파일을 추가하십시오. 따라서, TIniFile 델파이에서 사용할 수

[My Name one] 
Date=06 June 2010 
StartTime=12:30pm 
StopTime=3:15pm 
FileName=Data1.csv 
[My Name two] 
... 

도구는 쉽게 그냥 선택하는 사용자에 대한 콤보 상자에 할당 할 수있는 문자열 목록에 ReadSections을 포함하여,이 목록을 관리 할 것입니다 :이 파일은 간단한 따라서, TIniFile 것 데이터 세트. (아래 예제 참조) CSV 파일과 마찬가지로 모든 텍스트 편집기에서 .ini 파일을 편집 할 수 있습니다.

사용자가 데이터 세트 (ini 파일 및 관련 .csv 파일의 섹션)를 삭제할 수 있도록 UI를 작성해야합니다. ini 파일의 사용 방법을 알려면 다음 데이터 세트를 삭제하기위한 의사 코드를 사용하십시오.

(IDE Object Inspector에서 ComboBox.Style : = csDropDownList를 설정하여 사용자가 존재하지 않습니다.)

사용 가능한 데이터 세트를 표시하는 콤보 상자를로드하십시오. 콤보 박스의 onSelect를 이벤트 핸들러에서

1. ComboBox.Items := IniFile.ReadSections; 

:

2. DeleteFile(IniFile.ReadString(CombBox.Text, 'FileName', '')); 
3. IniFile.EraseSection(ComboBox.Text); // remove the section from the inifile 

지옥, 그건 당신이 보호 및 오류 검사의 비트를 추가 한 후에도 코드를 많이 아니에요!

어쩌면 위의 해결책은 둥근 못을 둥근 구멍에 넣거나 바퀴를 다시 발명하려는 시도로 여기에서 다른 사람들이 투표 할 것입니다. 그리고 나는 그들과 동의 할지도 모른다. 많은 파일의 확산을 포함하여이 접근 방식에 대한 좋은 논거가 있습니다. 그러나 그것이 저라면, 적어도이 접근법을 유지하고 단순하고 새로운 것을 요구하지는 않지만 TIniFile 객체를 배울 것이라고 생각합니다. 이것은 상당히 강력합니다.

+0

다른 포스터 앞에 빨간색 플래그를 추가로 웨이브하려면 (!) 파일 확산을 제거하고 데이터 세트 당 너무 많은 데이터 포인트가 없거나 데이터 세트가 너무 많으면 데이터를 저장할 수 있습니다 .ini 파일 섹션 자체가 쉼표로 제한된 문자열로 나타납니다. 그런 다음 하나의 파일 만 : inifile 자체. – RobertFrank

+0

로버트 감사합니다, 나는 실제로 많은 데이터 파일을 가지고 있어도 상관하지 않습니다. 파일을 자동으로 생성하면됩니다. 귀하의 질문에 대답하기 위해 - 아니 나는 속도 또는 크기 문제와 어떤 문제로 실행하지 않았습니다. 나는 아마 단지 신중한 조금이다!! 나는 .ini 파일을 사용하는 것을 좋아합니다. 초보자로서, 나는 Delphi의 많은 기능을 사용한 적이 없으며 TiniFile Object를 포함합니다. 나는 그것에 대해 읽어야 할 것이다. 일부 실행은 1 주일 이상일 수 있고 샘플 속도는 1 초당 판독 값이므로 데이터 세트는 상당히 클 수 있습니다. 따라서 많은 .csv 파일을 생성해야합니다. 다시 한번 감사드립니다. – jdsdesign

+0

1 주일 동안 지속되는 매 순간 포인트를 사용하여 데이터를 작성하는 방법에 대해 생각해보고 지금까지 수집 된 내용이 충돌, 정전 등을 견뎌 낼 수 있도록하십시오. 파일을 디스크로 플러시합니다. 어쩌면 100 점을 저장 한 다음 한 번에 모두 쓸 수 있습니다. – RobertFrank