File
다른 프로그램이 로컬 폴더나 네트워크 폴더의 파일에 쓰는 값(시험기의 CSV, 데이터 로거의 로그, JSON이나 XML로 된 결과)을 태그로 읽고, 다른 프로그램을 위해 줄이나 파일 전체를 씁니다. "폴더와 파일", "파일 텍스트", "쓰기" 카드, 각 형식에서 태그가 읽는 것, 수신 폴더, 열이나 필드마다 태그를 제안하는 스캔, 세 가지 완전한 예, 그리고 드라이버가 하지 않는 일입니다.
File 드라이버는 다른 프로그램이 파일에 쓰는 값을 읽습니다. 시험기가 시료마다 한 줄씩 덧붙이는 CSV, 데이터 로거의 로그, JSON이나 XML로 된 결과 파일, 로트 번호만 들어 있는 텍스트 파일 같은 것입니다. 각 태그는 파일의 값 하나를 읽고, 값은 다른 모든 태그의 값과 같은 곳에 도착합니다. Logic, 대시보드, 그리고 Process 시험대의 실행 기록입니다. 장치가 허용하면 드라이버는 다른 프로그램을 위해 쓰기도 합니다. 파일에 한 줄을 추가하거나 파일 전체를 교체합니다.
주된 용도는 읽기이며, 필요한 답은 세 가지입니다. 폴더, 파일, 그 형식입니다. 파일 텍스트를 읽는 방식(인코딩, 열 구분 기호, 소수점 기호)은 감지로 두면 파일 자체에서 읽어 내고, 스캔이 열이나 필드마다 태그를 제안하며, 모든 태그는 읽기 전용으로 만들어집니다. 쓰기에 관한 것은 장치에서 쓰기를 켠 뒤에만 나타납니다.
이 드라이버의 장치는 폴더 하나와 그 안에서 읽는 파일입니다. 같은 폴더의 파일 두 개는 장치 두 개입니다. 폴더는 드라이브와 폴더(C:\TestMachine\Logs)이거나 네트워크 공유와 그 아래 폴더(\\lab-pc\results)이며, 스테이션은 자신을 실행하는 계정의 Windows 권한으로 접근합니다. 장치는 드라이버 아래에 놓이고 폴더로 정리할 수 있으며, 시리얼 회선도 브로커도 없는 다른 모든 드라이버와 마찬가지로 드라이버 → 폴더 → 장치 → 태그가 됩니다.
드라이버 페이지
머리글 아래 줄에는 "각 장치는 파일 하나, 또는 폴더 하나에 들어오는 파일을 읽습니다. 장치를 추가하고 폴더, 파일, 형식을 입력한 다음 스캔하여 값을 태그로 추가하십시오."라고 적혀 있습니다. Connector 구성 권한이 있으면, 페이지에는 이 드라이버 고유의 스캔 범위 카드가 있어 스캔이 읽을 파일을 담습니다(장치 검색을 보십시오). 그 아래에는 다른 모든 드라이버와 같은 장치 표(장치 표를 보십시오)가 있으며, 제목 오른쪽의 장치 추가로 늘립니다. 비어 있으면 "아직 장치가 없습니다."라고 표시합니다. 드라이버 막대에는 장치 검색이 있으며, 스캔 범위 카드가 다 채워질 때까지 회색입니다. 이 드라이버는 파일과 데이터베이스 아래에 있으며, 드라이버 목록마다 이 범주는 웹과 API와 테스트 사이에 있습니다.
장치
이 드라이버의 장치에는 연결 카드가 없습니다. 그 자리에 폴더와 파일 카드가 있고, 이어서 파일 텍스트 카드가, 파일 하나를 읽는 장치에서는 쓰기 카드가 있습니다. "장치" 카드의 읽기 주기 (ms)는 기본값이 1000이며 태그가 파일을 얼마나 자주 읽는지를 정하고, 다른 모든 드라이버와 마찬가지로 각 태그가 재정의할 수 있습니다.
새 장치에는 폴더가 없습니다. "폴더를 아직 입력하지 않음"이라고 표시하고, 페이지에는 "폴더를 입력하기 전까지 스테이션은 이 장치를 읽지 않으므로, 아직 아무것도 읽지 않고 표시할 오류도 없습니다. 아래 폴더와 파일 카드에 폴더를 입력하면 스테이션이 읽기 시작합니다."라고 표시되며, 폴더를 입력할 때까지 아무것도 읽지 않습니다. 머리글에 보이는 기본 URI는 실행 시 주소로, 폴더와 이름을 URI 형태로 쓰고 그 뒤에 감지가 아닌 설정을 붙입니다. file://single?folder=C%3A%5CTestMachine%5CLogs&name=Log_%7Byyyy-MM-dd%7D.csv&format=delimited이며, 수신 폴더는 file://inbox?...입니다.
"폴더와 파일" 카드
| 필드 | 의미 | 기본값 |
|---|---|---|
| 폴더 경로 | "드라이브와 폴더, 또는 네트워크 공유입니다. 폴더에는 스테이션을 실행하는 계정의 Windows 권한으로 접근합니다." 입력란에는 힌트로 C:\TestMachine\Logs가 표시됩니다. |
비어 있음 |
| 파일 이름 | 파일 하나를 읽는 장치에서: "폴더 안의 이름입니다. 중괄호 안의 부분은 스테이션의 날짜와 시각입니다. Log_.csv는 매일 새 파일입니다." 이름에는 그 폴더의 하위 폴더를 넣을 수 있습니다(results\last.csv). |
비어 있음 |
| 읽을 파일 | 수신 폴더에서의 같은 입력란: "폴더 바로 안에서 읽을 파일입니다. 는 임의의 문자들을, ?는 문자 하나를 뜻합니다. 예: Test_.csv." | 비어 있음 |
| 읽을 곳 | 파일 하나: "파일은 바뀔 때마다 다시 읽습니다. 커지는 파일은 마지막으로 읽은 곳부터 읽습니다." 수신 폴더: "새 파일은 도착한 순서대로 한 번씩 읽은 뒤 하위 폴더 Processed(으)로 옮깁니다. 아무것도 삭제하지 않습니다." | 파일 하나 |
| 파일 형식 | CSV와 열 형식 텍스트, 자유 텍스트, JSON, XML 중 하나: 태그가 파일에서 값을 찾는 방식입니다(태그 주소 지정을 보십시오). | CSV와 열 형식 텍스트 |
날짜 부분이 있는 이름은 중괄호 안에 .NET 날짜와 시각 형식으로 쓰며, 스테이션 자체의 시계를 따릅니다. Log_{yyyy-MM-dd}.csv는 오늘이면 Log_2026-10-03.csv이고 자정이 지나면 다음 날의 파일이 되며, Data_{yyyy-MM}.txt는 매달 바뀝니다. 입력란 아래에 카드는 지금 그것이 어떤 파일인지 보여 줍니다. "오늘: Log_2026-10-03.csv". 겹쳐 쓴 중괄호 {{와 }}는 이름 안의 중괄호입니다. 날짜 부분에는 콜론을 쓰지 않습니다. 파일 이름에 쓸 수 없기 때문입니다. {HH:mm}이 아니라 {HH-mm}으로 씁니다.
장치가 동작하면 카드는 읽고 있는 파일을 알려 줍니다.
| 카드 표시 | 언제 |
|---|---|
| "지금 읽는 파일: Log_2026-10-03.csv" | 사용 중인 파일, 즉 장치가 지금 읽는 파일입니다. |
| "지금 읽는 파일: Log_2026-10-03.csv(아직 없음)" | 파일이 아직 없습니다. 그 태그는 기다리고 장치는 온라인을 유지합니다. |
| "태그가 이 이름을 썼습니다. 다시 시작하면 장치는 설정된 파일을 다시 읽습니다." | 파일 이름을 읽는 태그에 값이 쓰여 장치가 다른 파일을 가리키고 있습니다(쓰기를 보십시오). |
| "수신 폴더에서 파일 3개가 대기 중" | 수신 폴더에 패턴과 맞는, 아직 읽지 않은 파일이 있습니다(하나면 "수신 폴더에서 파일 1개가 대기 중"). |
카드가 받아들일 수 없는 설정은 카드 아래에 표시되며, 고칠 때까지 장치는 저장되지 않습니다.
| 입력한 내용 | 카드 표시 |
|---|---|
전체 경로가 아닌 폴더(Logs 등) |
"폴더는 전체 경로입니다. 드라이브와 폴더(C:\Test), 또는 네트워크 공유와 그 아래 폴더(\server\tests)입니다." |
폴더 이름에 쓸 수 없는 문자가 있는 폴더, 또는 아래에 폴더가 없는 공유(\\server) |
"폴더에 폴더 이름에 쓸 수 없는 문자가 있거나, 아래에 폴더가 없는 네트워크 공유입니다." |
| 파일 이름이 없음 | 거부되지 않습니다. 장치는 저장되어 기다리며, 이름을 입력할 때까지 "파일 이름을 아직 입력하지 않음"(수신 폴더에서는 "읽을 파일을 아직 입력하지 않음")이 나옵니다. |
이름으로 쓴 전체 경로(C:\Logs\last.csv 등) |
"파일 이름은 폴더 안의 이름이지 전체 경로가 아닙니다. 폴더는 폴더 경로 칸에 입력하십시오." |
..가 들어간 이름(..\other\last.csv 등) |
"파일 이름이 ".."로 폴더 밖으로 나갑니다. 드라이버는 폴더 밖으로 나가지 않습니다." |
: 같은 파일 이름에 쓸 수 없는 문자가 있는 이름, 또는 마침표나 공백으로 끝나는 부분 |
"파일 이름에 파일 이름에 쓸 수 없는 문자(: 또는 | 등)가 있거나, 일부가 마침표나 공백으로 끝납니다. 날짜 부분에는 콜론을 쓸 수 없습니다. 대신 을 사용하십시오." |
Windows가 장치용으로 예약한 이름(CON, COM1 등) |
"Windows는 이 이름을 장치용으로 예약해 둡니다(CON, NUL, COM1 등). 다른 이름을 선택하십시오." |
파일 하나를 읽는 장치에서 * 또는 ? |
"* 또는 ?는 수신 폴더의 패턴에만 쓸 수 있습니다. 파일 하나의 이름을 지정하거나, 수신 폴더에서 읽으십시오." |
| 수신 폴더의 패턴에 들어간 하위 폴더 | "수신 폴더는 폴더 자체입니다. 하위 폴더는 폴더 경로 칸에 넣고 여기에는 패턴만 남기십시오." |
| 닫히지 않았거나 날짜 형식이 아닌 날짜 부분 | "이름의 날짜 부분이 닫히지 않았거나 날짜 형식이 아닙니다. Log_.csv처럼 중괄호로 감싸십시오." |
저장도 카드와 같은 규칙을 지키며, 거부할 때는 작업 기록 줄이 그렇게 알립니다. "장치 'Tensile tester'에 드라이버가 사용할 수 없는 파일 설정이 있습니다. 장치를 열어 패널이 표시하는 필드를 고치십시오."
"파일 텍스트" 카드
파일의 문자, 열, 숫자를 읽는 방식입니다. 모든 설정은 파일에서 감지에서 시작하며, 드라이버가 사용 중인 파일에서 읽어 냅니다. 그대로 둔 설정 아래에는, 장치가 파일을 읽은 뒤 찾은 것을 알려 주는 줄이 표시됩니다(예: "파일에서 찾음: UTF-8"). 처음 몇 줄로는 알 수 없는 파일을 위해, 어느 설정이든 골라서 고정할 수 있습니다.
| 필드 | 표시 조건 | 선택지 | 기본값 |
|---|---|---|---|
| 인코딩 | 항상 | 파일에서 감지, UTF-8, Windows-1252 (ANSI)(오래된 Windows 프로그램의 인코딩) |
파일에서 감지 |
| 열 구분 기호 | CSV | 파일에서 감지, 세미콜론(;), 쉼표(,), 탭 | 파일에서 감지 |
| 소수점 기호 | 항상 | 파일에서 감지, 소수점 마침표(12.5), 소수점 쉼표(12,5) | 파일에서 감지 |
| 머리글 행 | CSV | 0에서 1000: "열 이름이 있는 줄이며 1부터 셉니다. 파일에 머리글이 없으면 0입니다." 그 앞의 줄은 건너뜁니다. | 1 |
| 설정 | 감지가 읽는 것 |
|---|---|
| 인코딩 | 파일 앞의 바이트 순서 표시이며, 어떤 선택보다 우선합니다. 없으면 바이트가 올바른 UTF-8일 때 UTF-8, 그렇지 않으면 Windows-1252입니다. |
| 열 구분 기호 | 탭, 세미콜론, 쉼표 가운데 처음 몇 줄을 같은 열 수로 나누는 첫 번째 것입니다. 첫 줄에 그중 어느 것도 없으면 열이 하나인 파일입니다. |
| 소수점 기호 | 파일의 숫자 가운데 숫자 사이에 마침표보다 쉼표가 있는 것이 많으면 쉼표, 그렇지 않으면 마침표입니다. JSON 숫자는 언제나 마침표이며, 이 설정은 텍스트로 쓴 숫자에 적용됩니다. |
"쓰기" 카드
파일 하나를 읽는 장치에는 쓰기 카드가 있습니다. 수신 폴더는 읽기만 하므로 이 카드가 없습니다.
| 필드 | 표시 조건 | 의미 | 기본값 |
|---|---|---|---|
| 쓰기 허용 | 항상 | 꺼짐: "장치는 읽기만 합니다. 줄을 추가하거나, 파일을 교체하거나, 스테이션 실행 중 다른 파일로 바꾸려면 쓰기를 켜십시오." 켜짐: "이 장치의 태그가 파일에 쓸 수 있습니다. 각 태그는 접근 권한을 바꾸기 전까지는 읽기만 합니다." | 꺼짐 |
| 머리글 텍스트 | 쓰기가 켜짐, CSV 또는 자유 텍스트 | "쓰기로 새로 만들어지는 파일의 첫 줄에 씁니다. 예: Time;Pressure." 줄 바꿈 없는 한 줄입니다. | 비어 있음 |
| 줄 끝 | 쓰기가 켜짐 | 파일에서 감지(파일 자신의 것, 새 파일에서는 CR LF), CR LF(Windows 방식) 또는 LF. | 파일에서 감지 |
쓰기는 장치의 어떤 태그도 더 이상 쓰지 않을 때에만 끌 수 있습니다. 아직 쓰는 태그가 있으면 스위치는 그려진 채 회색이 되어 이유를 알려 줍니다. "이 장치의 태그 2개가 파일에 씁니다. 쓰기를 끄기 전에 그 태그들을 읽기 전용으로 바꾸십시오." (하나면 "이 장치의 태그 하나가 파일에 씁니다. 쓰기를 끄기 전에 그 태그를 읽기 전용으로 바꾸십시오.").
온라인, 대기, 오프라인
| 상황 | 장치와 그 태그의 동작 |
|---|---|
| 폴더를 입력하지 않음 | 장치가 기다립니다. "폴더를 아직 입력하지 않음", 회색 점, 아무것도 읽지 않고 오류도 없습니다. |
| 폴더는 입력했지만 파일 이름이 없음 | 장치가 기다립니다. "파일 이름을 아직 입력하지 않음", 회색 점, 아무것도 읽지 않고 오류도 없습니다. 페이지에는 "파일 이름을 입력하기 전까지 스테이션은 이 장치를 읽지 않으므로, 아직 아무것도 읽지 않고 표시할 오류도 없습니다. 아래 폴더와 파일 카드에 파일 이름을 입력하면 스테이션이 읽기 시작합니다."라고 표시됩니다. |
| 수신 폴더에서 폴더는 입력했지만 읽을 파일이 없음 | 장치가 기다립니다. "읽을 파일을 아직 입력하지 않음", 회색 점, 아무것도 읽지 않고 오류도 없습니다. 페이지에는 "읽을 파일을 입력하기 전까지 스테이션은 이 장치를 읽지 않으므로, 아직 아무것도 읽지 않고 표시할 오류도 없습니다. 아래 폴더와 파일 카드의 읽을 파일에 입력하면(예: Test_*.csv) 스테이션이 읽기 시작합니다."라고 표시됩니다. |
| 폴더에 접근할 수 없음(멈춘 공유, 사라진 드라이브, 접근 권한이 없는 계정) | 장치는 오프라인이 되고 태그는 읽기에 실패합니다. 폴더는 최대 1초마다 다시 확인하며, 돌아오면 장치가 바로 연결됩니다. |
| 폴더에는 접근할 수 있지만 파일이 아직 없음 | 장치는 온라인을 유지합니다. 값을 읽는 태그는 읽은 값 없이 기다리고, 파일 존재 여부는 거짓을 읽습니다. |
| 다른 프로그램이 파일을 공유하지 않고 잡고 있음 | 이번에는 읽지 않고 다음 읽기에서 다시 시도합니다. 태그는 마지막 읽은 값을 유지하며, 읽기 주기에 10초를 더한 것보다 오래된 값은 다른 모든 드라이버와 마찬가지로 읽기 실패로 셉니다. |
| 값이 없거나 태그 형식에 맞지 않음 | 그 태그의 읽기 실패이며 이유가 붙습니다. 장치는 다른 태그를 계속 읽습니다. |
태그 주소 지정
태그가 읽는 것
이 드라이버의 태그에는 자신의 주소 입력란이 없습니다. 신호원 카드가 무엇을 읽는지 묻고, 값이라면 장치 형식에서 값이 어디 있는지 묻습니다.
| 읽는 내용 | 태그가 보여 주는 것 | 데이터 형식 |
|---|---|---|
| 값 | 파일 안의 값이며, 아래에 있는 장치 형식의 필드로 찾습니다. | Boolean, Int32, Int64, Float, Double, String. 새 태그는 Double |
| 파일 전체 | 끝의 줄 끝을 뺀 전체 내용입니다. 로트 번호나 상태만 들어 있는 파일입니다. 최대 4 MiB. | 같음. 새 태그는 String |
| 파일 존재 여부 | 사용 중인 파일이 지금 있는지 여부. | Boolean |
| 파일 크기 | 파일의 바이트 수. | Int64 |
| 마지막 변경 | 파일이 마지막으로 쓰인 시각. 이것이 바뀌는 것으로 Logic은 새 데이터가 도착했음을 압니다. | DateTime |
| 파일 이름 | 폴더 안에서 사용 중인 파일의 이름. 쓰면 다른 파일을 지정합니다(쓰기를 보십시오). | String |
| 줄 수 | "머리글 행과 빈 줄을 포함해 파일의 모든 줄을 셉니다." | Int64 |
신호원이 읽을 수 없는 형식은 읽을 수 있는 형식을 알려 주며 거부됩니다. "이 값을 읽을 수 있는 데이터 형식 중 하나를 선택하십시오: Int64." 다른 신호원을 고르면 그 형식이 따라옵니다. 파일에서 꺼낸 텍스트는 Generic serial and TCP 드라이버가 메시지를 읽는 것과 같은 방식으로 태그 형식으로 읽으며, 파일의 소수점 기호를 씁니다. Boolean은 1, true, on, yes와 0, false, off, no를 읽고, 정수는 정수를 읽으며, String은 문자를 있는 그대로 받으므로 0412 같은 코드는 String일 때만 앞의 0을 유지합니다.
모든 태그는 읽기 전용으로 만들어지며, 쓰기를 허용하지 않는 장치에서는 접근 필드가 다른 것을 제시하지 않습니다. 장치가 쓰기를 허용하면 값이나 파일 전체를 읽는 태그는 읽기와 쓰기나 쓰기 전용이 될 수 있고, 파일 이름을 읽는 태그는 읽기와 쓰기가 될 수 있습니다. 파일 정보(존재 여부, 크기, 마지막 변경, 줄 수)는 절대 쓰지 않습니다. "파일 정보에는 쓸 수 없습니다. 태그를 읽기 전용으로 두십시오."
CSV와 열 형식 텍스트
| 필드 | 표시 조건 | 의미 | 기본값 |
|---|---|---|---|
| 열 | 값을 읽음 | "머리글 행에 있는 열 이름, 또는 1부터 센 열 번호입니다." 숫자로만 된 텍스트는 번호이며, 이름은 대소문자와 앞뒤 공백을 구분하지 않습니다. 머리글 행이 없는 파일에서는: "1부터 센 열 번호입니다. 이 파일에는 머리글 행이 없어 열에 이름이 없습니다." | 비어 있음 |
| 읽을 행 | 값을 읽음 | 마지막, 번호로, 내용으로. "행은 머리글 행 다음부터 셉니다. 내용으로를 고르면 키 열에 키 값이 들어 있는 마지막 행을 읽습니다." | 마지막 |
| 행 번호 | 번호로 | 머리글 다음부터 1로 센 데이터 행. | 비어 있음 |
| 키 열 | 내용으로 | 그 값으로 행을 고르는 열이며, 이름이나 번호로 지정합니다. | 비어 있음 |
| 키 값 | 내용으로 | 읽을 행에서 키 열이 가진 값(0412 등). |
비어 있음 |
큰따옴표로 감싼 필드는 구분 기호를 담을 수 있습니다. 줄 바꿈이 들어 있는 필드는 읽지 않습니다. 필드가 성립하지 않는 태그는 저장되지 않으며, 페이지에 무엇이 빠졌는지 표시됩니다.
| 비워 두거나 입력한 내용 | 태그 페이지 표시 |
|---|---|
| 열이 없음 | "머리글 행의 열 이름이나 열 번호로 열을 입력하십시오." |
| 열 0 | "열은 1부터 셉니다." |
| 머리글 행이 없는 파일에서 이름으로 지정한 열 | "이 파일에는 머리글 행이 없으므로 열은 번호로 지정합니다." |
| 번호로, 행 번호 없이 | "1부터 센 번호를 입력하십시오." |
| 내용으로, 키 열 없이 | "키 열을 입력하십시오. 그 열의 값으로 행을 고릅니다." |
| 내용으로, 키 값 없이 | "행 또는 줄에 들어 있는 내용을 입력하십시오." |
읽기 전용인 신호원 주소 (버스) 줄은 드라이버가 받는 것을 보여 줍니다. column?name=Force는 마지막 행의 Force, column?number=3&row=number&rowNumber=5는 다섯째 행의 셋째 열, column?name=Force&row=match&key=Sample&equals=0412는 시료 0412의 행입니다.
자유 텍스트
| 필드 | 표시 조건 | 의미 | 기본값 |
|---|---|---|---|
| 읽을 줄 | 값을 읽음 | 마지막(비어 있지 않은 마지막 줄), 번호로, 내용으로. "줄은 파일 처음부터 셉니다. 내용으로를 고르면 그 텍스트가 들어 있는 마지막 줄을 읽습니다." | 마지막 |
| 줄 번호 | 번호로 | 파일 처음부터 1로 센 줄. | 비어 있음 |
| 줄에 포함된 텍스트 | 내용으로 | 읽을 줄에 들어 있는 텍스트(Result 등). |
비어 있음 |
| 값을 꺼내는 방식 | 값을 읽음 | "Generic serial and TCP 드라이버와 같은 선택지입니다. 줄 전체, 고정 위치, 구분 기호 사이의 필드, 또는 정규식입니다." 선택지는 그 드라이버와 같고, 첫 선택지만 줄에 맞춘 이름입니다. 줄 전체, 고정 위치(첫 문자와 길이), 구분 문자 사이의 필드(구분 문자와 필드 번호), 패턴의 캡처 그룹(패턴)입니다. | 줄 전체 |
위치와 필드는 1부터 세고, 패턴은 값을 감싸는 캡처 그룹이 정확히 하나인 .NET 정규식이며, 읽는 데 250 ms보다 오래 걸리는 줄은 읽지 않습니다. 거부는 범용 드라이버 자신의 것으로, 예를 들면 "값의 첫 문자 위치를 1부터 세어 넣으십시오." 또는 "패턴에는 값을 감싸는 캡처 그룹이 정확히 하나 있어야 합니다."입니다. 버스 주소는 line 뒤에 해당하는 것을 붙여 씁니다. 예: line?row=match&contains=Result&extract=regex&pattern=....
JSON과 XML
| 필드 | 형식 | 의미 |
|---|---|---|
| JSON 경로 | JSON | "멤버는 점으로 구분하고 위치는 0부터 대괄호에 씁니다. 예: result.force, items[0].value." 이름에 점이 있는 멤버는 ['flow.rate']로 씁니다. |
| XML 경로 | XML | "루트부터의 요소를 슬래시로 구분하고, 요소가 반복되는 곳에는 1부터의 위치를, 마지막에는 속성을 씁니다. 예: Result/Force, Result/@unit." 이름은 로컬 이름으로 맞추며 네임스페이스 접두사는 무시합니다. |
JSON 숫자, true, false는 그대로 받고, 문자열은 태그 형식으로 읽습니다. 객체나 목록은 String으로, 그 JSON만 읽을 수 있습니다. JSON이나 XML 문서는 바뀌었을 때 전체를 읽으며, 최대 4 MiB이고, DTD는 읽지 않습니다. 버스 주소는 json?path=result.force 또는 xml?path=Result%2FForce입니다.
| 비워 두거나 입력한 내용 | 태그 페이지 표시 |
|---|---|
| 경로가 없음 | "값까지의 경로를 입력하십시오. 파일 전체를 읽으려면 파일 전체를 선택하십시오." |
| 해석할 수 없는 JSON 경로 | "JSON 경로가 아닙니다. 멤버는 점으로 구분하고 위치는 대괄호에 씁니다. 예: result.items[0].value." |
| 해석할 수 없는 XML 경로 | "XML 경로가 아닙니다. 요소는 슬래시로 구분하고, Item[2]처럼 위치를 쓰고, 마지막에 @unit 같은 속성을 씁니다." |
읽기
읽을 때마다 드라이버는 Windows에 파일의 크기와 시각을 묻습니다. 이 방법은 Windows의 변경 알림이 작동하지 않는 네트워크 공유에서도 통하며, 그중 하나라도 바뀌었을 때에만 파일을 엽니다. 열 때는 언제나 읽기, 쓰기, 삭제 공유를 허용하므로 파일을 쓰는 프로그램이 막히는 일은 없습니다.
| 파일 | 읽기의 동작 |
|---|---|
| 커졌고, 앞과 끝이 예전 그대로임 | 추가된 부분만 읽으며 파일 전체를 다시 읽지 않습니다. 수 메가바이트의 로그도 새 줄만큼만 비용이 듭니다. |
| 짧아졌거나, 다시 쓰였거나, 다시 만들어짐 | 처음부터 다시 읽습니다. |
| 아직 줄 끝으로 닫히지 않은 줄로 끝남 | 그 줄은 기다립니다. 반쯤 쓰인 값을 읽지 않기 위해서입니다. 파일이 2초 동안 바뀌지 않으면 마지막 줄로 읽습니다. |
| JSON, XML, 또는 파일 전체를 읽는 태그 | 바뀌었을 때 전체를 읽으며 최대 4 MiB입니다. 해석할 수 없고 바뀐 지 2초가 안 된 문서는 아직 쓰는 중으로 보고 태그는 기다립니다. |
| 1 MiB를 넘는 줄이 있음 | 줄 단위 텍스트가 아닙니다. 그 태그는 읽기에 실패합니다. |
모든 읽은 값에는 읽은 시각이 아니라 파일의 마지막 변경 시각이 붙으므로, 실행 기록은 다른 프로그램이 시료를 쓴 시각에 그 시료를 놓습니다.
수신 폴더
읽을 곳을 수신 폴더로 하는 것은 시료마다 파일 하나(Test_0412.json, Test_0413.json...)를 쓰는 기계를 위한 것입니다. 패턴과 맞는 새 파일은 각각 도착한 순서대로 한 번만 읽습니다.
| 단계 | 일어나는 일 |
|---|---|
| 파일이 도착함 | 1초 동안 크기와 시각이 그대로이고, 쓰기 위해 파일을 열어 둔 프로그램이 없을 때 가져옵니다. |
| 무엇부터 | 먼저 만들어진 것, 다음으로 먼저 쓰인 것, 그다음 이름순입니다. 함께 도착한 두 파일은 두 번에 나누어 읽으며, 건너뛰는 것은 없습니다. |
| 그 읽은 값 | 장치의 모든 태그가 그 파일을 읽고, 파일 하나가 읽은 값 하나가 되며 파일의 시각이 붙습니다. 실행 기록은 각각을 기록합니다. 파일 이름은 값이 어느 파일에서 왔는지 알려 줍니다. |
| 모든 태그가 읽은 뒤 | 하위 폴더 Processed로 옮깁니다. 이 폴더는 드라이버가 만들며, 다른 프로그램이 찾을 수 있으므로 이름은 모든 언어에서 같습니다. 거기에 같은 이름이 이미 있으면 name (2).json이 됩니다. 다음 파일까지는 그 값이 태그의 읽은 값으로 남습니다. |
| 옮기기에 실패함 | 읽을 때마다 다시 시도합니다. 그동안 파일을 다시 읽지는 않습니다. |
| 옮기기 전에 스테이션이 다시 시작됨 | 파일을 다시 읽습니다. 읽은 값 하나를 잃기보다 두 번 세는 쪽을 택합니다. |
아무것도 삭제하지 않습니다. 하위 폴더 Processed는 누군가 비울 때까지 커집니다. 수신 폴더에는 절대 쓰지 않습니다.
쓰기
파일 하나를 읽고 쓰기를 허용하는 장치에서, 값이나 파일 전체를 읽고 접근 권한으로 쓰는 태그는 쓰기가 무엇을 하는지 정합니다.
| 필드 | 표시 조건 | 의미 | 기본값 |
|---|---|---|---|
| 쓰기 동작 | 태그가 씀 | 줄 추가: "파일 끝에 줄 하나를 추가합니다. 모든 쓰기가 반영되며, 더 새로운 쓰기 때문에 버려지는 것은 없습니다." 파일 교체: "임시 파일을 거쳐 파일 전체를 값으로 교체하므로, 다른 프로그램이 반쯤 쓰인 파일을 읽지 않습니다." | 줄 추가 |
| 줄 템플릿 | 줄 추가 | "비워 두면 쓴 값이 그대로 한 줄이 됩니다. 는 값, 은 쓴 시각이며, 필요하면 콜론 뒤에 형식을 붙입니다. 예: ." 입력란에는 힌트로 {datetime};{value}가 표시됩니다. |
비어 있음 |
| 템플릿 | 12.5를 쓰면 추가되는 줄 |
|---|---|
| 비어 있음 | 12.5 |
{datetime};{value} |
2026-10-03 14:05:12;12.5 |
{datetime:dd/MM/yyyy HH:mm};{value:0.00} |
03/10/2026 14:05;12.50 |
{value:FORMAT}은 .NET 숫자 형식을, {datetime:FORMAT}은 .NET 날짜와 시각 형식을 받으며 스테이션의 시계를 쓰고, 지정이 없으면 yyyy-MM-dd HH:mm:ss입니다. 숫자는 파일의 소수점 기호로 쓰므로, 같은 템플릿이라도 쉼표를 쓰는 파일에는 12,50으로 씁니다. Boolean 태그의 템플릿은 {value}를 생략할 수 있으며, 참을 쓰면 명령처럼 줄을 추가합니다. 드라이버가 채울 수 없는 템플릿은 태그 페이지에서 거부됩니다.
| 입력한 내용 | 태그 페이지 표시 |
|---|---|
{value}도 {datetime}도 아닌 부분, 또는 닫히지 않은 중괄호 |
"템플릿에는 와 을 쓸 수 있으며, 필요하면 콜론 뒤에 형식을 붙입니다. {{와 }}는 줄에 쓰는 중괄호입니다." |
Boolean이 아닌 태그에서 {value}가 없음 |
"템플릿에 가 없어서 쓴 값이 파일에 도달하지 않습니다. 생략할 수 있는 것은 불리언 태그뿐이며, 참을 쓰면 줄을 추가합니다." |
| 줄 바꿈 | "템플릿은 줄 바꿈 없는 한 줄입니다." |
| 쓰기를 허용하지 않는 장치에서 쓰는 태그 | "장치가 쓰기를 허용하지 않습니다. 장치에서 쓰기를 켜거나 태그를 읽기 전용으로 두십시오." |
| 쓰기 | 진행 방식 |
|---|---|
| 줄 추가 | 줄은 한 번의 쓰기로 보내지고, 쓰기가 완료로 세어지기 전에 디스크에 플러시됩니다. 쓰기로 만들어지는 파일에는 먼저 머리글 텍스트가 쓰이고, 마지막 줄에 줄 끝이 없는 파일에는 먼저 줄 끝을 붙여 줄이 온전하도록 합니다. 줄 바꿈이 들어 있는 값은 거부됩니다. 모든 쓰기가 반영됩니다. 장치의 대기열에서 기다리는 쓰기는 같은 태그로 가는 더 새로운 쓰기 때문에 버려지지 않으며, 명령이 버려지지 않는 것과 같습니다. |
| 파일 교체 | 값은 파일 옆의 임시 파일에 쓰이고 플러시된 뒤, 한 번에 파일의 자리를 차지합니다. 아직 기다리는 더 새로운 값은 오래된 값을 대체하며, 다른 설정값과 같습니다. |
| 파일 이름 | 파일 이름을 읽는 읽기와 쓰기 태그에 다른 이름을 쓰면, 그때부터 장치는 같은 폴더의 그 파일을 가리킵니다. "여기에 이름을 쓰면 그때부터 장치는 같은 폴더의 그 파일을 읽고 씁니다. 폴더 밖의 이름은 거부됩니다." 전체 경로, .., :, Windows가 예약한 이름은 거부됩니다. 장치가 다시 연결되면(다시 시작 포함) 설정된 파일을 다시 읽습니다. |
| 텍스트 | 파일 자신의 인코딩, 줄 끝, 소수점 기호로 쓰며, 장치가 감지로 둔 것은 파일에서 읽어 냅니다. 새 파일은 장치가 따로 정하지 않는 한 바이트 순서 표시가 없는 UTF-8, CR LF, 소수점 마침표입니다. |
| 응답 | 완료, 또는 원인이 붙은 거부입니다. 장치가 쓰기를 허용하지 않음, 계정에 권한이 없음, 파일에 읽기 전용 특성이 설정됨(그 특성을 해제하면 다음 쓰기가 이루어짐), 디스크가 가득 참, 파일이 다른 프로그램에서 열려 있음 가운데 하나입니다. 파일 교체는 어떤 프로그램이든 파일을 열고 있는 동안 거부되고, 줄 추가는 공유하지 않는 프로그램이 파일을 잡고 있을 때만 거부됩니다. 그 프로그램이 파일을 닫으면 다음 쓰기가 이루어집니다. |
이름이 가리키는 폴더와 하위 폴더는 쓰기에 필요할 때 만들어지며, 언제나 장치의 폴더 안에 있습니다.
장치 검색
"스캔 범위" 카드
Connector 구성 권한이 있으면 드라이버 페이지에 스캔 범위 카드가 있으며, 그 아래 줄은 "파일 하나를 읽어 찾은 열이나 필드마다, 그리고 파일 정보마다 태그를 제안합니다. 장치를 골라 그 파일을 읽거나, 폴더, 파일, 형식을 입력하십시오."입니다.
| 필드 | 의미 | 기본값 |
|---|---|---|
| 스캔할 파일 | 여기에 입력한 파일, 또는 이름으로 고르는 이 드라이버의 장치. 장치의 파일은 저장된 장치 설정으로 읽으며, 아직 저장을 기다리는 장치 편집은 먼저 저장합니다. | 여기에 입력한 파일 |
| 폴더 경로 | 입력한 파일: 폴더이며, 장치와 같습니다. | 비어 있음 |
| 파일 이름 또는 읽을 파일 | 입력한 파일: 이름, 또는 수신 폴더의 패턴. | 비어 있음 |
| 읽을 곳 | 입력한 파일: 파일 하나 또는 수신 폴더. | 파일 하나 |
| 파일 형식 | 입력한 파일: 형식. 입력한 파일의 텍스트 설정은 머리글 행까지 모두 감지합니다. 첫 줄의 어떤 필드도 숫자가 아니고 다음 줄에 숫자가 있으면 첫 줄이 머리글입니다. | CSV와 열 형식 텍스트 |
범위에 아직 빠진 것은 카드 아래에 빨간 글씨로 표시되며, 다 채워질 때까지 장치 검색은 회색으로 남습니다.
| 범위 | 카드 표시 |
|---|---|
| 폴더가 없는 입력한 파일 | "파일이 있는 폴더를 입력하십시오." |
| 전체 경로가 아닌 입력한 폴더 | "'Logs'은(는) 이 스테이션이 읽을 수 있는 폴더가 아닙니다. C:\Test 또는 \server\tests 같은 전체 경로를 쓰십시오." |
| 폴더의 파일이 아닌 입력한 이름 | "'..\last.csv'은(는) 폴더 안 파일의 이름이 아닙니다." |
| 더 이상 없는 장치 | "스캔하려고 고른 장치가 더 이상 없습니다. 스캔할 다른 파일을 고르십시오." |
| 폴더나 파일이 없는 장치 | "장치 'Tensile tester'에 아직 폴더나 파일이 없거나, 드라이버가 사용할 수 없는 설정이 있습니다. 먼저 폴더와 파일 카드를 채우십시오." |
스캔할 장치에 저장할 수 없는 편집이 있으면 스캔은 시작되지 않습니다. "스캔할 장치의 편집을 저장하지 못해 장치 검색을 시작하지 않았습니다."
스캔이 제시하는 것
스캔은 파일 하나를 읽는 장치가 지금 읽는 파일, 또는 수신 폴더의 가장 새 파일을 읽습니다(그 파일은 옮기지 않습니다). 파일이 없거나, 폴더에 접근할 수 없거나, 문서를 해석할 수 없으면 스캔은 이유를 붙여 끝납니다. 후보 하나를 제시하며, 찾은 값을 후보 태그로 삼고 모두 읽기 전용입니다.
| 형식 | 후보 태그 |
|---|---|
| CSV | 열마다 하나이며 마지막 행을 읽고, 머리글로 이름을 붙입니다(머리글이 이름을 주지 않거나 같은 이름을 두 번 주는 곳은 번호로). 형식은 처음 몇 행의 값으로 정합니다. 모두 숫자면 Double, 모두 true나 false면 Boolean, 그 밖에는 String입니다. 0412처럼 앞에 0이 있는 코드는 String으로 남습니다. |
| 자유 텍스트 | 마지막 줄이며 String입니다. |
| JSON, XML | 값마다 하나이며 경로로 이름과 주소를 붙이고, 최대 500개입니다. JSON 목록은 처음 20개 항목을 제시하고, 8단계 깊이까지 탐색합니다. |
| 모든 형식 | 파일 정보: 파일 존재 여부, 파일 크기, 마지막 변경, 파일 이름, 줄 수. |
스캔은 CSV 파일의 열을 포함해 값을 최대 500개 제시하며, 거기서 잘린 스캔은 스캔을 마치는 줄과 결과 위에서 "result.json의 스캔이 일찍 멈췄습니다. 스캔은 값을 최대 500개 제시합니다. 나머지는 열, JSON 경로 또는 XML 경로를 지정해 태그로 추가하십시오."라고 알려 줍니다.
입력한 파일의 후보는 파일 이름을 따르고(run.csv이면 run), 날짜 부분이 있는 이름이나 수신 폴더는 폴더 이름을 따릅니다. 폴더, 이름, 읽을 곳을 이 드라이버의 장치가 이미 읽고 있는 후보(스캔한 장치, 또는 같은 다른 장치)는 이미 설정됨으로 표시됩니다. 그 카드에는 그 장치의 어떤 태그도 아직 읽지 않는 값만 체크된 채 나열되며, 열기 앞에 있는 태그로 추가가 체크한 것을 읽기 전용으로 그 장치에 추가합니다. 스캔의 나머지 동작은 장치 검색에 있습니다.
장치 자신의 페이지도 드라이버 페이지 없이 같은 일을 합니다. 태그 카드 머리의 태그 검색은 그 장치의 파일을 저장된 그대로 읽고, 아직 태그가 없는 값만 제시합니다(장치의 태그 검색 참고).
예: 시험기의 일일 CSV
인장 시험기가 매일 CSV 하나를 C:\TestMachine\Logs에 씁니다. 이름은 Log_2026-10-03.csv이고, 머리글 행은 Sample;Force;Elongation이며, 시료마다 0412;12,5;3,1 같은 행을 씁니다. 간단한 경로로 읽습니다.
- 드라이버 페이지에서 장치 추가를 누르고 이름을
Tensile tester로 합니다. - 폴더와 파일 카드에서 폴더 경로에
C:\TestMachine\Logs, 파일 이름에Log_{yyyy-MM-dd}.csv를 입력하고, 파일 하나와 CSV와 열 형식 텍스트는 그대로 둡니다. 카드는 "오늘: Log_2026-10-03.csv"를 표시하고, 장치가 그 파일을 읽으면 "지금 읽는 파일: Log_2026-10-03.csv"를 표시합니다. 파일 텍스트 카드는 파일에서 감지로 둡니다. 세미콜론과 소수점 쉼표를 찾아냅니다. - 드라이버 페이지의 스캔할 파일에서
Tensile tester를 고르고 장치 검색을 누릅니다. 후보는 이미 설정됨이며Sample(String이라0412의 0을 유지),Force와Elongation(Double), 그리고 파일 정보를 나열합니다. 태그로 추가를 누릅니다.
각 태그는 마지막 행을 읽습니다. 마지막 변경은 새 시료마다 바뀌며, Logic의 동작은 이것으로 시료가 도착했음을 압니다. 자정에 장치는 다음 날의 파일로 넘어가며, 시험기가 그 파일을 쓸 때까지 값에는 읽은 값이 없고 파일 존재 여부는 거짓을 읽습니다. 에이전트도 도구로 같은 일을 합니다.
device_upsert name="Tensile tester" driver=File fileFolder="C:\TestMachine\Logs" fileName="Log_{yyyy-MM-dd}.csv" fileFormat=Delimited
device_discover driver=File fileDevice="Tensile tester"
tag_upsert device="Tensile tester" name=Force address=Force opcUaType=Double
tag_upsert device="Tensile tester" name=Sample address=Sample opcUaType=String
tag_upsert device="Tensile tester" name="Last change" fileSource=Modified
예: JSON 결과 파일의 수신 폴더
시험 셀이 시료마다 결과 파일 하나를 C:\Results\Inbox에 둡니다. 예를 들어 {"sample":"0413","result":{"force":12.5,"ok":true}}가 들어 있는 Test_0413.json입니다.
- 장치 추가를 누르고 이름을
Results, 폴더 경로를C:\Results\Inbox, 읽을 곳을 수신 폴더, 읽을 파일을Test_*.json, 파일 형식을 JSON으로 합니다. - 태그 추가로
Force, JSON 경로result.force, Double. 태그 추가로Pass, JSON 경로result.ok, Boolean. 태그 추가로Sample, JSON 경로sample, String. - 태그 추가로
Source file, 읽는 내용은 파일 이름입니다. 값이 어느 파일에서 왔는지 보여 줍니다.
각 파일은 1초 동안 그대로 있고 쓰기 위해 열어 둔 프로그램이 없어진 뒤, 도착한 순서대로 한 번만 읽습니다. 각각이 독립된 읽은 값이며 파일의 시각이 붙습니다. 모든 태그가 읽으면 C:\Results\Inbox\Processed로 옮겨집니다. 아무것도 삭제하지 않습니다. 도구로는 다음과 같습니다.
device_upsert name=Results driver=File fileFolder="C:\Results\Inbox" fileName="Test_*.json" fileMode=Inbox fileFormat=Json
tag_upsert device=Results name=Force address=result.force opcUaType=Double
tag_upsert device=Results name=Pass address=result.ok opcUaType=Boolean
tag_upsert device=Results name=Sample address=sample opcUaType=String
tag_upsert device=Results name="Source file" fileSource=Name
예: 다른 프로그램을 위해 줄 하나 추가하기
다른 프로그램이 D:\Records\run.csv를 읽습니다. 1초에 한 줄이며, 시각과 압력이 들어 있습니다.
- 장치 추가를 누르고 이름을
Run log, 폴더 경로를D:\Records, 파일 이름을run.csv로 합니다. - 쓰기 카드에서 쓰기 허용을 켜고 머리글 텍스트에
Time;Pressure를 입력합니다. - 태그 추가로
Line, Double, 접근은 쓰기 전용, 쓰기 동작은 줄 추가, 줄 템플릿은{datetime};{value:0.00}으로 합니다.
Line에 12.5를 쓰면 2026-10-03 14:05:12;12.50을 추가하며, 파일이 이미 쉼표를 쓰거나 소수점 기호가 소수점 쉼표(12,5)이면 쉼표를 씁니다. 쓰기로 만들어지는 파일에는 먼저 Time;Pressure가 쓰입니다. 빠르게 이어지는 쓰기도 모두 순서대로 남습니다. 실행마다 파일 하나를 쓰려면 File 태그를 추가하고, 읽는 내용을 파일 이름, 읽기와 쓰기로 합니다. 실행이 시작되면 Logic이 일련번호에 .csv를 붙여 쓰고, 줄은 그 파일로 갑니다. 도구로는 다음과 같습니다.
device_upsert name="Run log" driver=File fileFolder="D:\Records" fileName=run.csv fileFormat=Delimited fileWrites=true fileHeaderText="Time;Pressure"
tag_upsert device="Run log" name=Line opcUaType=Double accessType=WriteOnly fileWriteMode=AppendLine fileLineTemplate="{datetime};{value:0.00}"
tag_upsert device="Run log" name=File fileSource=Name accessType=ReadAndWrite
에이전트 도구
driver_capabilities는 이 드라이버를 file 아래에서 설명합니다. 간단한 경로, 장치의 각 필드, 폴더 규칙과 그 폴더 안에서만 움직이는 제한, 파일 이름의 형태, 두 가지 읽는 방식, 형식과 각각의 주소 문법, 신호원과 그 형식, 텍스트 설정, 읽기와 쓰기의 동작, 장치 검색, 그리고 세 가지 완전한 예입니다. device_upsert driver=File은 fileFolder, fileName, fileMode(기본값 SingleFile 또는 Inbox), fileFormat(기본값 Delimited, Text, Json, Xml), fileEncoding(Automatic, Utf8, Windows1252), fileSeparator(Automatic, Semicolon, Comma, Tab), fileDecimal(Automatic, Point, Comma), fileHeaderRow(0에서 1000), fileWrites, 그리고 쓰기가 켜져 있으면 fileHeaderText와 fileLineEnd(Automatic, CrLf, Lf)를 받습니다. 돌려주는 장치에는 file이 있으며, 그 안의 fileStatus는 동작 중인 드라이버가 찾은 것입니다. 사용 중인 파일, 그 파일이 있는지, 읽어 낸 인코딩, 구분 기호, 줄 끝, 그리고 수신 폴더에서 기다리는 파일입니다. tag_upsert는 fileSource(Value, WholeFile, Exists, Size, Modified, Name, Lines), fileRow(Last, Number, Matching), fileRowNumber, fileKeyColumn, fileMatchText, fileWriteMode(AppendLine 또는 ReplaceFile), fileLineTemplate을 받습니다. 열이나 경로는 address이고, 자유 텍스트의 값은 범용 드라이버의 valueExtraction, valueStart, valueLength, valueSeparator, valueField, valuePattern을 쓰며, 새 태그는 읽기 전용이고 opcUaType으로 따로 정하지 않으면 신호원 자신의 형식이 됩니다. device_discover driver=File은 이 드라이버 장치의 이름인 fileDevice, 또는 스캔을 위해 입력한 fileFolder, fileName, fileMode, fileFormat을 읽습니다. 설정된 장치에 없는 태그는 tag_upsert로 추가합니다. connector_browse는 장치마다 fileFolder, fileName, fileMode, fileFormat을 돌려줍니다. 다른 도구는 에이전트 도구에 있습니다.
알아 둘 한계
- Excel 통합 문서는 읽지 않습니다. 통합 문서는 그 프로그램이 CSV로 저장한 뒤에 읽습니다.
- 드라이버는 파일을 삭제하지 않습니다. 수신 폴더는 읽은 것을
Processed로 옮기며, 지우는 것은 실패한 교체의 임시 파일뿐입니다. - "폴더에서 가장 새 파일"은 읽는 방식이 아닙니다. 함께 도착한 파일을 놓치고 이전 시료의 값을 보여 줄 수 있기 때문입니다. 시료마다 파일 하나를 쓰는 기계는 수신 폴더로 읽습니다.
- 파일 안의 값을 그 자리에서 바꾸지 않습니다(CSV의 셀, 다른 프로그램의 JSON 멤버). 쓰기는 줄을 추가하거나 파일 전체를 교체하는데, 두 프로그램이 같은 파일에 쓰면 서로의 변경을 잃을 수 있기 때문입니다.
- 네트워크 공유에는 스테이션을 실행하는 계정의 Windows 권한으로 접근합니다. 장치는 사용자도 비밀번호도 저장하지 않으므로, 공유가 그 계정을 받아들여야 합니다(읽기, 그리고 쓰는 장치나 수신 폴더에서는 쓰기와 옮기기도).
- 드라이버는 자기 폴더 밖의 어떤 것도 건드리지 않습니다. 다른 곳을 가리키는 이름은 입력할 때와 쓸 때 모두 거부됩니다.
- 파일은 읽을 때마다 확인합니다. 변경은 다음 읽기에서 보이며, 다른 프로그램이 쓰는 그 순간에는 보이지 않습니다.
- 줄 바꿈이 들어 있는 CSV 필드는 읽지 않으며, JSON, XML, 파일 전체 태그가 읽는 것은 최대 4 MiB입니다.