Programming C, C++, Java, PHP, Ruby, Turing, VB
Computer Science Canada 
Programming C, C++, Java, PHP, Ruby, Turing, VB  

Username:   Password: 
 RegisterRegister   
 [Tutorial] File I/O
Index -> Programming, Turing -> Turing Tutorials
Goto page 1, 2, 3  Next
View previous topic Printable versionDownload TopicRate TopicSubscribe to this topicPrivate MessagesRefresh page View next topic
Author Message
Clayton




PostPosted: Wed Jun 21, 2006 3:12 pm   Post subject: [Tutorial] File I/O

File Input/Output


Well i was looking through the Improving Tutorials thread and I saw that the File I/O was said to be a little rough around the edges so ive decided to try and fix it up a little bit Smile.

Whats Going to be Covered

All commands associated with File I/O (except mod, and if anybody could PM me an explanation of what it does it would be much appreciated), which are:
open
close
put
get
read
write
seek
tell
eof


I will show you an example of each command in action as well as an explanation of how to use it.

How do I use a File to Begin With?

The answer to that question is really quite simple, and I will go over that right now.

To use a file to input or take information from you must first open the file.

Turing:

var stream : int
open : stream, "filename.txt", put


Alright, what I've done here is opened the text file "filename.txt" along the file path "stream". I've done this because you need to have an integer file path (which does not get initiated) so that the computer knows which file you are using in the event of more than one file being open at a time. Just ignore the "put" part of that open statement for now, we will come back to it later.

Now the actual syntax for open is as such

Syntax:
Turing:

open : fileNumber,fileName, I/O operation


Also, whenever you are done using the file, you should close it, even if you aren't going to be using it again in the program. This is done automatically whenever the run window is closed, but it is good practice to close a file when done with it. The syntax is as follows:

Turing:

close : fileNumber


So in our example above:

Turing:

close : stream


I've got the file open, now what?

Another good question. Now we come back to the "put" part of the open statement. In the open statement that we made we can add several things on the end, each of which allows us to do different things with our file. Here is the list of commands that you can use along with a description of each:

put: Well we all know that put outputs things to the screen, but did you know it outputs things to file as well? When putting things to file the syntax is slightly different however, it is as such:

Turing:

var stream : int
open : stream, "myText.txt", put
put : stream, "This is how you put something to file"


Also note that you can put integers, real numbers, and booleans to file as well, and the process is exactly the same:

Turing:

var stream : int
open : stream, "myText.txt", put
put : stream, 42
put : stream, 2.112
put : stream, false


You can also put variables to file:

Turing:

var stream : int
var myPhrase : string := "This is how you put a variable to file"
open : stream, "myText.txt", put
put : stream, myPhrase


Simple as that and it works with any variable type Smile.

I can put stuff to the file, now I want to get it back

This is a simple thing to do as well. Very similiar to put, however there is a couple of differences. Like input from the run window you get information from your source (in this case our text file) with the command get. The syntax for get is the same as put for the most part other than the fact the command is get. Here is the syntax:

Turing:

get : fileNumber, information


Now when getting a value from a file you have to be careful that you are indeed getting a value that coincides with your variable type. For example, you can't give your int a value of "hello", it just doesn't work. Here is an example of how get works:

Turing:

var stream : int
var myText : string := ""
open : stream, "myText.txt", get %notice the file has to be in the "get" mode
get : stream, myText


It's as easy as that. Just make sure that your variable type is the same as the data that you are getting.

What if I don't want my file to be read?

Well there are a couple of ways to do this. You can use the read and write commands, or you can learn to encrypt your files (note this is an advanced technique not for beginners), which we will not be going over in this tutorial.

Now, you can semi-protect your information in a file by using the read and write commands. These commands are more or less identical to put and get with the exception that they write to a file in binary code, whereas put and get write to files in source, which means anyone with a text editor (like notepad) can read them.

Read and Write

Reading and writing to a file is very simple, it uses the same idea as put and get, but with different syntax, and it also uses different I/O modes: read and write

Here is an example of how to use each:

read (similiar to get)
Turing:

var stream : int
var myText : string
open : stream, "myText.txt", read
read : stream, myText


And for write (similiar to put)
Turing:

var stream : int
var myText : string := "This is how to write to a file"
open : stream, "myText.txt", write
write : stream, myText


Notice the similiarities to put and get?

Great, I know how to get my variables in and out of a file, what if a want to go to a certain line?

With the tell and seek commands, thats how!

tell and seek are two commands that have to do with positon in a file. tell can record a current position in the file for later use (like in a saved game file for re-loading), and seek can go to a given position in the file to start I/O operations. The syntax for both tell and seek are very similiar:

tell:
Turing:

tell : fileNumber, filePosition


seek:
Turing:

seek : fileNumber, filePosition


As you can see, they both use the same variables: fileNumber (called stream in this tutorial), and filePosition (the binary position in the file). Using a combination of seek and tell you can keep track of positions in files and go back to them. Here is an example of both in action (Note that the file has to be in the "seek" mode to be able to use either seek or tell)

Turing:

var stream : int
var filePosition : int
var myText : string := "An example of seek and tell"
open : stream, "myText.txt", put, seek
tell : stream, filePosition
put : stream, myText
seek : stream, filePosition


So all we've done there is found the initial location of data entry, recorded it, put myText to file, then gone back to where it was for future use.

Great, but what if I have more than one thing in my file?

Put it in a loop! Very Happy If you haven't learned flexible arrays yet i suggest that you do. When dealing with file I/O flexible arrays will be your best friend.

Now, when you are dealing with multiple (sometimes unknown) amounts of data coming in from a file, it is almost necessary to create an array. When you have done this, you can put the array in a loop getting one piece of data from the file one line at a time. Then when you have come to the end of the file you can exit the loop. Here is an example of how to get multiple lines of data from a file. Note I will be using flexible arrays here, if you don't understand them, don't worry, just concentrate on the idea of getting multiple lines of data from the file.

Turing:

var stream : int
var myText : flexible array 1..1 of string
open : stream, "myText.txt", get
loop
    exit when eof(stream)
    get : stream, myText(upper(myText))
    new myText, upper(myText) + 1
end loop


Now you notice how I used this little command "exit when eof (stream)" ?
eof is a command (meaning end-of-file) that calls a function that returns a boolean. If it is true, that means we have reached the end of the file and we exit our loop, otherwise, we keep going until eof = true. Note that you have to tell eof which file number you are using so that it knows which file to check. This is especially important if you have more than one file open.

For putting your multiple lines of data to a file the process is the same, but you should put all of your data into the file in a for loop with a dynamic upper bound.

Problems


1.Create a file in a text editor called "marks.txt" and fill it with one mark per line for at least 15 lines. Then, create a program that will import these marks into an array in your program and then calculate the averages of the marks and output the average on the screen.

2.Create a file in a text editor filled with at least 15 names and save it as "names.txt". Create a program to import these names from the file and then sort them, then put them on the run window sorted alphabetically, and into that file sorted alphabetically.

3.Create a program that creates 100 random numbers from 1-500, puts them in a file called"numbers.txt". Then create another program to import those same numbers, sort them, and putt hem back in the file sorted.

Closing

That is my tutorial on file I/O, if anybody has any questions, plz post or PM me and I willbe glad to answer them, anything you see that needs fixing should be PM'ed to me as well. I hope that you guys learned something from this tutorial. Very Happy
Sponsor
Sponsor
Sponsor
sponsor
aldreneo




PostPosted: Wed Jun 21, 2006 3:17 pm   Post subject: (No subject)

Good job, I was having trouble with the old "File O/I Tutorial"

+10 Bits Very Happy
Delos




PostPosted: Wed Jun 21, 2006 4:42 pm   Post subject: (No subject)

Great work. A couple things you should mention in there:

-
code:

get : fileNo, some_var : *


- write can only accept vars as parameters. No raw text. I.e., this won't work:
code:

write : fileNo, "Crashing..."


- seek/tell: Files do not understand the concept of 'lines'. Everything in a file is a long strings of characters, and end-of-line characters are no exception. Although a file might be rendered by a text pad as having lines, those breaks are actually characters. Hence:
text:

Hello
World

is roughly:
raw:

Hello/nWorld

Where '/n' is a single character - the line break.

- Additional parameters to read/write. I have found some of these insanely useful. Notice how if you were to create a file with nothing more than a single character in it, the file is still 32.0 KB? If I recall, using one of the additional paramters in 'write' ('actual size' methinks) can allow you to write files that are their actual size...so a single character file would be a few bytes, as oppoesd to 32.0 KB. I'm not positive whether the 'few bytes' registers as 'Actual Size' or 'Size on Disk'.
Even if it doesn't, they're good to know about. You could add those to an 'advanced' section of the tut.

- Speaking of which, I would advise you to break this down into 3 sections: Beginner, Intermediate, Advanced...use these as rough guidelines:
+Beginner: put/get
+Intermediate: read/write
+Advanced: further read/write, seek/tell
Questions at the end of each would be prime. Once they're done, you can post each in a seperate post (in this thread!) and either Cervantes or myself will then rearrange a few posts to ensure that all 3 parts follow each other (so don't worry about others posting in here).

I'll let Cervantes handle the bits - seeing as he has so many to spare these days Laughing.
Clayton




PostPosted: Wed Jun 21, 2006 4:52 pm   Post subject: (No subject)

All right Very Happy thanks for the ideas! I'll begin to work on a Beginner, Intermediate, Advanced level tutorial and delete this one eventually Very Happy thanks for the notice on write only being able to accept variables, I never knew that, seeing as I only use variables when passing information to file anyways Very Happy
Cervantes




PostPosted: Wed Jun 21, 2006 10:12 pm   Post subject: (No subject)

Looks nice.

Beginner/Intermediate/Advanced is a good idea. File I/O is a big topic -- probably too much for the average Turing high school programmer to digest in one sitting.

I think some deeper expainations are warranted. You really glossed over how get works. That is, it gets text until whitespace. get with the additional ": *" gets a whole line. It's useful to think of having an imaginary cursor in your file when you're getting data from it. The cursor starts at the beginning of the file (bytes = 0) and moves along. Emphasize that this imaginary cursor can't move backwards -- only forwards.

More detail regarding read and write: One of the greatest things about read/write is that they can work with large data structures as easily as they can work with the primitive data types. That is, I define a custom data type that is really big and has lots of fields. Variables of that data type can be written to a data file just by writing the variable. The entire variable can then be read in using only one read line. Using put/get, I would have to manually put/get each field of the record.

seek/tell: Emphasize that the integer parameter that seek accepts and the value tell stores in the variable you give it (oh gosh, what a horrible side-effect).... emphasize that this integer is the number of bytes since the beginning of the file. Delos' explanation of file structure is useful here.

Your examples and sample problems are all variations on the same thing. File I/O can be more complex than simply inputting and outputting line after line linearly. Consider a data file that represents a maze. A "#" character might represent a wall while a "." character might represent an empty space. The data file would have lots of these characters on a single line. You'd want to read this information into a 2D array.

And of course, mod. mod allows us to alter the contents of a file without totally erasing it. This is most useful for appending data onto the end of a file. It is also possible to overwrite data in the middle of a file (you might seek to that spot in the middle of the file). However, it must be understood that overwriting data in the middle of a file is just changing the bits in those specific positions in the file. It is not inserting new bits into the middle of the file.It's rather like using the 'replace' style of cursor in a text editor rather than the 'insert' style.

Edit: Oh, and there's the matter of bits, of course. I'm going to only give 100 bits now, but there's much more to come if you add these details Delos and I have mentioned. Smile
War_Caymore




PostPosted: Fri Sep 22, 2006 11:21 am   Post subject: (No subject)

hey, this is war_caymore saything taht i read this and i msut say, i can actualy open a program into turing now. i was confused by the Turing Refrence help and this all made it clear to me. you can all hope to see some good things from me within the next couple of months.

war_caymore
BenLi




PostPosted: Thu Sep 28, 2006 4:10 pm   Post subject: (No subject)

thank you this has been helpful in re-learning file io

however, you stated that write and read writes files in binary. Why is it, after i used write to create a txt file that i can still open it and it looks like normal text?
Cervantes




PostPosted: Thu Sep 28, 2006 6:06 pm   Post subject: (No subject)

BenLi wrote:
however, you stated that write and read writes files in binary. Why is it, after i used write to create a txt file that i can still open it and it looks like normal text?

All files are binary files. Everything the computer does is in binary. The only reason some files are called binary files whereas some are called ASCII files (or some other name) is because binary files are intended to be read assuming each group of 0's and 1's is a number. So we might be working with 2-byte integers, meaning reading a binary file involves reading 2 bytes at a time and interpreting them as a number.

With ASCII files, however, the binary data is intended to be read as 1-byte integer, then converted to a character based on the ASCII table.

So it's entirely possible that a binary file that contains some numbers could be perfectly coherent text in English.

However, chances are more likely that you sent the english text to the file using write, with the secret intention that it would be english text.


One final note about binary files: they are often organized into blocks. Each block might be 256 integers. So if you're reading 2-byte integers, each block will be 512 bytes. This kind of organization makes it easy to seek to the place you want (you have to know exactly where you want to go, though, or nothing will make sense), but it often means sections of the file will be empty (contain only 0's).
Sponsor
Sponsor
Sponsor
sponsor
lord_pwnerer




PostPosted: Tue Oct 17, 2006 7:48 pm   Post subject: (No subject)

I've read all the turing tutorials on File I/O and still am uncertain about how to read a certain line, and then another certain line. And so on and so forth.

I know that
code:
get : fileNumber, txt :*

gets the the first line

and I've heard of seek, but don't quite understand it. If someone could please explain this to me I would be gratefull.

Thanks
Clayton




PostPosted: Tue Oct 17, 2006 8:29 pm   Post subject: (No subject)

ok, do you understand how each character is stored in memory?

If your file looked like this (physically):

File wrote:

Hello
World
!


So if your file looked like this physically, in memory, it would look something like this (with newline characters (\n) being one character)

Memory wrote:

Hello\nWorld\n!


Now, when this is stored in memory, each character takes up one byte of memory. When you seek to a place in a file, you go to the byte position given. IE. If you had this file and you wanted to seek to "World", you would need to seek to byte 7 (Hello\n is seven bytes of memory), from there you can do what you want with the file (eg read from it or mod it) however, you cannot change the arrangement of the bytes in the file, when you mod something, you change the exact same amount of bytes as you took out.

Sorry if I haven't explained this very well, if someone else wants to take a stab at it be my guest Very Happy
lord_pwnerer




PostPosted: Wed Oct 18, 2006 4:24 pm   Post subject: (No subject)

code:
var iFile : int
var oFile : int
var txt : string

open : iFile, "INPUT.TXT", read, seek
seek : iFile, 7
read : iFile, txt
open : oFile, "OUTPUT.TXT", write
write : oFile, txt

my bad, I had it working, that's what I had, lol, is there a code to tell it when to stop? like read from seven to 10?
Cervantes




PostPosted: Wed Oct 18, 2006 7:40 pm   Post subject: (No subject)

lord_pwnerer wrote:
my bad, I had it working, that's what I had, lol, is there a code to tell it when to stop? like read from seven to 10?

Nope. You would do that yourself with for loops or recursion.

I don't remember any way to just get one character (byte) from a file. That would be useful here.
Silent Avenger




PostPosted: Wed Oct 18, 2006 8:08 pm   Post subject: (No subject)

Wow nice tutorial Freakman now if I ever have time to program with turing at school I'll know what I'm doing.
darkangel




PostPosted: Mon Dec 10, 2007 8:40 pm   Post subject: Re: [Tutorial] File I/O

to add...

code:
get : file , *


will find the end of said file so you can add things unto the file without erasing the old.
This (to me at least) is a lot easier than making flexible arrays....which are annoying.
Mackie




PostPosted: Sun Feb 03, 2008 2:01 pm   Post subject: RE:[Tutorial] File I/O

How would I create a file in Turing? I'm making an application and it requires saving you work.
Display posts from previous:   
   Index -> Programming, Turing -> Turing Tutorials
View previous topic Tell A FriendPrintable versionDownload TopicRate TopicSubscribe to this topicPrivate MessagesRefresh page View next topic

Page 1 of 3  [ 31 Posts ]
Goto page 1, 2, 3  Next
Jump to:   


Style:  
Search: