Friday, June 5, 2015

[C / C++] Cross-Platform pratik dosya yaratma & okuma sınıfları (Linux/Windows/MacOs)


Merhaba arkadaşlar. Gerek iş, gerek okul nedeniyle blogu uzun zamandır güncelleyemiyorum. Bugün pratik dosya yaratmanıza ve okumanıza olanak sağlayacak iki adet sınıf paylaşacağım. Bu iki sınıfı kullanarak sadece birkaç satır ile dosya okuyabilecek, yaratabilecek, veya dosyaya yazabileceksiniz. Öncelikle, kullanacağımız sınıflar şunlar;

FileReader.h


  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
#pragma once

#ifndef WIN32
 #include <stdio.h>
 #include <unistd.h>
 #include <sys/types.h>
#else
 #include <io.h>
#endif

#include <fcntl.h>
#include <sys/stat.h>
#include <errno.h>


class FileReader
{
public:
 FileReader(char * path);
 ~FileReader();
 bool Open();
 char * GetContents() const { return buf; }
 char * GetAt(int index) const { return &buf[index]; }
 bool CopyTo(char * path);
 long   GetSize()  const { return _size; }
 void PrintError();
private:
 /* File handle */
 int  _fhandle;
 /* File size */
 long _size;
 /* File path */
 char * m_szPath;
 /* File content */
 char * buf;
 bool ReadFileContent();
};

/* Constructor */
FileReader::FileReader(char * path) : m_szPath(path),_size(-1),_fhandle(-1) {}

/* Destructor */
FileReader::~FileReader()
{
 if (_fhandle != -1)
 {
  delete[] buf;
  close(_fhandle);
 }
}

bool FileReader::Open()
{
 _fhandle = open(m_szPath, O_RDWR);

 if (_fhandle > -1)
 {
  if (!ReadFileContent())
   return false;
  return true;
 }
 return false;
}

bool FileReader::ReadFileContent()
{
 if (_fhandle == -1)
  return false;
 struct stat stat_buf;
 int rc = stat(m_szPath, &stat_buf);
 if (rc == 0)
 {
  _size = stat_buf.st_size;
  buf = new char[_size];
  read(_fhandle, &buf[0], _size);
  return true;
 }
 else
  return false;
}

bool FileReader::CopyTo(char * szPath)
{
 if (_fhandle > -1)
 {
  int _fhandle2 = open(szPath, O_CREAT | O_EXCL | O_RDWR);
  if (_fhandle2 > -1)
  {
   if (write(_fhandle2, GetContents(), GetSize()) == GetSize())
   {
    close(_fhandle2);
    return true;
   }
   close(_fhandle2);
  }
  return false;
 }
 return false;
}

void FileReader::PrintError()
{
 perror("FileReader");
}

FileBuilder.h


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
#pragma once


#include <fcntl.h>
#include <sys/stat.h>
#include <errno.h>

#ifndef WIN32
 #include <stdio.h>
 #include <unistd.h>
 #include <sys/types.h>
#else
 #include <io.h>
#endif

#define SEEK_CUR    1
#define SEEK_END    2
#define SEEK_SET    0

class FileBuilder
{
public:
 FileBuilder(char * ,bool);
 ~FileBuilder();
 void PrintError();
 bool Create();
 bool Append(char * , long );
 bool Append(FileReader&);
private:
 bool _overwrite;
 /* File handle */
 int  _fhandle;
 /* File size */
 long _size;
 /* File path */
 char * m_szPath;
};

FileBuilder::FileBuilder(char * szPath, bool overwrite = true) :m_szPath(szPath), _size(-1), _fhandle(-1), _overwrite(overwrite)
{
}

bool FileBuilder::Create()
{
 if (!_overwrite)
  _fhandle = open(m_szPath, O_CREAT | O_EXCL | O_RDWR, 0777);
 else
  _fhandle = open(m_szPath, O_CREAT | O_TRUNC | O_RDWR, 0777);
 if (_fhandle > -1)
 {
  
  if (!_overwrite && errno == EEXIST)
   return false;
  return true;
 }
 return false;
 
}

bool FileBuilder::Append(char * val, long size)
{
 if (_fhandle == -1)
  return false;
 lseek(_fhandle, 0, SEEK_END);
 return write(_fhandle, val, size) == size;
}

bool FileBuilder::Append(FileReader& reader)
{
 if (_fhandle == -1)
  return false;
 lseek(_fhandle, 0, SEEK_END);
 return write(_fhandle, reader.GetContents(), reader.GetSize()) == reader.GetSize();
}

void FileBuilder::PrintError()
{
 perror("FileBuilder");
}


FileBuilder::~FileBuilder()
{
 if (_fhandle != -1)
 {
  close(_fhandle);
 }
}

Yukardaki sınıfları FileReader.h ve FileBuilder.h olarak kaydedin ve kullanmak istediğiniz projeye include edin.(veya aşagıdan dosyaları indirebilirsiniz)

Sınıfların kullanımı ;

FileReader :


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
#include "stdafx.h"
#include "FileReader.h"
#include "FileBuilder.h"
#include <iostream>

using namespace std;


int _tmain(int argc, _TCHAR* argv[])
{
 FileReader fr("C:\\demo.txt"); // c:\\demo.txt, açılmak istenen dosyanın konumu + adı
 if (fr.Open()) // open fonksiyonunu çağırarak dosyayı açalım
  cout << "Dosya başarı ile açıldı.\n";
 else
  fr.PrintError(); // Eğer dosya açılamadıysa, ekrana sebebini belirten hata mesajını yazdıralım.

 char * buf = fr.GetContents(); // Dosyanın içeriğini getir (char array pointer)
 // fr.GetSize() ile dosya boyutuna erişilebilir

 fr.CopyTo("c:\\demo2.txt"); // Açılan dosyayı verilen konuma kopyalar.
}

FileBuilder :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include "stdafx.h"
#include "FileReader.h"
#include "FileBuilder.h"
#include <iostream>

using namespace std;


int _tmain(int argc, _TCHAR* argv[])
{
 // İlk parametre yaratılacak dosya konumu + adı, ikincisi eğer dosya mevcutsa üzerine yazılıp yazılmayacağı
 FileBuilder fb("c:\\file.txt",true); 
 
 if (fb.Create()) // Eğer dosya yaratıldıysa
  cout << "Dosya yaratıldı. \n";
 else
  fb.PrintError(); // Yaratılamadıysa, nedenini bildiren hata mesajını yazdır

 //fb.Append(fr);

 char * m = new char[] {'a', 'b', 'c', 'd', 'e', 'f', 'g'};
 if (fb.Append(&m[0], 7)) // Append fonksiyonu ile dosyaya veri ekle
  cout << "Ekleme başarılı.\n";

 //Append fonksiyonunu kullanarak aynı zamanda FileReader objelerini de ekleyebilirsiniz.
 
 getchar();
 return 0;
}

Bugünlük bu kadar :) Sağlıcakla kalın.

FileReader.h & FileWriter.h  = BURADAN
Mustafa K. Bilgisayar Müh.

Kahve kokusu, visual studio, uykusuzluk ve huzur.

1 comment:

  1. Sınıfların güncel hallerini buradan(https://github.com/mustify/Cross-Platform-File-Helpers) takip edebilir, ve sorunları bildirebilirsiniz.

    ReplyDelete