C# Log Write 와 Read

안녕하세요!!
네 직장인 2년차 뉴비입니다, 선배님들 잘 부탁드립니다! ^–^
저는 제조업 회사에 재직중이며 C# 을 활용해 물류 이동이나 상태표시 등 간단한(?) 작업을 하고 있습니다.
그리고 프로그램에서는 Timer 를 통해 물류 관련 항목을 Logging 작업으로 엑셀에 저장하고 있습니다.

  • 무엇을 하고자 하는지

프로그램에서 Logging 작업을 하면서 작업자가 해당 Excel 파일을 간섭없이 열람하고 싶습니다.

  • 현재 작성한 코드 중 문제가 되는 부분

기존 코드
using (swSave = new StreamWriter(strFilePath, true, Encoding.UTF8))
{
swSave.WriteLine(strBld);
}

  • using 문을 활용해 swSave(StreamWriter) 를 생성하여 경로(strFilePath) 에 데이터(strBld) 를 Write 합니다.

  • 하지만 작업자가 Excel 파일을 Open 한다면, 매초 swSave 가 생성될 때, 해당 경로 파일이 이미 열려 있으므로 IOException 발생 → 발생 시간동안 Log Data 누락

  • 기대하는 동작

대안 1. Excel 파일 속성을 읽기전용으로 설정한다.
정말 1차원적인 생각이였습니다… 읽기전용으로 하니 swSave 를 생성할 때, 해당 경로 파일 접근이 불가했습니다.

대안 2. FileStream 속성을 지정한다.
FileStream fsSave = new FileStream(strFilePath, FileMode.Append, FileAccess.Write, FileShare.Read);

using (swSave = new StreamWriter(fsSave, Encoding.UTF8))
{
swSave.WriteLine(strBld);
}

  • FileMode(Path의 파일을 가지고 할 행동을 나타냅니다) : Append (파일을 열고 파일의 끝까지 검색하거나 새 파일을 만듭니다.)
  • FileAccess(내가(본인 프로세스) 이 파일을 열 때에 지정할 권한을 의미) : Write (파일에 쓸 수 있습니다.)
  • FileShare(다른 프로세스(스레드)가 파일을 열 때 가질 수 있는 권한을 지정) : Read (다른 프로세스가 파일을 읽을 수 있습니다.)

프로그램에서는 Write 하면서 작업자는 Read 속성으로 파일을 Open 하면 될 줄 알았습니다.
하지만 아래와 같은 두가지 case 가 반복 됬습니다.

case 1) 파일이 Write 중일 때, 작업자가 Open 한 경우 ( 프로그램이 선점한 경우 )
해당 경우는 Excel 에서 읽기전용으로 Open 할지 물어봅니다. 그러면 데이터 열람도 가능하고 Write 도 정상적으로 동작합니다.

case 2) 파일이 아직 Write 안할 때, 작업자가 먼저 Open 한 경우 (다른 프로세스가 선점한 경우 )
해당 경우는 Excel 은 일반 파일처럼 열리고 바로 swSave 에서 해당 파일이 열렸으므로 IOException 이 발생합니다.

끝으로 쓰다보니 말이 길었습니다.
사실 요즘 느끼는 생각은 궁금한 내용에 대해서 찾아보거나 테스트 해보지 않은 상태에서 두루뭉실하게 검색을 하다보니 원하는 정보를 찾지 못하는거 같습니다. 뭔가 프로그래밍하면서 똑같은 코드를 반복해 매너리즘(?) 에 빠지는 느낌도 드는거 같구요. 뭔가 이번 계기로 프로그램을 개선해나가면서 당연하다고 생각했던 부분들을 뜯어 고치고 싶습니다.

좋은 방법과 도움될만한 정보도 모두 환영입니다!
감사합니다!

–참고 URL : https://chashtag.tistory.com/49

1 Like

본인 프로세스와 스레드가 동시에 파일에 엑세스하는 것이 문제인가요?

file과 file_old로 나눠서 file에는 새로운 내용을 적고 file_old를 제가 보는 것이죠, 제가 엑셀을 닫아서 file_old에 프로세스가 접근 가능할 때 file의 내용을 file_old에 옮기는 것입니다.

해당 방법의 단점은 메모리적으로 좋지 않다, 이건 file이 아닌 변수에 담아놨다 옮기면 될거같구요. 실시간으로는 못본다 정도 같습니다.

3 Likes

Read/Write를 동시에 해야되는데, 이걸 엑셀 파일로 구현하려고 하는 시도부터가 잘못된겁니다.
하지 말아야되는 걸, 안되는걸, 할 필요가 없는걸 억지로 하려고 하지 마세요.
SQLite나 LiteDB 같은 로컬db 쓰세요.

3 Likes

자마린님 말씀대로 외부툴을 이용하는 경우 제약 조건이 무조건 발생하며,
원하는 동작을 하면 운이 좋은것이고 일반적으로는 안되는게 정상입니다.

그러므로 가장 좋은 방법은 뷰어를 만드는 것이고요.
다음으로 꼭 엑셀로 봐야겠다면 아메리카노님 말씀대로 실시간을 포기하고
쓰기 에러가 날 경우 별도의 임시 파일로 저장하다 에러가 안날 때 한번에 추가하는 방법을 써야 합니다.

2 Likes

굳이 왜 이걸 Read / Write를 동시에 하시려는 모르겠지만 두번째 케이스를 포기를 하시면 됩니다 ㅎㅎ
프로그램에서 파일을 열기전 이미 열려있다면 메세지와 함께 실행이 되지 않으면 됩니다.
굳이 하겠다면 아메리카노님 방법으로 사용하는 방법이 있긴한데 …
근데 개인적으로 같은 제조업 종사자로서 작업자에게 동시 접근이 불가하다고 설득하시는게 여러모로 더 나을 수도 있습니다. 골머리 써서 구현을 해둬봤자 불안정 하거니와 나중에 프로그램에 뻗어버리면 작업자들 대응 아시죠?? ㅋㅋ

2 Likes

많은 조언 감사드립니다! 제가 불필요한 부분에 신경을 많이 쓴것 같습니다.
Tokhi 님 의견처럼 작업자에게 설득하는게 나을것 같습니다.
다음에는 좀더 의미있는 질문으로 글 올리겠습니다!

1 Like

회사에서 통합로깅(엘크)을 지원해줄지는 모르겠으나
로깅은 엘크가 대세이며~ 로깅을 잘 쌓으면 bi성 데이터도 저렴한 비용으로 시각화할수 있습니다.

엘크는 설치/클라우드로 쉽게 사용할수 있는 스택이며 ms 클라우드 쓸필요없으나
ms가 관련기술 잘 설명을 해주어서 닷넷에서도 쉽게 쓸수있으니 아래 내용도 참고하면 도움될것같습니다.

(엑셀이 아닌 키바나 통합뷰에서 노코딩 대시보드화 할수있는것이 핵심입니다)