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 : [C#] 다른 프로세스가 읽을 수 있게 파일 열기 (FileAccess, FileShare)

1개의 좋아요

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

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

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

3개의 좋아요

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

3개의 좋아요

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

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

2개의 좋아요

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

2개의 좋아요

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

1개의 좋아요

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

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

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