summaryrefslogtreecommitdiff
path: root/fatfs/documents/doc/lseek.html
blob: ffd1f6221d4097700808bbe422080a23a86f7d28 (plain)
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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Style-Type" content="text/css">
<link rel="up" title="FatFs" href="../00index_e.html">
<link rel="alternate" hreflang="ja" title="Japanese" href="../ja/lseek.html">
<link rel="stylesheet" href="../css_e.css" type="text/css" media="screen" title="ELM Default">
<title>FatFs - f_lseek</title>
</head>

<body>

<div class="para func">
<h2>f_lseek</h2>
<p>The f_lseek function moves the file read/write pointer of an open file object. It can also be used to expand the file size (cluster pre-allocation). </p>

<pre>
FRESULT f_lseek (
  FIL*    <span class="arg">fp</span>,  <span class="c">/* [IN] File object */</span>
  FSIZE_t <span class="arg">ofs</span>  <span class="c">/* [IN] Offset of file read/write pointer to be set */</span>
);
</pre>
<pre>
FRESULT f_rewind (
  FIL*    <span class="arg">fp</span>   <span class="c">/* [IN] File object */</span>
);
</pre>
</div>

<div class="para arg">
<h4>Parameters</h4>
<dl class="par">
<dt>fp</dt>
<dd>Pointer to the open file object.</dd>
<dt>ofs</dt>
<dd>Byte offset from top of the file to set read/write pointer. The data type <tt>FSIZE_t</tt> is an alias of either <tt>DWORD</tt>(32-bit) or <tt>QWORD</tt>(64-bit) depends on the configuration option <tt><a href="config.html#fs_exfat">FF_FS_EXFAT</a></tt>.</dd>
</dl>
</div>


<div class="para ret">
<h4>Return Values</h4>
<p>
<a href="rc.html#ok">FR_OK</a>,
<a href="rc.html#de">FR_DISK_ERR</a>,
<a href="rc.html#ie">FR_INT_ERR</a>,
<a href="rc.html#io">FR_INVALID_OBJECT</a>,
<a href="rc.html#tm">FR_TIMEOUT</a>
</p>
</div>


<div class="para desc">
<h4>Description</h4>
<p>File read/write ponter in the open file object points the data byte to be read/written at next read/write operation. It advances as the number of bytes read/written. The <tt>f_lseek</tt> function moves the file read/write pointer without any read/write operation to the file. The <tt>f_rewind</tt> function is impremented as a macro.</p>
<pre>
#define <em>f_rewind</em>(fp) f_lseek((fp), 0)
</pre>
<p>If an offset beyond the file size is specified in write mode, the file size is expanded to the specified offset. The file data in the expanded part is <em>undefined</em>, because no data is written to the file in this process. This is suitable to pre-allocate a data area to the file quickly for fast write operation. When a contiguous data area needs to be allocated to the file, use <tt>f_expand</tt> function instead. After the <tt>f_lseek</tt> function succeeded, the current read/write pointer should be checked in order to make sure the read/write pointer has been moved correctry. In case of the read/write pointer is not pointing expected offset, either of followings has been occured.</p>
<ul>
<li>End of file. The specified <tt class="arg">ofs</tt> was clipped at end of the file in read-only mode.</li>
<li>Disk full. There is no free space on the volume to expand the file.</li>
</ul>
<p>The fast seek feature enables fast backward/long seek operations without FAT access by using an on-memory CLMT (cluster link map table). It is applied to <tt>f_read</tt> and <tt>f_write</tt> function as well, however, the file size cannot be expanded by <tt>f_write</tt>, <tt>f_lseek</tt> function while the file is at fast seek mode.</p>
<p>The fast seek mode is available when <tt>FF_USE_FASTSEEK = 1</tt>. The CLMT must be created into the <tt>DWORD</tt> array prior to use the fast seek mode. To create the CLMT, set address of the <tt>DWORD</tt> array to the member <tt>cltbl</tt> in the open file object, set the size of array in unit of items to the <tt>cltbl[0]</tt> and then call <tt>f_lseek</tt> function with <tt class="arg">ofs</tt><tt> = CREATE_LINKMAP</tt>. After the function succeeded, no FAT access is occured in subsequent <tt>f_read</tt>, <tt>f_write</tt>, <tt>f_lseek</tt> function to the file. The number of items used or required is returned into the <tt>cltbl[0]</tt>. The number of items needed is (number of the file fragments + 1) * 2. For example, 12 items in the array will be used for the file fragmented in 5 portions. If the function failed with <tt>FR_NOT_ENOUGH_CORE</tt>, the size of given array is insufficient for the file.</p>
</div>


<div class="para comp">
<h4>QuickInfo</h4>
<p>Available when <tt><a href="config.html#fs_minimize">FF_FS_MINIMIZE</a> &lt;= 2</tt>. To use fast seek function, <tt><a href="config.html#use_fastseek">FF_USE_FASTSEEK</a></tt> needs to be set 1 to enable this feature.</p>
</div>


<div class="para use">
<h4>Example</h4>
<pre>
    <span class="c">/* Open file */</span>
    fp = malloc(sizeof (FIL));
    res = f_open(fp, "file.dat", FA_READ|FA_WRITE);
    if (res) ...

    <span class="c">/* Set read/write pointer to 5000 */</span>
    res = <em>f_lseek</em>(fp, 5000);

    <span class="c">/* Set read/write pointer to end of the file to append data */</span>
    res = <em>f_lseek</em>(fp, f_size(fp));

    <span class="c">/* Advance read/write pointer 3000 bytes */</span>
    res = <em>f_lseek</em>(fp, f_tell(fp) + 3000);

    <span class="c">/* Rewind read/write pointer 2000 bytes (take care on wraparound) */</span>
    res = <em>f_lseek</em>(fp, f_tell(fp) - 2000);
</pre>
<pre>
<span class="c">/* Cluster pre-allocation (to prevent buffer overrun on streaming write) */</span>

    res = f_open(fp, recfile, FA_CREATE_NEW | FA_WRITE);   <span class="c">/* Create a file */</span>

    res = <em>f_lseek</em>(fp, PRE_SIZE);             <span class="c">/* Expand file size (cluster pre-allocation) */</span>
    if (res || f_tell(fp) != PRE_SIZE) ...   <span class="c">/* Check if the file has been expanded successfly */</span>

    res = <em>f_lseek</em>(fp, OFS_DATA);             <span class="c">/* Record data stream with free from cluster allocation delay */</span>
    ...                                      <span class="c">/* Write operation should be aligned to sector boundary to optimize the write throughput */</span>

    res = f_truncate(fp);                    <span class="c">/* Truncate unused area */</span>
    res = <em>f_lseek</em>(fp, OFS_HEADER);           <span class="c">/* Set file header */</span>
    ...

    res = f_close(fp);
</pre>
<pre>
<span class="c">/* Using fast seek mode */</span>

    DWORD clmt[SZ_TBL];                    <span class="c">/* Cluster link map table buffer */</span>

    res = f_open(fp, fname, FA_READ | FA_WRITE);   <span class="c">/* Open a file */</span>

    res = <em>f_lseek</em>(fp, ofs1);               <span class="c">/* This is normal seek (cltbl is nulled on file open) */</span>

    fp-&gt;cltbl = clmt;                      <span class="c">/* Enable fast seek mode (cltbl != NULL) */</span>
    clmt[0] = SZ_TBL;                      <span class="c">/* Set table size */</span>
    res = <em>f_lseek</em>(fp, CREATE_LINKMAP);     <span class="c">/* Create CLMT */</span>
    ...

    res = <em>f_lseek</em>(fp, ofs2);               <span class="c">/* This is fast seek */</span>
</pre>
</div>


<div class="para ref">
<h4>See Also</h4>
<p><tt><a href="open.html">f_open</a>, <a href="truncate.html">f_truncate</a>, <a href="expand.html">f_expand</a>, <a href="sfile.html">FIL</a></tt></p>
</div>

<p class="foot"><a href="../00index_e.html">Return</a></p>
</body>
</html>