DCL 3.7.4
Loading...
Searching...
No Matches
File Class Reference

#include <File.h>

Inheritance diagram for File:
Object PollAble SerialPort Socket SSLSocket

Public Types

enum  Whence { BEGIN , CURRENT , END }

Public Member Functions

virtual String toString () const
virtual ~File ()
 File (const String &_path, int _oflags=READONLY, int _mode=0666) __DCL_THROWS1(IOException *)
void open (const String &_path, int _oflags=READONLY, int _mode=0666) __DCL_THROWS1(IOException *)
 File (HandleType _handle, int _ohints, bool _closeOnClose) __DCL_THROWS1(IOException *)
void open (HandleType _handle, int _ohints, bool _closeOnClose) __DCL_THROWS1(IOException *)
virtual void sync () __DCL_THROWS1(IOException *)
virtual void close () __DCL_THROWS1(IOException *)
virtual size_t available () const __DCL_THROWS1(IOException *)
virtual size_t read (void *_buf, size_t _n) __DCL_THROWS1(IOException *)
virtual size_t write (const void *_buf, size_t _n) __DCL_THROWS1(IOException *)
off_t seek (off_t _offset, int _whence) __DCL_THROWS1(IOException *)
off_t size () const __DCL_THROWS1(IOException *)
DateTime mtime () const __DCL_THROWS1(IOException *)
bool time (time_t *_atime, time_t *_mtime, time_t *_ctime) const
HandleType handle () const
const String & path () const
Public Member Functions inherited from Object
virtual void destroy ()
String className () const
bool isInstanceOf (const std::type_info &typeinfo) const
virtual const std::type_info & typeInfo () const

Static Public Member Functions

static FileopenTempFile (const String &_dirname, const String &_prefix, unsigned int _mode=0666) __DCL_THROWS1(IOException *)

Protected Member Functions

 File ()
 File (HandleType _handle, const String &_path)
Protected Member Functions inherited from Object
virtual ~Object ()
 Object ()

Protected Attributes

String __path
HandleType __handle
bool __closeOnClose

Detailed Description

운영체제 파일을 추상화 한다.

이 클래스의 목적은 서로다른 운영체제에서 파일 접근을 위한 표준 접근방법을 제공하는 것으로, 기본 모델은 UNIX의 것을 따른다.

Definition at line 41 of file File.h.

Member Enumeration Documentation

◆ Whence

Enumerator
BEGIN 
CURRENT 
END 

Definition at line 207 of file File.h.

208 {
209 BEGIN, // SEEK_SET
210 CURRENT, // SEEK_CUR
211 END // SEEK_END
212 };
@ CURRENT
Definition File.h:210
@ END
Definition File.h:211
@ BEGIN
Definition File.h:209

Constructor & Destructor Documentation

◆ File() [1/4]

File::File ( )
protected

Definition at line 62 of file File.cpp.

63{
65 __closeOnClose = true;
66#ifdef __WINNT__
67 __fileType = UNKNOWN;
68 __readEvent = NULL;
69 __writeEvent = NULL;
70#endif
71}
#define NULL
Definition Config.h:312
#define INVALID_HANDLE_VALUE
Definition Dir.cpp:34
HandleType __handle
Definition File.h:255
bool __closeOnClose
Definition File.h:256

◆ File() [2/4]

File::File ( HandleType _handle,
const String & _path )
protected

열려진 파일핸들을 사용하여 객체를 구성한다.

이것은 openTempFile(const String&,const String&,int) 사용한다.

Definition at line 264 of file File.cpp.

265{
266 __handle = _handle;
267 __path = _path;
268 __closeOnClose = true;
269}
String __path
Definition File.h:254

◆ ~File()

virtual File::~File ( )
virtual

객체의 파괴를 수행한다. close하지 않았으면 close()하며 예외가 발생하면 무시한다.

◆ File() [3/4]

File::File ( const String & _path,
int _oflags = READONLY,
int _mode = 0666 )

주어진 경로의 파일을 열고 객체를 구성한다.

파일의 종류는 일반파일(Regular File), 시리얼 포트(COM#N, /dev/ttyS#N, /dev/ttyUSBS#N), Windows에서 콘솔(COM), 명명된 파이프(Named Pipe)이다.

Parameters
_pathWindows에서 COM#N이 사용되면 큐 버퍼는 2048로 설정된다.
_oflagsWindows CON은 READONLY, WRITEONLY만 사용된다. Windows에서 NONBLOCK을 사용하면 FILE_FLAG_OVERRLAPPED가 적용되고, read, write를 위한 이벤트를 생성한다.
_modeWindows에서는 무시되고, UNIX에서 umask가 적용된다.

Definition at line 73 of file File.cpp.

75{
77 open(_path, _oflags, _mode);
78}
void open(const String &_path, int _oflags=READONLY, int _mode=0666) __DCL_THROWS1(IOException *)
Definition File.cpp:80

◆ File() [4/4]

File::File ( HandleType _handle,
int _ohints,
bool _closeOnClose )

열려진 파일핸들을 사용하여 객체를 구성한다.

See also
File::OpenFlags
Parameters
_handleUNIX에서 open, pipe등의 시스템콜 리턴값, Windows에서는 CreateFile, CreatePipe 등의 리턴값이다.
_ohintsWindows에서 _handle의 생성 플래그에 FILE_FLAG_OVERLAPPED가 사용되었거나, ioctlsock FIONBIO의 사용으로 NONBLOCK 으로 설정된 핸들에 대하여 사용된다. READONLY, WRITEONLY, READWRITE와 NONBLOCK이 조합된다. UNIX에서는 무시된다.
_closeOnCloseclose()에서 _handle을 닫을지 여부를 지정한다.

Definition at line 271 of file File.cpp.

273{
275 open(_handle, _ohints, _closeOnClose);
276}

Member Function Documentation

◆ available()

size_t File::available ( ) const
virtual

Non-Block으로 읽혀질 수 있는 바이트의 수를 리턴한다.

UNIX에서 ioctl FIONREAD를 사용한다. WINDOWS에서는 일반파일, (Named) Pipe, 시리얼포트(COM#N), 콘솔 및 소켓에 대하여 구현되어 있고, 그 외에는 항상 0을 리턴한다.

Definition at line 407 of file File.cpp.

409{
411
412#ifdef __WINNT__
413 size_t nbytes = 0;
414 switch (__fileType) {
415 case REGULAR: {
416 LARGE_INTEGER fileSize;
417 if (GetFileSizeEx(__handle, &fileSize)) {
418 LARGE_INTEGER distanceToMove;
419 LARGE_INTEGER newFilePointer;
420 distanceToMove.QuadPart = 0;
421 if (SetFilePointerEx(__handle, distanceToMove, &newFilePointer, FILE_CURRENT))
422 nbytes = (size_t)(fileSize.QuadPart - newFilePointer.QuadPart);
423 }
424 break;
425 }
426 case PIPE: {
427 DWORD dwTotalBytesAvail;
428 if (PeekNamedPipe(__handle, NULL, 0, NULL, &dwTotalBytesAvail, NULL))
429 nbytes = (size_t)dwTotalBytesAvail;
430 break;
431 }
432 case CONSOLE: {
433 INPUT_RECORD buf[200]; // 200 * (sizeof(INPUT_RECORD) == 20) 4000
434 DWORD dwEvents = 0;
435 if (PeekConsoleInput(__handle, buf, __countof(buf, INPUT_RECORD), &dwEvents)) {
436 size_t n = 0;
437 for (size_t i = 0; i < __countof(buf, INPUT_RECORD); i++) {
438 if (buf[i].EventType == KEY_EVENT) {
439 KEY_EVENT_RECORD& ev = buf[i].Event.KeyEvent;
440 if (ev.bKeyDown && ev.uChar.AsciiChar != 0) {
441 if (ev.uChar.AsciiChar == 13) {
442 nbytes = n + 2; // ReadFile에서 \r\n으로 변환되어 읽힌다.
443 break;
444 }
445 n += ev.wRepeatCount;
446 }
447 }
448 }
449 // NONBLOCK
450 if (nbytes == 0 && __readEvent)
451 nbytes = n;
452 }
453 break;
454 }
455 case COMM: {
456 DWORD dwErrors;
457 COMSTAT stat;
458 if (ClearCommError(__handle, &dwErrors, &stat))
459 nbytes = (size_t)stat.cbInQue;
460 break;
461 }
462 case SOCKET: {
463 u_long n = 0;
464 if (ioctlsocket((::SOCKET)__handle, FIONREAD, &n))
465 throw new IOException(__path, WSAGetLastError());
466 nbytes = (size_t)n;
467 break;
468 }
469 default: {
470 __DCL_ASSERT(false);
471 }
472 }
473 return nbytes;
474#else
475 // x64 nbytes를 off_t(long long int)로 하면 안된다.
476 unsigned int nbytes = 0;
477 ioctl(__handle, FIONREAD, &nbytes);
478 return (size_t)nbytes;
479#endif
480}
#define __countof(array, type)
Definition Config.h:336
#define __DCL_ASSERT(expr)
Definition Object.h:394
#define __DCL_ASSERT_HANDLE(expr)
Definition Object.h:408
#define ioctlsocket(s, cmd, argp)
Definition Socket.cpp:47

◆ close()

void File::close ( )
virtual

파일을 닫는다.

Reimplemented in SSLSocket.

Definition at line 369 of file File.cpp.

372{
374
375#ifdef __WINNT__
376 if (__fileType == COMM)
377 PurgeComm(__handle, PURGE_RXABORT | PURGE_RXCLEAR
378 | PURGE_TXABORT | PURGE_TXCLEAR);
379 __fileType = UNKNOWN;
380 if (__readEvent) {
381 CloseHandle(__readEvent);
382 __readEvent = NULL;
383 }
384 if (__writeEvent) {
385 CloseHandle(__writeEvent);
386 __writeEvent = NULL;
387 }
388#endif
389
390 if (!__closeOnClose)
391 return;
392
393 HandleType handle = __handle;
394 String path = __path;
396 __path.clear();
397
398#ifdef __WINNT__
399 if (!CloseHandle(handle))
400 throw new IOException(path, GetLastError());
401#else
402 if (::close(handle))
403 throw(new IOException(path, errno));
404#endif
405}
HandleType handle() const
Definition File.h:246
virtual void close() __DCL_THROWS1(IOException *)
Definition File.cpp:369
const String & path() const
Definition File.h:251

◆ handle()

HandleType File::handle ( ) const
inline

파일의 핸들값을 리턴한다. (File::HandleType)-1 이면 닫혀진 상태이다.

Definition at line 246 of file File.h.

246{ return __handle; }

◆ mtime()

DateTime File::mtime ( ) const

파일 최종 수정된 시간을 얻는다.

Definition at line 665 of file File.cpp.

667{
668 time_t mtime;
669 if (!time((time_t * )NULL, &mtime, (time_t * )NULL)) {
670#ifdef __WINNT__
671 throw new IOException(__path, GetLastError());
672#else
673 throw (new IOException(__path, errno));
674#endif
675 }
676 return DateTime(mtime);
677}
bool time(time_t *_atime, time_t *_mtime, time_t *_ctime) const
Definition File.cpp:679
DateTime mtime() const __DCL_THROWS1(IOException *)
Definition File.cpp:665

◆ open() [1/2]

void File::open ( const String & _path,
int _oflags = READONLY,
int _mode = 0666 )

이미 열린 파일은 닫고, 파일을 새로 연다.

See also
File(const String& _path, int _oflags, int _mode)

Definition at line 80 of file File.cpp.

82{
84 close();
85
86 __closeOnClose = true;
87#ifdef __WINNT__
88 __fileType = UNKNOWN;
89 __readEvent = NULL;
90 __writeEvent = NULL;
91
92 FileType fileType = UNKNOWN;
93 // Console, COMM 을 검사한다.
94 HANDLE handle = CreateFileW(_path, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
96 DWORD dw;
97 DCB dcb;
98 if (GetNamedPipeInfo(handle, NULL, NULL, NULL, NULL))
99 fileType = PIPE;
100 else if (GetConsoleMode(handle, &dw))
101 fileType = CONSOLE;
102 else if (GetCommState(handle, &dcb))
103 fileType = COMM;
104 else
105 fileType = REGULAR;
106
107 CloseHandle(handle);
109 }
110
111 DWORD dwDesiredAccess = GENERIC_READ;
112 DWORD dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
113 SECURITY_ATTRIBUTES securityAttributes = { sizeof(SECURITY_ATTRIBUTES), NULL, TRUE };
114 DWORD dwCreationDisposition = OPEN_EXISTING;
115 DWORD dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL;
116
117 switch (_oflags & (READONLY | WRITEONLY | READWRITE)) {
118 default:
119 // _oflags == 0 이면 READONLY 인 것으로 간주한다.
120 case READONLY:
121 dwDesiredAccess = GENERIC_READ;
122 break;
123 case WRITEONLY:
124 if (_oflags & APPEND)
125 dwDesiredAccess = GENERIC_READ | GENERIC_WRITE;
126 else
127 dwDesiredAccess = GENERIC_WRITE;
128 break;
129 case READWRITE:
130 dwDesiredAccess = GENERIC_READ | GENERIC_WRITE;
131 break;
132 }
133
134 if (_oflags & EXCLUSIVE) {
135 dwShareMode = 0;
136 }
137
138 switch (_oflags & (CREATE | EXCLUSIVE | TRUNCATE)) {
139 default:
140 case EXCLUSIVE:
141 dwCreationDisposition = OPEN_EXISTING;
142 break;
143 case CREATE:
144 case CREATE | TRUNCATE:
145 dwCreationDisposition = OPEN_ALWAYS;
146 break;
147 case CREATE | EXCLUSIVE:
148 case CREATE | EXCLUSIVE | TRUNCATE:
149 dwCreationDisposition = CREATE_NEW;
150 break;
151 case TRUNCATE:
152 case TRUNCATE | EXCLUSIVE:
153 dwCreationDisposition = TRUNCATE_EXISTING;
154 break;
155 }
156
157 if (_oflags & NONBLOCK)
158 dwFlagsAndAttributes |= FILE_FLAG_OVERLAPPED;
159
160 if (_oflags & SYNC)
161 dwFlagsAndAttributes |= FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH;
162
163 if (fileType == CONSOLE || fileType == PIPE) {
164
165 handle = CreateFileW(_path, dwDesiredAccess, dwShareMode, &securityAttributes,
166 OPEN_EXISTING, dwFlagsAndAttributes, NULL);
167 }
168 else if (fileType == COMM) {
169 handle = CreateFileW(_path, dwDesiredAccess, dwShareMode, &securityAttributes,
170 OPEN_EXISTING, dwFlagsAndAttributes, NULL);
171 }
172 else {
173 // UNKNOWN, maybe REGULAR
174 switch (dwDesiredAccess & (GENERIC_READ | GENERIC_WRITE)) {
175 case GENERIC_READ:
176 dwFlagsAndAttributes |= FILE_FLAG_SEQUENTIAL_SCAN;
177 break;
178 case GENERIC_READ | GENERIC_WRITE:
179 dwFlagsAndAttributes |= FILE_FLAG_RANDOM_ACCESS;
180 break;
181 }
182
183 if ((_oflags & TRUNCATE) && ((dwDesiredAccess & GENERIC_WRITE) == GENERIC_WRITE))
184 handle = CreateFileW(_path, dwDesiredAccess, dwShareMode,
185 &securityAttributes, TRUNCATE_EXISTING, dwFlagsAndAttributes, NULL);
186
188 handle = CreateFileW(_path, dwDesiredAccess, dwShareMode,
189 &securityAttributes, dwCreationDisposition, dwFlagsAndAttributes, NULL);
190
192 && (_oflags & APPEND) && ((dwDesiredAccess & GENERIC_READ) == GENERIC_READ)) {
193 fileType = REGULAR;
194 if (SetFilePointer(handle, 0, NULL, FILE_END) == INVALID_SET_FILE_POINTER) {
195 DWORD dwSaveError = GetLastError();
196 CloseHandle(handle);
198 SetLastError(dwSaveError);
199 }
200 }
201 }
202
203 // _oflags에 NONBLOCK이 있으면 read, write Overrlapped Io 하도록 Event 객체를 생성한다.
204 HANDLE readEvent = NULL, writeEvent = NULL;
205 if (handle != INVALID_HANDLE_VALUE && _oflags & NONBLOCK) {
206 __DCL_ASSERT(dwFlagsAndAttributes & FILE_FLAG_OVERLAPPED);
207 if (_oflags & (WRITEONLY | READWRITE))
208 writeEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
209
210 // _oflags == 0 이면 READONLY 인 것으로 간주한다.
211 if (_oflags & (READONLY | READWRITE) || writeEvent == NULL)
212 readEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
213
214 if (readEvent == NULL && writeEvent == NULL) {
215 DWORD dwSaveError = GetLastError();
216 if (readEvent)
217 CloseHandle(readEvent);
218 if (writeEvent)
219 CloseHandle(writeEvent);
220
221 CloseHandle(handle);
223 SetLastError(dwSaveError);
224 }
225 }
226
228 throw new IOException(_path, GetLastError());
229
230 __fileType = fileType;
231 __readEvent = readEvent;
232 __writeEvent = writeEvent;
233#else
234 int oflags = 0;
235 if (_oflags & READONLY)
236 oflags |= O_RDONLY;
237 if (_oflags & WRITEONLY)
238 oflags |= O_WRONLY;
239 if (_oflags & READWRITE)
240 oflags |= O_RDWR;
241 if (_oflags & CREATE)
242 oflags |= O_CREAT;
243 if (_oflags & EXCLUSIVE)
244 oflags |= O_EXCL;
245 if (_oflags & NOCTTY)
246 oflags |= O_NOCTTY;
247 if (_oflags & APPEND)
248 oflags |= O_APPEND;
249 if (_oflags & TRUNCATE)
250 oflags |= O_TRUNC;
251 if (_oflags & NONBLOCK)
252 oflags |= O_NONBLOCK;
253 if (_oflags & SYNC)
254 oflags |= O_SYNC;
255
256 int handle = __open(_path, oflags, _mode);
257 if (handle == -1)
258 throw new IOException(_path, errno);
259#endif
261 __path = _path;
262}
DCLCAPI int __open(const String &_path, int _oflags,...)
Definition _fcntl.cpp:31
#define TRUE
#define FALSE

◆ open() [2/2]

void File::open ( HandleType _handle,
int _ohints,
bool _closeOnClose )

이미 열려진 파일핸들을 사용하여 객체를 구성한다.

See also
File(HandleType _handle, int _ohints, bool _closeOnClose

Definition at line 278 of file File.cpp.

280{
282 close();
283
284#ifdef __WINNT__
285 __fileType = UNKNOWN;
286 __readEvent = NULL;
287 __writeEvent = NULL;
288
289 StringBuilder path;
290 FileType fileType = UNKNOWN;
291
292 wchar_t nameInfo[PATH_MAX + 1 + 4] = { L'\0' };
293 DWORD dwConsoleMode;
294 DCB dcb;
295 if (GetFileInformationByHandleEx(_handle, FileNameInfo, nameInfo, sizeof(nameInfo))) {
296 fileType = REGULAR;
297 path.assign(((FILE_NAME_INFO*)nameInfo)->FileName);
298 }
299 else if (GetNamedPipeInfo(_handle, NULL, NULL, NULL, NULL)) {
300 path.format(__T("(pipe: %d)"), _handle);
301 fileType = PIPE;
302 }
303 else if (GetConsoleMode(_handle, &dwConsoleMode)) {
304 path = __T("CON");
305 fileType = CONSOLE;
306 }
307 else if (GetCommState(_handle, &dcb)) {
308 path = __T("COM#N");
309 fileType = COMM;
310 }
311 else {
312 path.format(__T("(HANDLE: %p)"), _handle);
313 throw new IOException(path, ERROR_INVALID_HANDLE);
314 }
315
316 HANDLE readEvent = NULL, writeEvent = NULL;
317 if (_ohints & NONBLOCK) {
318 if (_ohints & (WRITEONLY | READWRITE))
319 writeEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
320
321 // _oflags == 0 이면 READONLY 인 것으로 간주한다.
322 if (_ohints & (READONLY | READWRITE) || writeEvent == NULL)
323 readEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
324
325 if (readEvent == NULL && writeEvent == NULL) {
326 DWORD dwSaveError = GetLastError();
327 if (readEvent)
328 CloseHandle(readEvent);
329 if (writeEvent)
330 CloseHandle(writeEvent);
331
332 throw new IOException(path, dwSaveError);
333 }
334 }
335
336 __path = path.toString();
337 __fileType = fileType;
338 __readEvent = readEvent;
339 __writeEvent = writeEvent;
340#else
341 if (isatty(_handle)) {
342 if (__ttyname(_handle, __path) != 0)
343 throw new IOException(className(), errno);
344 }
345 else
346 __path = String::format(__T("(fd: %d)"), _handle);
347#endif
348
349 __handle = _handle;
350 __closeOnClose = _closeOnClose;
351}
DCLCAPI int __ttyname(int fd, String &_r)
Definition _unistd.cpp:60
#define __T(str)
Definition Object.h:60
String className() const
Definition Object.cpp:163

◆ openTempFile()

File * File::openTempFile ( const String & _dirname,
const String & _prefix,
unsigned int _mode = 0666 )
static

Definition at line 727 of file File.cpp.

732{
733 File* r = NULL;
734
735 StringBuilder sbTemplate;
736 if (!_dirname.isEmpty()) {
737 sbTemplate = _dirname;
738 if (!_dirname.endsWith(L"/")) {
739 sbTemplate += L"/";
740 }
741 }
742
743 if (!_prefix.isEmpty()) {
744 sbTemplate += _prefix;
745 }
746 else {
747 sbTemplate += L"dcl";
748 }
749
750 sbTemplate += L"XXXXXX";
751
752#ifdef __WINNT__
753 if (::_wmktemp((wchar_t*)sbTemplate.data())) {
754 r = new File(sbTemplate, READWRITE | CREATE | EXCLUSIVE, _mode);
755 }
756 else {
757 throw new IOException(sbTemplate, EINVAL);
758 }
759#else
760 ByteString bsbTemplate = UTF8Encoder::encode(sbTemplate.toString());
761 int handle = ::mkstemp((char*)bsbTemplate.data());
762 if (handle == -1) {
763 throw new IOException(sbTemplate, errno);
764 }
765
766 struct stat st;
767 if (::fstat(handle, &st)) {
768 throw new IOException(sbTemplate, errno);
769 }
770
771 if (st.st_mode != _mode) {
772 if (::fchmod(handle, _mode)) {
773 throw new IOException(sbTemplate, errno);
774 }
775 }
776
777 r = new File(handle, UTF8Decoder::decode(bsbTemplate));
778#endif
779 return r;
780}
IOException *size_t r
Definition MediaInfo.cpp:82
File()
Definition File.cpp:62

◆ path()

const String & File::path ( ) const
inline

열려진 파일의 경로를 리턴한다.

Definition at line 251 of file File.h.

251{ return __path; }

◆ read()

size_t File::read ( void * _buf,
size_t _n )
virtual

파일을 읽는다. 오픈 플래그에 NONBLOCK이 사용되면 0을 리턴할 수 있다. UNIX는 O_NONBLOCK이, Windows는 FILE_FLAG_OVERLAPPED가 사용된다. UNIX에서 리턴값이 0이면 errno가 EAGAIN 일 수 있다.

Parameters
_buf버퍼
_n버퍼의 크기, 버퍼의 바이트 수
Returns
읽혀진 바이트의 수이다. 0이면 EOF를 의미한다.

Definition at line 482 of file File.cpp.

484{
486 __DCL_ASSERT_PARAM(_buf != NULL);
487
488#ifdef __WINNT__
489 DWORD n = 0;
490 if (__readEvent) {
491 // NONBLOCK, Overrapped Read
492 OVERLAPPED ov;
493 ZeroMemory(&ov, sizeof(ov)); // cf. memset(&ov, 0, sizeof(ov));
494 ov.hEvent = __readEvent;
495 if (ReadFile(__handle, _buf, (DWORD)_n, &n, &ov)) {
496 // GetOverlappedResult가 성공하면 이벤트는 Set 된다.
497 SetEvent(ov.hEvent);
498
499 // 다른 스레드에서 WriteFile을 호출했을 경우 n == 0일 수 있다.
500 return n;
501 }
502 if (GetLastError() == ERROR_IO_PENDING) {
503 // 읽기가 진행중이다. 마칠때까지 기다린 후 결과를 확인한다.
504 switch (WaitForSingleObject(ov.hEvent, INFINITE)) {
505 case WAIT_OBJECT_0:
506 if (GetOverlappedResult(__handle, &ov, &n, FALSE))
507 return n;
508 break;
509 case WAIT_TIMEOUT: // 이것은 결코 도달하지 않는다. INFINITE
510 CancelIo(__handle);
511 SetLastError(ERROR_TIMEOUT);
512 break;
513 default:
514 __DCL_ASSERT(false);
515 }
516 }
517 // ERROR!
518 throw new IOException(__path, GetLastError());
519 }
520 else {
521 // __readEvent == NULL, Blocked Read
522 if (!ReadFile(__handle, _buf, (DWORD)_n, &n, NULL))
523 throw new IOException(__path, GetLastError());
524 }
525 return n;
526#else
527 ssize_t n = 0;
528 while ((n = ::read(__handle, _buf, _n)) == -1) {
529 // errno가 EAGAIN or EWOULDBLOCK인 경우
530 // fd가 O_NONBLOCK으로 열렸고, 읽기가 차단되었다.
531 // EAGAIN이면 0바이트를 읽었고, 읽기를 다시 시도한다.
532 // 그 외에는 오류이다.
533 if (!(errno == EAGAIN || errno == EWOULDBLOCK)) {
534 throw new IOException(__path, errno);
535 }
536 }
537 return n;
538#endif
539}
#define __DCL_ASSERT_PARAM(expr)
Definition Object.h:409
#define INFINITE
Definition Thread.h:34
virtual size_t read(void *_buf, size_t _n) __DCL_THROWS1(IOException *)
Definition File.cpp:482

◆ seek()

File::off_t File::seek ( off_t _offset,
int _whence )

파일의 읽기/쓰기 변위(offset)를 재설정한다.

Parameters
_offset변위
_whenceBEGIN, CURRENT, END
Returns
파일의 시작을 기준으로 새로운 변위를 리턴한다.

Definition at line 596 of file File.cpp.

598{
600
601#ifdef __WINNT__
602 DWORD dwMoveMethod = FILE_BEGIN;
603 switch (_whence) {
604 case BEGIN:
605 dwMoveMethod = FILE_BEGIN;
606 break;
607 case CURRENT:
608 dwMoveMethod = FILE_CURRENT;
609 break;
610 case END:
611 dwMoveMethod = FILE_END;
612 break;
613 default:
614 __DCL_ASSERT(false);
615 }
616 LARGE_INTEGER distanceToMove;
617 LARGE_INTEGER newFilePointer;
618 distanceToMove.QuadPart = _offset;
619 if (!SetFilePointerEx(__handle, distanceToMove, &newFilePointer, dwMoveMethod))
620 throw new IOException(__path, GetLastError());
621 return newFilePointer.QuadPart;
622#else
623 int whence = 0;
624 switch (_whence) {
625 case BEGIN :
626 whence = SEEK_SET;
627 break;
628 case CURRENT :
629 whence = SEEK_CUR;
630 break;
631 case END :
632 whence = SEEK_END;
633 break;
634 default :
635 __DCL_ASSERT(false);
636 }
637
638 off_t r = lseek(__handle, _offset, whence);
639 if (r == (off_t)-1)
640 throw (new IOException(__path, errno));
641 return r;
642#endif
643}

◆ size()

File::off_t File::size ( ) const

파일의 크기를 구한다.

Definition at line 645 of file File.cpp.

647{
649
650#ifdef __WINNT__
651 LARGE_INTEGER fileSize;
652 if (!GetFileSizeEx(__handle, &fileSize))
653 throw new IOException(__path, GetLastError());
654 return fileSize.QuadPart;
655#else
656 struct stat st;
657 int r = fstat(__handle, &st);
658 if (r == -1)
659 throw (new IOException(__path, errno));
660
661 return st.st_size;
662#endif
663}

◆ sync()

void File::sync ( )
virtual

장치와 동기화 한다. UNIX fsync, Windows FlushFileBuffers

Definition at line 353 of file File.cpp.

355{
357
358#ifdef __WINNT__
359 if (!FlushFileBuffers(__handle))
360 // 콘솔과 같이 버러링을 하지 않는 장치
361 throw new IOException(__path, GetLastError());
362#else
363 if (fsync(__handle) == -1)
364 // EINVAL, EBADF, EROFS, EIO
365 throw new IOException(__path, errno);
366#endif
367}

◆ time()

bool File::time ( time_t * _atime,
time_t * _mtime,
time_t * _ctime ) const

Definition at line 679 of file File.cpp.

680{
682
683#ifdef __WINNT__
684 FILETIME atime;
685 FILETIME mtime;
686 FILETIME ctime;
687 if (!GetFileTime(__handle, &atime, &mtime, &ctime)) {
688 return false;
689 }
690
691 ULARGE_INTEGER n;
692 if (_atime) {
693 n.HighPart = atime.dwHighDateTime;
694 n.LowPart = atime.dwLowDateTime;
695 *_atime = n.QuadPart;
696 }
697 if (_mtime) {
698 n.HighPart = mtime.dwHighDateTime;
699 n.LowPart = mtime.dwLowDateTime;
700 *_mtime = n.QuadPart;
701 }
702 if (_ctime) {
703 n.HighPart = ctime.dwHighDateTime;
704 n.LowPart = ctime.dwLowDateTime;
705 *_ctime = n.QuadPart;
706 }
707#else
708 struct stat sb;
709 int r = fstat(__handle, &sb);
710 if (r == -1) {
711 return false;
712 }
713 if (_atime) {
714 *_atime = sb.st_atime;
715 }
716 if (_mtime) {
717 *_mtime = sb.st_mtime;
718 }
719 if (_ctime) {
720 *_ctime = sb.st_ctime;
721 }
722#endif
723 return true;
724}

◆ toString()

virtual String File::toString ( ) const
virtual

Reimplemented from Object.

◆ write()

size_t File::write ( const void * _buf,
size_t _n )
virtual

파일에 데이터를 쓴다. 오픈 플래그에 NONBLOCK이 사용되면 오류 없이 0을 리턴할 수 있다. UNIX는 O_NONBLOCK이, Windows는 FILE_FLAG_OVERLAPPED가 사용된다. UNIX에서 리턴값이 0이면 errno가 EAGAIN 일 수 있다. 0을 리턴하는 것은 read, write를 호출한 스레드가 서로 달라서, 서로 겹쳐지기 때문으로 볼 수 있다. 0을 리턴하면 write하지 않았기 때문에 다시 시도해야 한다.

Parameters
_buf버퍼
_n버퍼의 크기, 버퍼의 바이트 수
Returns
쓰여진 바이트의 수이다. 0이면 다시 시도하라.

Definition at line 541 of file File.cpp.

543{
545 __DCL_ASSERT_PARAM(_buf != NULL);
546
547#ifdef __WINNT__
548 DWORD n = 0;
549 if (__writeEvent) {
550 // NONBLOCK, Overrapped Write
551 OVERLAPPED ov;
552 ZeroMemory(&ov, sizeof(ov)); // cf. memset(&ov, 0, sizeof(ov));
553 ov.hEvent = __writeEvent;
554 if (WriteFile(__handle, _buf, (DWORD)_n, &n, &ov)) {
555 // GetOverlappedResult가 성공하면 이벤트는 Set 된다.
556 SetEvent(ov.hEvent);
557 // 다른 스레드에서 ReadFile을 호출했을 경우 n == 0일 수 있다.
558 return n;
559 }
560 if (GetLastError() == ERROR_IO_PENDING) {
561 // 쓰기가 진행중이다. 마칠때까지 기다린 후 결과를 확인한다.
562 switch (WaitForSingleObject(ov.hEvent, INFINITE)) {
563 case WAIT_OBJECT_0:
564 if (GetOverlappedResult(__handle, &ov, &n, FALSE))
565 return n;
566 break;
567 case WAIT_TIMEOUT: // 이것은 결코 도달하지 않는다. INFINITE
568 CancelIo(__handle);
569 SetLastError(ERROR_TIMEOUT);
570 default:
571 __DCL_ASSERT(false);
572 }
573 }
574 // ERROR!
575 throw new IOException(__path, GetLastError());
576 }
577 else {
578 // __writeEvent == NULL, Blocked Write
579 if (!WriteFile(__handle, _buf, (DWORD)_n, &n, NULL))
580 throw new IOException(__path, GetLastError());
581 }
582 return n;
583#else
584 ssize_t n = ::write(__handle, _buf, _n);
585 if (n == -1) {
586 // 파일이 nonblocking으로 표시되었고 오퍼레이션이 블록되었다.
587 if (errno == EAGAIN || errno == EWOULDBLOCK)
588 return 0;
589 else
590 throw new IOException(__path, errno);
591 }
592 return n;
593#endif
594}
virtual size_t write(const void *_buf, size_t _n) __DCL_THROWS1(IOException *)
Definition File.cpp:541

Member Data Documentation

◆ __closeOnClose

bool File::__closeOnClose
protected

Definition at line 256 of file File.h.

◆ __handle

HandleType File::__handle
protected

Definition at line 255 of file File.h.

◆ __path

String File::__path
protected

Definition at line 254 of file File.h.


The documentation for this class was generated from the following files: