I'll provide an S3 answer, since it is one of your tags. Amazon's S3 allows you to set permissions on files, and create a signed URL with an expiry time. Using these two ideas together, it is possible to create a system that functions as a one time use URL. Additionally, S3 has two levels of storage, so if redundancy isn't a major factor for you, it is possible to save a bit by using the reduced redundancy storage. As with all AWS services though, you will have to pay for bandwidth used. S3 also charges a fee per request to your files.
Unlike the typical S3 implementation, where the file permissions are set to public, here you will be setting the permissions to private, and signing with your access key to grant access.
If you do not care whether your clients share the link with others or download multiple times (so long as they cannot access any other files) then the implementation is quite simple, you will just need to create a (reasonably far) future expire date with the signed URL. So, for instance, you upload your file to S3 (it is private by default); create a signed URL with a one week expiry; and your client, within the next week, can access the file using the URL provided, as many times as they wish. They cannot access any other files, since they do not have signed URLs - and all the files are private.
The problem with the above scenario is one of time - you don't want to keep a URL available for too long, yet you need to give enough time for your client to access the file - it also takes some effort to validate that your client has in fact viewed the file (i.e. you would turn on logging on S3, and check your logs).
The alternate scenario requires a partial implementation on your site, instead of being fully reliant on S3. Create a page that accepts an unique ID (stored in a database) and send your client a link to your page including that ID. When your client accesses the page, you generate a signed S3 URL that expires in the near future (30s). (At the same time, you can of course, log that the ID is no longer valid and that your client has accessed the file). Launch the download using the generated URL. In this way, clients can only use the URL once - they cannot make it available to others (although, they could always make the file itself available to someone else), they can use the link you email them at any time (since there is no expiry on that), and since you are using signed URLs, they cannot access any other files (even if they guess the paths/filenames).