Nipuna Kumaranathunga
4 min readMar 17, 2023

I have encountered numerous use cases where the need to save files such as images, attachments, and other documents arises. In this blog post, I will provide three options for implementing file storage in an enterprise application, along with their advantages and disadvantages, code samples, and references.

Option 1: Local File System Storage

The simplest and most straightforward way to store files in an enterprise application is to use the local file system. In this approach, the files are stored on a disk or a network file share accessible to the application server.

Advantages:

  • Simplicity: This approach is easy to implement and requires minimal setup.
  • Cost-effective: No additional costs are associated with using the local file system for storage.
  • High performance: Accessing files from the local file system is typically faster than accessing files from a remote storage service.

Disadvantages:

  • Limited scalability: The local file system approach is limited by the storage capacity of the server where the files are stored.
  • Single point of failure: If the server where the files are stored fails, the application will not be able to access the files.
  • Security concerns: The files may be accessible to unauthorized users if proper security measures are not implemented.

Code sample:

@PostMapping("/upload")
public String handleFileUpload(@RequestParam("file") MultipartFile file) throws IOException {
Path filePath = Paths.get("/path/to/your/storage/directory", file.getOriginalFilename());
Files.write(filePath, file.getBytes());
return "File uploaded successfully!";
}

References:

Option 2: Database Storage

Another option for storing files in an enterprise application is to use a database. In this approach, the files are stored as blobs in the database.

Advantages:

  • Easy to manage: Storing files in the database makes it easy to manage them, as they are stored along with other application data.
  • High availability: Most modern databases support replication and clustering, which provide high availability for the stored files.
  • Security: Database storage provides a more secure way to store files, as access to the files can be controlled through the database's security features.

Disadvantages:

  • Performance: Accessing files stored in a database can be slower than accessing files stored in the local file system.
  • Scalability: Storing large files in a database can cause performance issues and can limit the scalability of the application.
  • Cost: The cost of storing files in a database can be higher than the cost of using the local file system.

Code sample:

@PostMapping("/upload")
public String handleFileUpload(@RequestParam("file") MultipartFile file, Model model) throws IOException {
FileModel fileModel = new FileModel();
fileModel.setName(file.getOriginalFilename());
fileModel.setType(file.getContentType());
fileModel.setData(file.getBytes());
fileRepository.save(fileModel);
model.addAttribute("message", "File uploaded successfully!");
return "upload";
}

References:

Option 3: Cloud Storage

Cloud storage is another option for storing files in an enterprise application. Cloud storage providers such as Amazon S3 and Azure Blob Storage provide scalable and highly available storage services that can be used by applications.

Advantages:

  • Scalability: Cloud storage can scale up or down based on demand, making it ideal for enterprise applications that need to handle large volumes of files.
  • High availability: Cloud storage services are designed to be highly available, providing better reliability than local file system storage.
  • Security: Cloud storage providers offer a range of security features such as encryption and access controls, making it more secure than local file system storage.
  • Cost-effective: Many cloud storage providers offer pay-as-you-go pricing models, making it a cost-effective option for small to medium-sized applications.

Disadvantages:

  • Complexity: Setting up and configuring cloud storage can be more complex than using the local file system or a database.
  • Latency: Accessing files stored in the cloud can be slower than accessing files stored locally, particularly if the application is located far from the storage service.
  • Dependency: Using cloud storage requires a dependency on a third-party service, which may impact application availability if the service experiences downtime.

Code sample (using AWS S3):

@Autowired
private AmazonS3 amazonS3Client;

@PostMapping("/upload")
public String handleFileUpload(@RequestParam("file") MultipartFile file) throws IOException {
String bucketName = "your-bucket-name";
String key = file.getOriginalFilename();
byte[] content = file.getBytes();
ObjectMetadata metadata = new ObjectMetadata();
metadata.setContentLength(content.length);
ByteArrayInputStream inputStream = new ByteArrayInputStream(content);
amazonS3Client.putObject(bucketName, key, inputStream, metadata);
return "File uploaded successfully!";
}

References:

Code sample (using Azure Blob Storage):

import com.azure.storage.blob.BlobClientBuilder;
import com.azure.storage.blob.BlobContainerClient;
import com.azure.storage.blob.BlobContainerClientBuilder;
import com.azure.storage.blob.models.BlobHttpHeaders;
import com.azure.storage.blob.models.BlockBlobItem;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

public class AzureBlobStorageService {

private final String connectionString;
private final String containerName;

public AzureBlobStorageService(String connectionString, String containerName) {
this.connectionString = connectionString;
this.containerName = containerName;
}

public void uploadFile(MultipartFile file) throws IOException {
BlobContainerClient containerClient = new BlobContainerClientBuilder()
.connectionString(connectionString)
.containerName(containerName)
.buildClient();

String fileName = file.getOriginalFilename();

BlobClientBuilder blobClientBuilder = new BlobClientBuilder()
.connectionString(connectionString)
.containerName(containerName)
.blobName(fileName);

BlobHttpHeaders headers = new BlobHttpHeaders()
.setContentType(file.getContentType());

InputStream fileStream = file.getInputStream();
blobClientBuilder.buildClient().upload(fileStream, file.getSize(),
true, headers, null, null, null);
}

public List<String> listFiles() {
BlobContainerClient containerClient = new BlobContainerClientBuilder()
.connectionString(connectionString)
.containerName(containerName)
.buildClient();

List<String> fileList = new ArrayList<>();
for (BlockBlobItem blobItem : containerClient.listBlobFlatSegment()) {
fileList.add(blobItem.getName());
}
return fileList;
}

public void deleteFile(String fileName) {
BlobClientBuilder blobClientBuilder = new BlobClientBuilder()
.connectionString(connectionString)
.containerName(containerName)
.blobName(fileName);

blobClientBuilder.buildClient().delete();
}
}

To use this code sample, you would need to provide your own Azure Blob storage connection string and container name when creating an instance of the AzureBlobStorageService class. Then you can call the uploadFile() method to upload a file, listFiles() method to list all files in the container, and deleteFile() method to delete a file.

References:

Conclusion

In this blog post, we explored three options for implementing file storage in an enterprise application: local file system storage, database storage, and cloud storage. Each option has its own advantages and disadvantages, and the choice of which one to use depends on the specific needs of the application. I hope this post has provided you with the information you need to make an informed decision about which option is best for your enterprise application.