[UWP]UWPアプリでファイルを作成~テキストを読み書き~画像を読み込み

tera1707.com

やりたいこと

UWPでファイル/フォルダを開いたり、そこにデータを読み書きする方法を部品どりで置いておきたい。
※いろんなやり方があると思うが、今回試した方法だけまずはメモする。

ファイルを開く

var folderPath = @"C:\Users\Public\Documents";
var fileName = @"myFile.txt";

StorageFolder sfolder = await StorageFolder.GetFolderFromPathAsync(folderPath);
StorageFile sfile = await sfolder.CreateFileAsync(fileName, CreationCollisionOption.ReplaceExisting);

テキスト読み書き

var folderPath = @"C:\Users\Public\Documents";
var fileName = @"myFile.txt";

StorageFolder sfolder = await StorageFolder.GetFolderFromPathAsync(folderPath);
StorageFile sfile = await sfolder.CreateFileAsync(fileName, CreationCollisionOption.ReplaceExisting);

// テキスト書き込み
await FileIO.WriteTextAsync(sfile, "あいうえお" + Environment.NewLine);
await FileIO.WriteTextAsync(sfile, "かきくけこ" + Environment.NewLine);// 「あいうえお\r\n」が消えて「かきくけこ\r\n」になる)
await FileIO.AppendTextAsync(sfile, "さしすせそ" + Environment.NewLine);// 追記されて「かきくけこ\r\nさしすせそ\r\n」になる

// テキスト読み込み
// ファイル内テキスト全部読み込み
var r1 = await FileIO.ReadTextAsync(sfile);
Debug.WriteLine(r1);

// 1行ずつ読み込み
var r2 = await FileIO.ReadLinesAsync(sfile);//IList<string>で行数の分だけ帰ってくる
foreach (var item in r2)
{
    Debug.WriteLine(item);//1行ずつ出力
}

テキスト読み書き(バイトデータとして)

var folderPath = @"C:\Users\Public\Documents";
var fileName = @"myFile.txt";

StorageFolder sfolder = await StorageFolder.GetFolderFromPathAsync(folderPath);
StorageFile sfile = await sfolder.CreateFileAsync(fileName, CreationCollisionOption.ReplaceExisting);

// バイトデータとして文字列を書き込み
IBuffer bufferW = CryptographicBuffer.ConvertStringToBinary("たちつてと", BinaryStringEncoding.Utf8);
await FileIO.WriteBufferAsync(sfile, bufferW);

// バイトデータとして文字列を読み込み
IBuffer bufferR = await FileIO.ReadBufferAsync(sfile);
var str = CryptographicBuffer.ConvertBinaryToString(BinaryStringEncoding.Utf8, bufferR);
Debug.WriteLine(str);

// バイナリデータとして文字列を読み込み
var ary = bufferR.ToArray();
foreach (var a in ary)
{
    Debug.Write(a.ToString("X2"));
    Debug.Write(",");
}

テキスト読み書き(stream使用)

var folderPath = @"C:\Users\Public\Documents";
var fileName = @"myFile.txt";
StorageFolder sfolder = await StorageFolder.GetFolderFromPathAsync(folderPath);
StorageFile sfile = await sfolder.CreateFileAsync(fileName, CreationCollisionOption.ReplaceExisting);

// ストリームを使って文字列を書き込み
using (StorageStreamTransaction transaction = await sfile.OpenTransactedWriteAsync())
{
    IBuffer buffer = CryptographicBuffer.ConvertStringToBinary("なにぬねの", BinaryStringEncoding.Utf8);
    await transaction.Stream.WriteAsync(buffer);
    transaction.Stream.Size = buffer.Length; // truncate file
    await transaction.CommitAsync();
}

// ストリームを使って文字列を読み込み
using (IRandomAccessStream readStream = await sfile.OpenAsync(FileAccessMode.Read))
{
    UInt64 size64 = readStream.Size;
    if (size64 <= UInt32.MaxValue)
    {
        UInt32 size32 = (UInt32)size64;
        IBuffer buffer = new Windows.Storage.Streams.Buffer(size32);
        buffer = await readStream.ReadAsync(buffer, size32, InputStreamOptions.None);
        string fileContent = CryptographicBuffer.ConvertBinaryToString(BinaryStringEncoding.Utf8, buffer);
        Debug.WriteLine(fileContent);
    }
    else
    {
        // 一塊で送るにはデータが大きすぎた(4GB以上のデータは一度には処理できない)
    }
}

画像を読み込み~画面に表示~別ファイルにコピー

var folderPath = @"C:\Users\Public\Documents";
StorageFolder sfolder = await StorageFolder.GetFolderFromPathAsync(folderPath);

// 画像ファイル読み込み~画面に表示
var datas = new List<int>();
var imageFileName = @"image.png";
var image = new BitmapImage();
StorageFile imageFile = await sfolder.CreateFileAsync(imageFileName, CreationCollisionOption.OpenIfExists);
using (IRandomAccessStream stream = await imageFile.OpenAsync(FileAccessMode.Read))
{
    // 画面に表示
    await image.SetSourceAsync(stream);

    // バイナリで読んでみる
    stream.Seek(0);// ←一旦、読み込み場所を先頭に戻す
    var imagestream = stream.AsStreamForRead();
    for (int i = 0; i < imagestream.Length; i++)
    {
        var data = imagestream.ReadByte();
        datas.Add(data);
    }
}
MyImage.Source = image;

// 画像書き込み
var imageFileName2 = @"image2.png";
StorageFile imageFile2 = await sfolder.CreateFileAsync(imageFileName2, CreationCollisionOption.ReplaceExisting);
int ctr = 0;
using (IRandomAccessStream stream = await imageFile2.OpenAsync(FileAccessMode.ReadWrite))
{
    var sw = stream.AsStreamForWrite();
    var data = datas.ToArray();
    await sw.WriteAsync(data.Select(x => (byte)x).ToArray(), 0, data.Length);
}

参考

docs.microsoft.com

docs.microsoft.com

github.com