#FileOutputStream uses old IO?

1 messages · Page 1 of 1 (latest)

tranquil hinge
#

I wanted to use FileOutputStream to write some primitive data to a file.
It seems this class takes File arguments and not the NIO Path.

Does that mean that this class is outdated? Is there an alternative? Why does the Java Platform API still use File?

wicked marlinBOT
#

<@&987246399047479336> please have a look, thanks.

#

Here is an AI assisted attempt to answer your question 🤖. Maybe it helps! In any case, a human is on the way 👍. To continue talking to the AI, you can use </chatgpt:1108714622413963314>.

#

s uses the old IO (java.io) instead of the newer NIO (java.nio) package?

Yes, that's correct. The FileOutputStream class is part of the old IO package (java.io) and it takes a File argument to specify the file to write to. It does not directly support the newer NIO Path class.

If you want to use Path with NIO, you can convert it to a File object using the toFile() method provided by the Path class. Here's an example:

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Path;

public class Main {
    public static void main(String[] args) {
        Path path = Path.of("example.txt");
        try (FileOutputStream fos = new FileOutputStream(path.toFile())) {
            // Write data using FileOutputStream
            fos.write(65); // Writing ASCII value of 'A'
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

In this example, we convert the Path object to a File object using the toFile() method and then pass it to the constructor of FileOutputStream.

vague crystal
#

arent all I/O streams part of the old system

fair apex
#

yes, they are

#

they are supposed to be used when u need more control over the process

#

and not just read/write and done

#

if u just want latter, use Files and not those streams

#

if u need more control, u can use those streams, but prefer creating them via the bridge methods

#

as explained at the end of this:

wicked marlinBOT
#

File IO in Java should be done preferably with NIO (Java 7+), revolving around the classes Files and Path; and not with the old interface File, BufferedReader, FileReader and similar.

NIO is simple to use. The path to a file is represented using the Path class:

Path path = Path.of("myFile.txt");

All file operations can be found in the Files class:

// Reading
List<String> allLines = Files.readAllLines(path);
// or as a single string
String content = Files.readString(path);
// or with a stream
try (Stream<String> stream = Files.lines(path)) {
  stream.forEach(System.out::println);
}

// Writing
Files.write(path, lines);
// or as a single string
Files.writeString(path, "hello world");
// or with extra options
Files.writeString(path, "hello world",
  StandardOpenOption.WRITE,
  StandardOpenOption.CREATE,
  StandardOpenOption.APPEND);

If you need more control over the process, you can fallback to the old interface, but prefer using the bridge methods from NIO (Files.newBufferedReader, Files.newInputStream, path.toFile() and similar) to benefit from advantages such as correct encoding and better error detection.

Here is a simple example of how to read a file line-wise with the old interface

try (BufferedReader br = Files.newBufferedReader(path)) {
  String line;
  while ((line = br.readLine()) != null) {
    System.out.println(line);
  }
}

it is way more verbose than NIO but it gives more control.

You must not forget to close file handles, even in all exceptional cases. Closing a handle manually is very hard, which is why you should always use try-with-resources for this to let Java automatically close the handle for you:

try (SomeResource resource = ...) {
  ...
} // Automatically closed here, even in exceptional cases
vague crystal
#

old system doesnt neccesarily mean bad

fair apex
#

old IO isnt straight out worse. its good for what it is

#

yeah exactly

#

the advantage of those streams is that u can plug them together as u prefer, like lego blocks

#

and build very custom things with that

tranquil hinge
#

I guess I can wrap the stream in a DataOutputStream

fair apex
#

its just that for the majority of use cases, all u want is to just read/write that one file there and call it a day

#

and for that, Files just provides the better interface

#

u mean u want to write objects like a Player class?

#

u want to use ObjectOutputStream for this

tranquil hinge
#

nah I just need writeInt and mayb something for writing strings

tranquil hinge
#

I mean I wouldn't

#

cuz it's more fun doing it manually

fair apex
#

and wrap it over the stream obtained via Files

#

the bridge methods

#

try (... = Files.newFileOutputStream(...)) {... }

tranquil hinge
#

right

#

I'll just wrap that in a DataOutputStream to write primitives

fair apex
#

wait. are u sure u want to write an int as int and not just as text?
ah frick my internet today... sorry, its way too slow to have a conversation

tranquil hinge
#

😅

#

int as int
I wanna do some binary serialization

#

To get a small file size

#

it's for fun, wanna learn from it

fair apex
#

why dont u just use sth like protobuffs then?

#

ah okay

tranquil hinge
#

ah

#

no

fair apex
#

yeah protobuf

#

its like json, but binary and compact

tranquil hinge
#

I don't want pre-defined contracts for how the data looks like

fair apex
#

so easy to use, but as slim as possible

tranquil hinge
#

my data is still in a json like format

#

I did look at protobuf

#

It does exactly what I want

#

except I can't have pre defined types

#

I dunno how my data is gonna look like, just a json like stucture

jolly portal
tranquil hinge
#

maps, lists, and values (string, int, bool)

#

e.g. have one byte say what type it is, if it's a list the next bytes will be the list size, and then the values etc.

#

I had to do something similar for my internship in C# and now I want to try to implement it for serializing in a data structure library I'm making

#

I know it's overcomplicated, that's the fun part

jolly portal
#

you could then simply use Files.write(Path, byte[]) or Files.newOutputStream(Path)

tranquil hinge
#

mhm

#

stream is more convenient cuz I can wrap it in a DataOutputStream to also be able to write primites like int and float

jolly portal
#

If you want json

tranquil hinge
#

nonnnon

jolly portal
#

you can simply us a json lib and pass it the outputstream

tranquil hinge
#

the whole point is trying binary serialization

#

for fun

#

I kinda forgot that Files could also do output streams

#

so I'll use that

#

I might also implement serialization to json in my lib

#

:]