{"id":324,"date":"2011-10-07T23:22:07","date_gmt":"2011-10-07T23:22:07","guid":{"rendered":"http:\/\/www.drmop.com\/?p=324"},"modified":"2011-10-18T23:34:23","modified_gmt":"2011-10-18T23:34:23","slug":"marmalade-sdk-tutorial-dealing-with-files-and-the-file-system","status":"publish","type":"post","link":"http:\/\/www.drmop.com\/index.php\/2011\/10\/07\/marmalade-sdk-tutorial-dealing-with-files-and-the-file-system\/","title":{"rendered":"Marmalade SDK Tutorial &#8211; Dealing with files and the file system"},"content":{"rendered":"<p>This tutorial is part of the Marmalade SDK tutorials collection. To see the tutorials index\u00a0<a title=\"Marmalade SDK tutorials index\" href=\"http:\/\/www.drmop.com\/index.php\/marmalade-sdk-tutorials\/\">click here<\/a><\/p>\n<p>This evening we are going to cover dealing with files and the file system in a cross platform manner using the Marmalade SDK. Note that there is no associated code with this tutorial as it is not required.<\/p>\n<p>To begin with, you will notice that Marmalade&#8217;s file functions look and behave very much like those in the standard C library, for example:<\/p>\n<pre>\r\n<blockquote>\r\n\r\ns3eFile *  s3eFileOpen (const char *filename, const char *mode)\r\nFILE *     fopen       (const char *path,     const char *mode)<\/blockquote>\r\n<\/pre>\n<h2>Paths in Marmalade<\/h2>\n<p>Paths with the Marmalade SDK follow the same approach as many other file systems in that they follow the drive, directories and filename pattern (drive:\/folder1\/folder2\/file.extension).<\/p>\n<p>The Marmalade SDK currently supports the following drive names:<\/p>\n<p>&#8216;rom&#8217; for the read-only portion of your apps data area and is read only.<br \/>\n&#8216;ram&#8217; for the writable portion of your apps data area. This drive is the only drive that is guaranteed to exist across platforms<br \/>\n&#8216;rst&#8217; for a removable memory card on the phone or tablet<br \/>\n&#8216;raw&#8217; for paths that will be passed directly to the underlying operating system without modification.  (not supported on all platforms)<br \/>\n&#8216;tmp&#8217; for a system temp folder, outside of the s3e data area. (system temporary folder and currently only available on iOS)<\/p>\n<p>Path length is limited to S3E_FILE_MAX_PATH characters (that value is currently 128 bytes, including the NULL string terminator)<\/p>\n<p>Paths can be relative or absolute<\/p>\n<p>Note that when reading a file where no drive has been specified the file system will attempt to find the file on the ram drive. if the file was not found then the system will look to the rom drive.<\/p>\n<h2>Marmalade SDK s3e file functions separated into categories<\/h2>\n<p>I have separated Marmalade&#8217;s s3e file functions into categories to make them easier to find. If you would like to see more details on each of these functions then take a look at the \u00a0<a title=\"Marmalade SDK 3SE File Reference\" rel=\"nofollow\" href=\"http:\/\/www.madewithmarmalade.com\/devnet\/docs#\/api\/api\/group__fileapigroup.html\" target=\"_blank\">Marmalade SDK s3E file reference online help doc<\/a><\/p>\n<h3>Opening and closing files<\/h3>\n<pre>s3eFile *  s3eFileOpen (const char *filename, const char *mode)\r\ns3eFile *  s3eFileOpenFromMemory (void *buffer, uint32 bufferLen)\r\ns3eResult  s3eFileClose (s3eFile *file)<\/pre>\n<h3>File query<\/h3>\n<pre>s3eBool   s3eFileCheckExists (const char *filename)\r\nint32     s3eFileGetSize (s3eFile *file)\r\nint32     s3eFileGetInt (s3eFileProperty property)\r\nint32     s3eFileTell (s3eFile *file)\r\nint64     s3eFileGetFileInt (const char *filename, s3eFileStats stat)\r\nchar *    s3eFileGetFileString (const char *filename, s3eFileStats stat, char *str, int len)\r\nuint64    s3eFileGetLastWriteTime (const char *filename)\r\nuint64    s3eFileGetFree (s3eFilePath path)<\/pre>\n<h3>File reading \/ writing \/ seeking<\/h3>\n<pre>s3eResult s3eFileFlush (s3eFile *file)\r\nint32     s3eFileGetChar (s3eFile *file)\r\ns3eBool   s3eFileEOF (s3eFile *file)\r\nint       s3eFilePrintf (s3eFile *f, const char *fmt,...)\r\nint32     s3eFilePutChar (char c, s3eFile *file)\r\nuint32    s3eFileRead (void *buffer, uint32 elemSize, uint32 noElems, s3eFile *file)\r\nchar *    s3eFileReadString (char *string, uint32 maxLen, s3eFile *file)\r\ns3eResult s3eFileSeek (s3eFile *file, int32 offset, s3eFileSeekOrigin origin)\r\nuint32    s3eFileWrite (const void *buffer, uint32 elemSize, uint32 noElems, s3eFile *file)<\/pre>\n<h3>File and folders deletion \/ renaming<\/h3>\n<pre>s3eResult  s3eFileDelete (const char *filename)\r\ns3eResult  s3eFileRename (const char *src, const char *dest)\r\ns3eResult  s3eFileDeleteDirectory (const char *dirName)\r\ns3eResult  s3eFileMakeDirectory (const char *dirName)<\/pre>\n<h3>Directory Recursion<\/h3>\n<pre>s3eResult     s3eFileListClose (s3eFileList *handle)\r\ns3eFileList*  s3eFileListDirectory (const char *dirName)\r\ns3eResult     s3eFileListNext (s3eFileList *handle, char *filename, int filenameLen)<\/pre>\n<h3>File error checking<\/h3>\n<pre>s3eFileError  s3eFileGetError ()\r\nconst char*   s3eFileGetErrorString ()<\/pre>\n<h2>Reading a file example<\/h2>\n<pre>\r\n<blockquote>\r\n\r\ns3eFile* file = s3eFileOpen(\u201cmyfile.txt\u201d, \"rb\");\r\nif (file != NULL)\r\n{\r\n    if (s3eFileRead(buffer, len, 1, File) != 1)\r\n    {\r\n        s3eFileGetError();\r\n        s3eDebugOutputString(s3eFileGetErrorString());\r\n    }\r\n    s3eFileClose(File);\r\n}\r\nelse\r\n{\r\n    s3eFileGetError();\r\n    s3eDebugOutputString(s3eFileGetErrorString());\r\n}<\/blockquote>\r\n<\/pre>\n<h2>Writing a file example<\/h2>\n<pre>\r\n<blockquote>\r\n\r\ns3eFile* file = s3eFileOpen(\u201cmyfile.txt\u201d, \"wb\");\r\nif (file != NULL)\r\n{\r\n    if (s3eFileWrite(buffer, len, 1, File) != 1)\r\n    {\r\n        s3eFileGetError();\r\n        s3eDebugOutputString(s3eFileGetErrorString());\r\n    }\r\n    s3eFileClose(File);\r\n}\r\nelse\r\n{\r\n    s3eFileGetError();\r\n    s3eDebugOutputString(s3eFileGetErrorString());\r\n}<\/blockquote>\r\n<\/pre>\n<p>As you can see the file system is pretty simple to use and doesn\u2019t particularly warrant an example demo to accompany it, so I haven\u2019t written one.<\/p>\n<p>It is worth noting that the file system also supports a call back system that allows you to implement your own file system. I will cover this in a more advanced tutorial.<\/p>\n<h2>Reading files within a compressed derbh file<\/h2>\n<p>It is possible to attach compressed derbh files to the file system and re-direct all file access to the archive, accessing these archives just like a regular file. To do this you call dzArchiveAttach(\u201cmy_archive.dz\u201d);. Note that you can attach multiple archives<\/p>\n<p>To detach the archives afterwards you would call dzArchiveDetachNamed(\u201cmy_archive.dz\u201d); or dzArchiveDetach() to detach the last attached archive.<\/p>\n<p>It\u2019s also possible to attach and detach memory based archives using dzArchiveAttachFromMem(void* pMem, uint32 size); and dzArchiveDetachFromMem(void* pMem);<\/p>\n<p>Using this system makes accessing data within compressed archives a doddle.<\/p>\n<p>To use derbh functionality within your app or game you need to include add the &#8216;derbh&#8217; sub project to the list of subprojects section of your project MKB file.<\/p>\n<h2>Creating Derbh (.DZ) Files Manually<\/h2>\n<p>Ok, so now you know how to access Marmalade compressed archive, but how do you actually create one? In the folder \\Marmalade\\5.1\\tools\\dzip you will find a tool called dzip.exe. You can use this tool to create a derbh compressed archive by supplying it with a .DCL configuration file. This file basically contains a small amount of header information along with the files that you would like to be included into the archive. Here is an example .DCL file:<\/p>\n<pre>\r\n<blockquote>\r\n\r\narchive my_archive.dz\r\nbasedir .\r\nfile image1.png 0 zlib\r\nfile image2.png 0 zlib\r\nfile image3.png 0 zlib\r\nfile image4.png 0 zlib<\/blockquote>\r\n<\/pre>\n<p>basedir \u2013 The base director of the source input files<\/p>\n<p>It is possible to specify which compressor to use on a per file based. In this case we use zlib compression, other values include lzma, dz, zero and copy.<\/p>\n<p>Well that\u2019s it from me and that&#8217;s it from him for today.<\/p>\n<p>Happy coding and please don\u2019t ever become a door to door sales PERSON! Seriously, those guys \/ gals do not know the meaning of the word &#8220;NO&#8221;!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This tutorial is part of the Marmalade SDK tutorials collection. To see the tutorials index\u00a0click here This evening we are going to cover dealing with files and the file system in a cross platform manner using the Marmalade SDK. Note that there is no associated code with this tutorial as it is not required. To [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4,13,29,43,44,42,28,3,45,1],"tags":[108,110,107,718,109],"class_list":["post-324","post","type-post","status-publish","format-standard","hentry","category-airplay-sdk","category-android-app-development","category-blackberry-playbook","category-blackberry-playbook-app-development","category-game-and-app-development","category-ios-app-development","category-marmalade-sdk","category-programming","category-samsung-bada-development","category-uncategorized","tag-cross-platform-file-system","tag-derbh-archives","tag-files-and-file-system","tag-marmalade-sdk","tag-standard-c-file-system"],"_links":{"self":[{"href":"http:\/\/www.drmop.com\/index.php\/wp-json\/wp\/v2\/posts\/324","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/www.drmop.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.drmop.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.drmop.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.drmop.com\/index.php\/wp-json\/wp\/v2\/comments?post=324"}],"version-history":[{"count":7,"href":"http:\/\/www.drmop.com\/index.php\/wp-json\/wp\/v2\/posts\/324\/revisions"}],"predecessor-version":[{"id":376,"href":"http:\/\/www.drmop.com\/index.php\/wp-json\/wp\/v2\/posts\/324\/revisions\/376"}],"wp:attachment":[{"href":"http:\/\/www.drmop.com\/index.php\/wp-json\/wp\/v2\/media?parent=324"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.drmop.com\/index.php\/wp-json\/wp\/v2\/categories?post=324"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.drmop.com\/index.php\/wp-json\/wp\/v2\/tags?post=324"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}