- A file is a unit of stored memory, usually on disk
- A file can also be... directories, buffers (standard input/output are files), a socket could be a file, a program is a file
- You can write to and read from a file
- Files may be plaintext or binary (or plaintext but not intended for human consumption: EDI, XML, JSON, base-64 encoding)
- The basic steps to follow are:
- Open the file
- Process the file
- Close the file
- There is a special
FILE * pointer built into the standard library
- You can open a file using
fopen()
- It takes two arguments (both strings): the path/name of the file to open and a mode:
"r" (reading, file input), "w" (writing, file output)
//open a file data.txt in the current working directory (CWD)
FILE *f = fopen("data.txt", "r");
//for writing instead:
FILE *f = fopen("data.txt", "w");
//you can also use relative paths:
FILE *f = fopen("../../mydata/data.txt", "r");
//you can use absolute paths:
FILE *f = fopen("/etc/shadow", "r");
- If
fopen fails, it returns NULL
- You may not have permission(s) to read/write a file, the file may not exist, etc.
- If you open a new file for writing that does not already exist, it will be create for you. However, if it did already exist, you will overwrite its data
- Once you are done processing the file, you should always close it
- To close a file use
fclose()
FILE *f = fopen("data.txt", "r");
//...
fclose(f);
- There are many ways to do file output, keep it simple:
- Use
fprintf(): same usage as printf but takes an additional first argument, the file you want to "print" to
FILE *f = fopen("data.txt", "w");
fprintf(f, "Hello world!\n");
int x = 10;
fprintf(f, "x = %d\n", x);
char name[] = "Chris";
fprintf(f, "hello, %s\n", name);
fclose(f);
- There are many dangerous ways to read from a file
- I'm going to keep it simple and safe:
fgetc, fgets
fgetc gets a single character at a time from the file
FILE *f = fopen("lorem.txt", "r");
int i;
char c = fgetc(f);
while(c != EOF) {
printf("%c\n", c);
c = fgetc(f);
}
fclose(f);
fgetc returns a special EOF (end of file) value when it gets to the end of a file
- It is generally more efficient to read an entire line at a time from a file:
fgets
fgets reads up to an entire line from the file: it stops when it reaches the first endline character \n OR it reaches the limit you gave it
- You provide a limit parameter that limits the number of characters/bytes that
fgets reads at a time to prevent buffer overflows
fgets reads an entire string from a file, *fgets(char *s, int size, FILE *stream);
s is the string that the line will be stored in (it is your responsibility to ensure it is "big enough")
size limits the number of byte reads, fgets will actually only read at most size-1 bytes; it automatically inserts the null terminator for you!
stream is the file you are reading from
- It returns a
char * pointer (which points to the same buffer string you read into) BUT when you reach the end of a file, it returns NULL
FILE *f = fopen("lorem.txt", "r");
char buff[100];
char *s = fgets(buff, 100, f);
while(s != NULL) {
//you can remove the endline character as follows:
//removing the endline character is known as "chomping"
buff[strlen(buff)-1] = '\0';
printf("%s\n", buff);
s = fgets(buff, 100, f);
}
fclose(f);
- C provides both
fread for reading binary data and fwrite
size_t fwrite(const void *restrict ptr, size_t size, size_t nitems, FILE *restrict stream);
- Java provides a
File class
File f = new File("file.txt");
File f = new File("/path/to/some/file.txt");
File f = new File("/../../mydata/file.txt");
//input:
Scanner s = new Scanner(f);
int x = s.nextInt();
String line = s.nextLine();
//closing: you close the scanner not the file
s.close();
//reading a file line by line:
File f = new File("data.txt");
Scanner s = new Scanner(f);
while(s.hasNextLine()) {
String line = s.nextLine();
System.out.println(line);
}
- There are at least a dozen ways to do file output
- Simplest: use a
PrintWriter to do file output
File f = new File("outputdata.txt");
PrintWriter pw = new PrintWriter(f);
pw.println("hello!");
pw.print("no endline character here, do it manually:\n");
int x = 10;
pw.printf("%d\n", x);
pw.println("x = " + x);