### Summary

If you have write permissions for the file you want to encrypt, but not for the directory it's in, `ansible-vault encrypt` corrupts the file.

My colleague originally encountered this problem on `ansible [core 2.13.1]` with `python version = 3.8.10`, which I believe is the version from the Ubuntu 20.04 package repo, but I managed to reproduce it on a fresh install of ansible core 2.15.2.

I'd upload the original and corrupted file but my corporate firewall stupidly blocks gists and that's too annoying to work around right now. If you do think the files would help, just let me know and I'll make it work.

### Issue Type

Bug Report

### Component Name

ansible-vault

### Ansible Version

```console
$ ansible --version
ansible [core 2.15.2]
  config file = None
  configured module search path = ['<homedir>/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = <homedir>/test_ansible/lib/python3.10/site-packages/ansible
  ansible collection location = <homedir>/.ansible/collections:/usr/share/ansible/collections
  executable location = <homedir>/test_ansible/bin/ansible
  python version = 3.10.12 (main, Jun 11 2023, 05:26:28) [GCC 11.4.0] (<homedir>/test_ansible/bin/python3)
  jinja version = 3.1.2
  libyaml = True
```


### Configuration

```console
# if using a version older than ansible-core 2.12 you should omit the '-t all'
$ ansible-config dump --only-changed -t all
CONFIG_FILE() = None
```


### OS / Environment

Ubuntu 22.04 LTS

### Steps to Reproduce

Consider the following directory and file.

```bash
> ls testdir/
drwxr-sr-x 2 root     some_group 4,0K 2023 Aug 07 (Mo) 11:34 .
-rw-rw---- 1 root     some_group 3,7K 2023 Aug 07 (Mo) 11:34 .bashrc
```

I'm not the owner of the file or directory but I'm part of that group. Because of a config error on my part, the directory is missing group write permissions. (I'm not actually trying to encrypt my .bashrc, that's just a convenient file for reproducing the problem.) I _am_ able to write to the existing file but I'm not able to create new files in that directory without using sudo. I think ansible-vault tries to move the new, encrypted file into the directory. That fails of course, and somehow corrupts the file in the process.

```bash
> ansible-vault encrypt testdir/.bashrc
New Vault password:
Confirm New Vault password:
ERROR! Unexpected Exception, this is probably a bug: [Errno 13] Permission denied: '<path>/testdir/.bashrc'
to see the full traceback, use -vvv
> less testdir/.bashrc
"testdir/.bashrc" may be a binary file.  See it anyway?
```

.bashrc is now in a corrupted state, as indicated by `less` recognizing it as binary.

If the group doesn't have write permissions on the file, ansible-vault fails with the same error message and the file is, correctly, not touched. The corruption happens because ansible-vault is able to write to the file.

### Expected Results

Ansible-vault should either correctly encrypt and write the file or should fail and leave the file untouched. Under no circumstance should it corrupt my file.

### Actual Results

```console
> ansible-vault encrypt -vvv testdir/.bashrc
New Vault password:
Confirm New Vault password:
ERROR! Unexpected Exception, this is probably a bug: [Errno 13] Permission denied: '<path>/testdir/.bashrc'
the full traceback was:

Traceback (most recent call last):
  File "<homedir>/test_ansible/lib/python3.10/site-packages/ansible/cli/__init__.py", line 659, in cli_executor
    exit_code = cli.run()
  File "<homedir>/test_ansible/lib/python3.10/site-packages/ansible/cli/vault.py", line 248, in run
    context.CLIARGS['func']()
  File "<homedir>/test_ansible/lib/python3.10/site-packages/ansible/cli/vault.py", line 261, in execute_encrypt
    self.editor.encrypt_file(f, self.encrypt_secret,
  File "<homedir>/test_ansible/lib/python3.10/site-packages/ansible/parsing/vault/__init__.py", line 906, in encrypt_file
    self.write_data(b_ciphertext, output_file or filename)
  File "<homedir>/test_ansible/lib/python3.10/site-packages/ansible/parsing/vault/__init__.py", line 1083, in write_data
    self._shred_file(thefile)
  File "<homedir>/test_ansible/lib/python3.10/site-packages/ansible/parsing/vault/__init__.py", line 837, in _shred_file
    os.remove(tmp_path)
PermissionError: [Errno 13] Permission denied: '<path>/testdir/.bashrc'

> less testdir/.bashrc
"testdir/.bashrc" may be a binary file.  See it anyway?
```


### Code of Conduct

- [X] I agree to follow the Ansible Code of Conduct
except KeyError:
            raise AnsibleError(u"{0} cipher could not be found".format(self.cipher_name))
        
        if vault_id:
            display.vvvvv(u'Encrypting with vault_id "%s" and vault secret %s' % (to_text(vault_id), to_text(secret)))
        else:
            display.vvvvv(u'Encrypting without a vault_id using vault secret %s' % to_text(secret))
        b_ciphertext = this_cipher.encrypt(b_plaintext, secret, salt)
        
        b_vaulttext = format_vaulttext_envelope(b_ciphertext,
                                                self.cipher_name,
                                                vault_id=vault_id)
        return b_vaulttext
    def decrypt(self, vaulttext, filename=None, obj=None):
        '''Decrypt a piece of vault encrypted data.
        :arg vaulttext: a string to decrypt.  Since vault encrypted data is an
            ascii text format this can be either a byte str or unicode string.
        :kwarg filename: a filename that the data came from.  This is only
            used to make better error messages in case the data cannot be
            decrypted.
        :returns: a byte string containing the decrypted data and the vault-id that was used
        '''
        plaintext, vault_id, vault_secret = self.decrypt_and_get_vault_id(vaulttext, filename=filename, obj=obj)
        return plaintext
    def decrypt_and_get_vault_id(self, vaulttext, filename=None, obj=None):
        """Decrypt a piece of vault encrypted data.
        :arg vaulttext: a string to decrypt.  Since vault encrypted data is an
            ascii text format this can be either a byte str or unicode string.
        :kwarg filename: a filename that the data came from.  This is only
            used to make better error messages in case the data cannot be