How can I create a Chatter File via Apex?

If you're asking how to upload files via Visualforce, or even just via Apex, there are code samples around: https://github.com/TehNrd/Multi-File-Uploader-Force.com shows how to upload via Visualforce to the Attachments object. To upload a File in general, you want to go to the ContentVersion object.

This is some code I wrote a while ago:

public static ContentVersion generateContentVersionFile(Boolean doInsert) {
    return generateNewContentVersionVersion(null, doInsert);
}

public static ContentVersion generateNewContentVersionVersion(Id contentDocId, Boolean doInsert) {
    ContentVersion cont = new ContentVersion();

    if (contentDocId != null) {
        cont.ContentDocumentId = contentDocId;
    }

    cont.Title = 'Title for this contentVersion';
    cont.PathOnClient = 'file_' + Datetime.now().getTime() + '.txt';
    cont.VersionData = Blob.valueOf('My Content in file_' + Datetime.now().getTime() + '.txt');
    cont.Origin = 'H';

    if (doInsert) {
        insert cont;
    }

    return cont;
}

public static FeedItem generatePostWithRelatedDocument(Id parent, Id contentVersionId) {
    FeedItem elm = new FeedItem(Body = 'Post with related document body', ParentId = parent, RelatedRecordId = contentVersionId, Type = 'ContentPost');
    insert elm;
    return elm;
}

Create Content Version

String yourFiles = 'All your info goes here';

ContentVersion conVer = new ContentVersion();
conVer.ContentLocation = 'S'; // S specify this document is in SF, use E for external files
conVer.PathOnClient = 'ionicLogo.png'; // The files name, extension is very important here which will help the file in preview.
conVer.Title = 'Proposal '; // Display name of the files
conVer.VersionData = EncodingUtil.base64Decode(yourFiles); // converting your binary string to Blob
insert conVer;

Link Content Version with record using Content document

// First get the content document Id from ContentVersion
Id conDoc = [SELECT ContentDocumentId FROM ContentVersion WHERE Id =:conVer.Id].ContentDocumentId;

//Create ContentDocumentLink
ContentDocumentLink cDe = new ContentDocumentLink();
cDe.ContentDocumentId = conDoc;
cDe.LinkedEntityId = yourObjectRecord.Id; // you can use objectId,GroupId etc
cDe.ShareType = 'I'; // Inferred permission, checkout description of ContentDocumentLink object for more details
cDe.Visibility = 'InternalUsers';
insert cDe;