質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.52%

  • C#

    7102questions

    C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

  • Azure

    212questions

    Azureは、マイクロソフトのクラウド プラットフォームで、旧称は Windows Azureです。PaaSとIaaSを組み合わせることで、 コンピューティング・ストレージ・データ・ネットワーキング・アプリケーションなど多くの機能を持ちます。

FileStreamでWriteAsyncを利用したファイルの書き込みについて

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 244

punineko

score 2

ファイルのアップロードするプログラムを作成しているのですが、
ファイルアップロードはできるのですがファイルが壊れてしまって開けない状態になってしまいます。

下記ソースでファイルはできるのですが壊れています。
よろしくお願いします。

var stream = Request.InputStream; //1mbづつアップされる。
var position = Int32.Parse(Request.Headers["ChunkPosition"]);

var bytes = ReadToEnd(InputStream);

if (bytes.Length > 0)
{
using (FileStream fs = new FileStream(_path, FileMode.Open, FileAccess.Write, FileShare.Write, bytes.Length, true))
{
fs.Seek(position, SeekOrigin.Begin);
fs.WriteAsync(bytes, 0, bytes.Length);
}
}

public static byte[] ReadToEnd(System.IO.Stream stream)
{
long originalPosition = 0;

if (stream.CanSeek)
{
originalPosition = stream.Position;
stream.Position = 0;
}

try
{
byte[] readBuffer = new byte[4096];

int totalBytesRead = 0;
int bytesRead;

while ((bytesRead = stream.Read(readBuffer, totalBytesRead, readBuffer.Length - totalBytesRead)) > 0)
{
totalBytesRead += bytesRead;

if (totalBytesRead == readBuffer.Length)
{
int nextByte = stream.ReadByte();
if (nextByte != -1)
{
byte[] temp = new byte[readBuffer.Length * 2];
Buffer.BlockCopy(readBuffer, 0, temp, 0, readBuffer.Length);
Buffer.SetByte(temp, totalBytesRead, (byte)nextByte);
readBuffer = temp;
totalBytesRead++;
}
}
}

byte[] buffer = readBuffer;
if (readBuffer.Length != totalBytesRead)
{
buffer = new byte[totalBytesRead];
Buffer.BlockCopy(readBuffer, 0, buffer, 0, totalBytesRead);
}
return buffer;
}
finally
{
if (stream.CanSeek)
{
stream.Position = originalPosition;
}
}
}

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+1

using (FileStream fs = new FileStream(_path, FileMode.Open, FileAccess.Write, FileShare.Write, bytes.Length, true))
{
    fs.Seek(position, SeekOrigin.Begin);
    fs.WriteAsync(bytes, 0, bytes.Length);
}


WriteAsyncは、非同期にファイル書き込みを行うものなので、メソッド自体は即座に終了します
書き込みが始まらない/終わらないうちにFilestreamがCloseされるため、ファイルは壊れてしまいます

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/07/19 12:41

    ご回答ありがとうございます。

    非同期で1mbづつファイルを書き込む処理になっております。
    最初のpositionに開始位置が入ってきて1mbづつファイルに書き込みすることになっています。

    キャンセル

  • 2018/07/19 12:58

    ふつーにWriteでいいんじゃないでしょうか

    キャンセル

  • 2018/07/19 13:10

    fs.Write(bytes, 0, bytes.Length);

    にしてもファイルが壊れていました。
    ということはストリームで送られてくるところで壊れている可能背のほうが大きいですかね。

    キャンセル

  • 2018/07/19 13:16

    2mbのファイルを書き込む際にバイナリを確認すると前半1mb分が空っぽになっていまいた。

    キャンセル

  • 2018/07/19 13:24

    受信したものをそのままそれぞれファイルへ書き込み(1.tmp、2.tmp
    って感じ)、全受信終了後に再構築(copy 1.tmp + 2.tmp 受信ファイル名)すればいいのでは?

    キャンセル

  • 2018/07/19 13:35

    書き込むデータがどうなってるか確認しましょう。
    そこのWriteのせいで壊れるってことはないはずです

    キャンセル

  • 2018/07/19 14:08

    ご回答ありがとうございます。
    前任者が毎回ファイルを作成するロジックにしており
    ファイルの中身が消して書き込むという感じになっておりました。
    ファイルサイズは指定されたサイズで作成されるため気づきませんでした。
    皆様ありがとうございました。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.52%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • C#

    7102questions

    C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

  • Azure

    212questions

    Azureは、マイクロソフトのクラウド プラットフォームで、旧称は Windows Azureです。PaaSとIaaSを組み合わせることで、 コンピューティング・ストレージ・データ・ネットワーキング・アプリケーションなど多くの機能を持ちます。