Yes, the approach you are using is not especially ideal.
Games use compression all the time, but you must recognize the tradeoffs you are making.
The ideal is when the compressed object is used directly. Graphics formats like ASTC and DDS are good examples, they are compressed in a format that can be directly used in graphics cards. They are not as tightly compressed as png or JPEG formats, which have an expensive step to decompress requiring both processing time and significant memory.
Games also use streaming compression as described above. Resources are quite often loaded sequentially so streaming it in can decompress on the fly. There are many libraries that focus on efficient decoding, paying a higher cost to encode and generating a better data dictionary and better results so decoding takes less memory and less processing.
Random access in files as you describe approaches the worst case for compressed files. Formats can provide options to estimate where blocks begin and end, but it is not a direct location in the data stream. A single byte location may encode three data tokens that happens to expand to twelve bytes, the next 8 bits may happen to expand to two bytes, and the next may encode less than a single byte. It is difficult to seek to a position in the decompressed file without actually decoding the data before it. Block formats are a little easier, you can seek to a block but still need to decode starting at the beginning of the block and going until you reach the desired offset.
Games use gigabytes because it is available to them. While some games waste it, many leverage all they can and will still be able to use more.
Finally, there are libraries out there that try to bridge the gap for you. PhysFS generally works like a file system but abstracts the compression and packaging away. It can do the work, following the efficient patterns and also allow you to access the data with inefficient patterns with relative ease. It still does the work, but does it behind your back.