# File.WriteAllBytes(..., about: row)

> Write a file by path ABOUT a row — a receipt for an order, a label for a shipment — and the row finds it again: File.About(row) lists its files, File.DeleteAbout(row) deletes them, and deleting or restricting the row takes its files with it. A path-written file with no `about:` is tied to nothing, and no erasure can ever find it.

<!-- id: storage-file-about · area: storage · stability: preview · html: https://osysharp.com/reference/storage/file-about/ -->

## Summary        {#summary}
A file written by path — `receipts/{order.Id}.pdf` — is just bytes at an address. Written with `about: order`, it is
also recorded against the order, so everything that later has to reach "every copy of this person's data" can:

- `File.About(row)` — the paths written about the row;
- `File.DeleteAbout(row)` — deletes them, answering how many;
- deleting the row, or restricting it ([restricted rows and purpose reads (Restriction, [PurposeRead])](https://osysharp.com/reference/security/restriction/)), deletes its files after the commit.

## Signature      {#signature}
```osy syntax
bool         File.WriteAllBytes(string path, byte[] bytes, about: row)
bool         File.WriteAllText(string path, string text, about: row)
List<string> File.About(row)
int          File.DeleteAbout(row)
```

## Description    {#description}
Needs `use Osysharp.Storage;` (the register lives there). `about:` takes a stored row of any entity; writing the same
path about the same row twice records it once. A restricted row's renderings are deleted rather than kept: a purpose
read renders them again when the purpose needs them.

If a file cannot be deleted when its row goes, its register entry stays — so `File.About` and
`Assert.NoTraceOf` ([Assert.NoTraceOf(token)](https://osysharp.com/reference/testing/assert-no-trace-of/)) still find it, rather than the copy silently surviving.

## Examples       {#examples}
```osy title="a receipt about an order" test app=storage-file-about
app Shop { use Osysharp.Storage; }

entity Order {
  [Required, MaxLength(20)] string Number;
  [MaxLength(200)] string? Buyer;
  security { allow read, create, update, delete when IsAuthenticated || IsAnonymous; }
}

string WriteReceipt(Order o) {
  var path = $"receipts/{o.Number}.txt";
  File.WriteAllText(path, "Receipt for " + o.Buyer, about: o);
  return path;
}
```

```osy title="the order finds its receipt, and takes it when it goes" run app=storage-file-about
[Test]
void A_receipt_goes_with_its_order() {
  var o = new Order { Number = "O-1", Buyer = "Ann" };
  UnitOfWork.Commit();
  var path = WriteReceipt(o);
  Assert.Equal(1, File.About(o).Count);
  o.Delete();
  UnitOfWork.Commit();
  Assert.False(File.Exists(path));
}
```

## See also       {#see-also}
- [Files (addressing something the app stores)](https://osysharp.com/reference/storage/index/) — the two ways the platform stores a file
- [restricted rows and purpose reads (Restriction, [PurposeRead])](https://osysharp.com/reference/security/restriction/) — a restricted row takes its renderings with it
- [Assert.NoTraceOf(token)](https://osysharp.com/reference/testing/assert-no-trace-of/) — proving a person's data is gone, files included
