> For the complete documentation index, see [llms.txt](https://docs.zongsoft.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.zongsoft.com/documentation/en/framework/core/io.md).

# Zongsoft.IO

Upload the description of the virtual file system and path in the Discussions long text and attachments.

Discussions places short text in the database, saves longer text as a file, and saves the file path back to the data model. Zongsoft.IO provides a unified file interface, the actual local disk or object storage implementation is determined by the deployment.

## The Base Path Comes from Configuration

Source: [src/Zongsoft.Discussions.option](https://github.com/Zongsoft/Zongsoft.Discussions/blob/main/src/Zongsoft.Discussions.option#L1) (excerpt; see source for context).

{% code title="Zongsoft.Discussions.option" %}

```xml
<?xml version="1.0" encoding="utf-8" ?>

<options>
	<option path="/Discussions">
		<general siteId="1" basePath="zfs.s3:/zongsoft-discussions/" />
	</option>
</options>
```

{% endcode %}

The real configuration uses the zfs.s3 scheme. Operation requires a corresponding file system implementation and its own storage configuration; this path is not a public space directly available to document readers. Utility.GetFilePath then organizes directories by site, user, and relative paths.

## Write Text Using the Same Entry

Source: [src/Utility.cs](https://github.com/Zongsoft/Zongsoft.Discussions/blob/main/src/Utility.cs#L241) (excerpt; see source for context).

{% code title="Utility.cs" %}

```csharp
public static bool WriteTextFile(string path, string content)
{
	if(string.IsNullOrWhiteSpace(path))
		throw new ArgumentNullException(nameof(path));

	if(string.IsNullOrWhiteSpace(content))
		return false;

	using(var stream = FileSystem.File.Open(path, FileMode.Create, FileAccess.Write))
	{
		using(var writer = new StreamWriter(stream, System.Text.Encoding.UTF8))
		{
			writer.Write(content);
		}
	}

	return true;
}
```

{% endcode %}

FileSystem.File implementation is selected based on path; stream and text writers are released by scope. Database transactions cannot roll back the files that have been generated here, and the calling business needs to handle failure compensation.

## The Difference Between Content and Path

Source: [src/Utility.cs](https://github.com/Zongsoft/Zongsoft.Discussions/blob/main/src/Utility.cs#L48) (excerpt; see source for context).

{% code title="Utility.cs" %}

```csharp
public static bool IsContentEmbedded(string contentType)
{
	if(string.IsNullOrEmpty(contentType))
		return true;

	return contentType.TrimEnd().EndsWith(CONTENT_TYPE_EMBEDDED_SUFFIX, StringComparison.OrdinalIgnoreCase);
}
```

{% endcode %}

Empty type or +embedded suffix indicates that the content field saves the text; other types indicate external files. This tag is a Discussions business convention, not a universal MIME transport rule. After reading the external file, it should be marked as inline synchronously to prevent the downstream from using the text as a path again.

## HTTP Attachment Upload

Source: [src/api/Controllers/FileController.cs](https://github.com/Zongsoft/Zongsoft.Discussions/blob/main/src/api/Controllers/FileController.cs#L79) (excerpt; see source for context).

{% code title="FileController.cs" %}

```csharp
var infos = this.Accessor.Write(this.Request,
							  this.DataService.GetDirectory(id),
							  args => args.FileName = $"{Timestamp.Millennium.Epoch.GetElapsed().Days}-{Randomizer.GenerateString()}", cancellation);
```

{% endcode %}

The upload directory is calculated by the FileService, and the filename uses the epoch day and a random string. The controller then converts the file information into a business File model and cleans up the just-saved file when writing fails. The original client file name is different from the server storage name, and display and download should be interpreted according to the business model.

## Operation and Troubleshooting

Utility.ReadTextFile currently returns an empty string when the file does not exist or the read fails. When troubleshooting, you must check the path saved in the data, the file system plugin, the storage access permissions, and whether the file exists. You cannot attribute empty text to the database.

Set up an independent directory for each isolation environment; the site directory is a storage organization method and cannot replace interface permissions. For file models, content tags, and external storage sources, see [real case](/documentation/en/cases.md) and [Amazon Extension](/documentation/en/framework/externals/projects/amazon.md).


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.zongsoft.com/documentation/en/framework/core/io.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
