Check out a free preview of the full Basics of Go course
The "Writing Files" Lesson is part of the full, Basics of Go course featured in this preview video. Here's what you'd learn in this lesson:
Maximiliano illustrates the process of writing a file using os.WriteFile and creating more intricate messages with fmt.Sprintf. The segment also addresses a student's question about whether package names and directories must match.
Transcript from the "Writing Files" Lesson
[00:00:00]
>> So what if we wanna write the file? For example, when I write the second file with some content, actually, it's relatively similar. So for that, I'm going to create another file the same package. Can I have more than one file in your package? Yeah, you can have as many files as you want.
[00:00:18]
In fact, look at this. Have I used the name reader anywhere? No, this can be go, like that, and it works anyway. File names are not important for the compiler. We don't use file names. The name of the go file doesn't matter. What matters is the name of the package.
[00:00:43]
We teach you a couple of questions, but no one asks yet. But can we have packages in subfolders? Can I create a hierarchy of packages? The first quick answer is no. The idea is to keep only one level of packages. Then you can organize your packages by the name.
[00:01:04]
Because they are part of this project or the other project, okay. But the idea is not to have fileutils, reader, fileutils, in the file system at least. Internally, you can work with the string, so it feels like it's a sub-package, okay? But actually, it doesn't work. There is something known as internal, not when you get there because it's an advance and not really something that we use a lot in Go, but a package can have an internal sub-package.
[00:01:34]
There's another package that works only for that package, something like that, like a private package. It's only one, it's called internal. And it's for a more advanced situation, so we won't cover that. Okay, so within the same fileutils package, I'm not going to create another package. I could, but let's use fileutils for both.
[00:01:55]
I'm going to create a new file for the writer. is given an error why? Because that file must contain the same pack cache name as the other files in the folder. Okay, and in this case, we're going to create another function. So we create a function export the function right to fire but we received filename and the content as a string.
[00:02:24]
And maybe in this case, we can return an error or nil. So we don't need the pair because we are not returning any value but we may we may return an error. In this case we are going to call OLS right file. When I press Enter, you will see it will add import OS for me.
[00:02:47]
And we already have the file name. And we just need to pass the content. The problem is the content that right file is expecting is actually in slice of byte. Okay, so yeah, and we have the string. Fortunately for us because we can convert a slice of a string into Slice of VITs, we can do the reverse operation as well.
[00:03:13]
So we use the name of the type is slice of white, and we use that as a function. Because it's a function name starting with with a symbol, which is weird, but it works, okay. Remember I mentioned that the documentation is actually available in the CLI. So you can say go doc, nothing appear because say go when you say doc, it show documentation for a package.
[00:03:45]
So the next step is to add the package. So go doc, the package is OS. Then go doc, OS, write file, and it give me the information. So sometimes it's faster to go and type that, in case you don't have the IDE, the IDE is not working, you can use the CLI to actually get the documentation of one specific function.
[00:04:12]
But in this case, I think I would prefer to go and try to read this directly from the document. I want to show you the example that they are mentioning here, so we go to learn, sorry, dogs standard library. We get into OS, the OS and within the OS, we look for me decrease the font size a little bit to get the menu.
[00:04:40]
So I can get all the functions here. Let's search for right file because I typically have an example. So you can see we have the devils in the details. Well in this case, the devil is in the sample because we have 0666 as the permission number that you see because this is using flags.
[00:05:09]
So we need to apply several flags at once. We need to match the flags binary intersection. It doesn't matter. We can try this to see if that works that value should work on every OS, is one of the standard permissions that you use. Okay, so this is returning me, an error.
[00:05:34]
So then I can check. I can just, even I don't need to greet the buyer. Well, I can just return this, because it's exactly the type that we are returning here. Nothing fancy actually, but at least you can now call write file. For example, you can take the same file called fileutils write to file to the same file.
[00:06:01]
So I could create a variable with that so let's say this is the file path := to create a variable and then we will write to the same file but I'm going to add a .output.txt so it's another file not the same file. For the content I can use I'm going to create a new content, And I'm going to do something like this like the original.
[00:06:37]
Is C and then I wanna double the original is C and another C. But you can see that doing this, it's okay, we can concatenate the strings. It looks weird. We are used to templating, okay? So remember that we have, from the font library, we have the Printf.
[00:07:08]
But Printf is printing to the console. And I want to say something similar to the string. Well, for that, the format library actually has a solution. It's called Sprintf. S of have a string. So it's going to return a string with a format with the same format as printf.
[00:07:33]
And be careful because now we have the S and then print is lowercase. So if you don't if that what I'm doing give me a second and you will get it, so I'm going to go format s printf and the format will be a value. Then it can be in a new line, or it can say original, colon, the value, and then you can say double original.
[00:08:00]
I'm just duplicating the same thing, percentage v percentage v, so I need to pass 3 arguments, and the three arguments are actually the same. C, C and C, that is actually the original string remember that they are reading. So the output is going to be original, colon, the original text, a new line that will original and twice the same text.
[00:08:24]
But I'm using, The printf format. To generate a string that is pretty useful every time you are creating complex messages or something like that, we use sprintf from the format library. Actually, this is the library that we use the most for. Does it make sense? We will use this two format.
[00:08:53]
Outputs for example I mean it's not the case I will delete this in a minute but if you need to print you have a variable with a price again and the price is it's a real number. And you need to print this okay or you wanna save a string version of it string price.
[00:09:11]
If you say a string of 34 or 3 is not going to work, it's not doing that conversion. Even if you print that, it will print things like this. Yeah, I don't want that for a price. So a simple way to make a conversion is to talk to format Sprintf, and because it's s printf will receive any kind of value, it can receive also float.
[00:09:38]
So I can say f with the price. And also I can say you know what, I want only two decimals and you use for that dot 2% dash the 2 F that's a float, only with two decimals. And then you have a string. Again, not for this particular sample in particular, but it's another usage for Sprintf.
[00:10:01]
It's a quick way to make conversions to a string, and to format different values into strings.
>> Okay, make sense? Any question? This was to play with the OS a little bit, to see the error management in action, how that works, how to receive two arguments, and also to use just because we're here Sprintf.
[00:10:28]
That we used the same print with format, but instead for output to the console to receive a string that's the idea
>> A couple of questions on or clarifications on packages should package names and directories always have the same
>> Nope, in fact, you can see here it says fileutils.
[00:10:52]
Let me change that now to FileIO, and everything works. The only thing I need to change is the, what I need to change here. No, I need to change anything. I think it's. Okay, so because here the important part is the package name the way to change that I can of course if you do the change both package names you have the same name.
[00:11:18]
And now I need to change also the main because yeah it's a different by the way, can I change the name here but not the alias? I can, and for that, I keep the alias like so. So we use a space, and this is an alias because if not, by default, it's going to use the last part of the path.
[00:11:39]
FileIo, okay, that makes sense? So if you want to you can do this. And for that if you don't like format you can call it f but yeah, no we don't do that. But we can do that with our own package name in case you want to. So if I change to file IO, I should also change the reference here.
[00:11:59]
And now we are good. You said a couple of questions. Do have alias description just answered the second question [LAUGH]. Okay, by the way, now that we have more than one import here, we have something new that we haven't seen before. We have a parenthesis here. You see that?
[00:12:16]
I mean, you can guess what's going on. But this is called a block. So in this case an import block. So you can import two things in two different lines, or you can create an import block where you use parentheses, not curly braces, parentheses. And then inside you put all the values.
[00:12:36]
And we can also call blocks for variables. Well, yeah, it can be constant as well. So not for functions. We can say bar, and then we create a as an integer, and n as a string, and then you just use bar ones. It's not a big deal, [LAUGH] but you can create these blocks as well.
[00:12:58]
At package level only, not within the function at package level.
Learn Straight from the Experts Who Shape the Modern Web
- In-depth Courses
- Industry Leading Experts
- Learning Paths
- Live Interactive Workshops