我以前从未接触过Java IO API的经验,现在我真的很沮丧.我发现很难相信它有多奇怪和复杂,做一个简单的任务有多难.
我的任务:我有2个位置(起始字节,结束字节),pos1和pos2.我需要读取这两个字节之间的行(包括起始字节,不包括结尾字节),并将它们用作UTF8字符串对象.
例如,在大多数脚本语言中,它将是一个非常简单的1-2-3-liner(在Ruby中,但它对于Python,Perl等基本相同):
f = File.open("file.txt").seek(pos1)
while f.pos < pos2 {
s = f.readline
# do something with "s" here
}
Run Code Online (Sandbox Code Playgroud)
使用Java IO API很快就会出现问题;)实际上,我看到了两种\n从常规本地文件中读取行(以...结尾)的方法:
getFilePointer()和seek(long pos),但它的readLine()读取非UTF8字符串(甚至不是字节数组),但非常奇怪的字符串具有破坏的编码,并且它没有缓冲(这可能意味着每个read*()调用都将被转换为单个不连续的OS read()= >相当慢).readLine()方法,它甚至可以进行一些搜索skip(long n),但它无法确定已经读取的偶数字节数,也没有提到文件中的当前位置.我试过用类似的东西:
FileInputStream fis = new FileInputStream(fileName);
FileChannel fc = fis.getChannel();
BufferedReader br = new BufferedReader(
new InputStreamReader(
fis,
CHARSET_UTF8
)
);
Run Code Online (Sandbox Code Playgroud)
...然后使用fc.position()获取当前文件读取位置并fc.position(newPosition)设置一个,但它似乎在我的情况下不起作用:看起来它返回由BufferedReader完成的缓冲区预填充的位置,或类似的东西 - …
在回答我对文件阅读问题的回答时,一位评论者表示FileInputStream.read(byte[])"不能保证填补缓冲区".
File file = /* ... */
long len = file.length();
byte[] buffer = new byte[(int)len];
FileInputStream in = new FileInputStream(file);
in.read(buffer);
Run Code Online (Sandbox Code Playgroud)
(代码假定文件长度不超过2GB)
除了IOException,什么可能导致该read方法无法检索整个文件内容?
编辑:
代码的概念(以及我回答的问题的OP的目标)是将整个文件一次性读入一块内存,这就是buffer_size = file_size的原因.
I'm trying to read from a file called "quiz_questions.txt" in my res/raw folder. The code I have compiles, but it looks like it stops before it gets to the FileInputStream. Maybe it is opening it, but not reading it. I'm not sure.
import java.io.*;
import android.app.Activity;
import android.content.Context;
import android.content.res.Resources;
public class Questions extends Activity {
public String[][] questions = new String[10][5];
public void fillArray() {
{
Context con = null;
try {
//fis = new BufferedInputStream(new FileInputStream("res/raw/quiz_questions.txt"));
FileInputStream fis …Run Code Online (Sandbox Code Playgroud) java.io.InputStream.skip()说"抛出:IOException - 如果流不支持搜索,或者是否发生其他一些I/O错误."
我怎么知道哪个文件流支持搜索?
当谷歌我找到Seekable,但我可以看到简单的FileInputStream,ByteArrayInputStream ...也支持skip(),我的意思是不给IOException; 他们没有扩展Seekable.
嗨我正在尝试从资产中读取excel并希望将其转换为JSON,但我收到错误:打开失败:ENOENT(没有这样的文件或目录),搜索了许多SO问题但找不到解决方案下面是我的代码
public void readXlsFileAndConvertToJsonObject() {
JSONArray jsonArray = new JSONArray();
JSONArray mainJsonArray = new JSONArray();
try {
File file = new File("file:///android_asset/filters.xls");
FileInputStream fis = new FileInputStream(file);
//final FileInputStream file = new FileInputStream(new File("filters.xls"));
int count = 0;
// Get the workbook instance for XLS file
HSSFWorkbook workbook = new HSSFWorkbook(fis);
// Get first sheet from the workbook
HSSFSheet sheet = workbook.getSheetAt(0);
// Iterate through each rows from first sheet
Iterator < Row > rowIterator = sheet.iterator();
while …Run Code Online (Sandbox Code Playgroud) 我正在尝试为FileInputStream用户从他们的图库中选择的图片获取一个对象,当我尝试从我收到的URI中打开文件时,它一直在说FileNotFoundException......
这是我用来启动从图库中选择图像的意图的代码:
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select Picture"), PICK_IMAGE_REQUEST);
Run Code Online (Sandbox Code Playgroud)
这是我用来捕捉的代码onActivityResult:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == PICK_IMAGE_REQUEST && resultCode == RESULT_OK && data != null && data.getData() != null) {
Uri uri = data.getData();
File myFile = new File(uri.getPath());
FileInputStream fiStream = new FileInputStream(myFile);
...
}
}
Run Code Online (Sandbox Code Playgroud)
在创建的时候FileInputStream,我通过模拟器选择了一张照片时出现了以下错误:
W/System.err: java.io.FileNotFoundException: /document/image:26171: open failed: ENOENT (No such file or …Run Code Online (Sandbox Code Playgroud) 当我使用FileInputStream读取一个对象(比如几个字节)时,底层操作是否涉及:
1)读取整块磁盘,这样如果我随后再进行另一次读取操作,它就不需要真正的磁盘读取,因为在上次读取操作中已经取出了该部分文件?
要么
2)由于FileInputStream不进行任何缓冲而应该进行新的磁盘访问,而应该使用bufferedInputStream来实现(1)的效果?
我认为,由于FileInputStream使用读取系统调用,并且它只从硬盘读取一组页面,因此必须进行一些缓冲.
我有一个文件f,我需要将其影响到FileInputStream fs:
File f = new File("C:/dir/foo.txt");
FileInputStream fs = (FileInputStream)f;
Run Code Online (Sandbox Code Playgroud)
但我得到这个错误:
Cannot cast from File to FileInputStream
Run Code Online (Sandbox Code Playgroud)
怎么能fs得到的内容f?
我有一个带有奇怪编码"UCS-2 Little Endian"的文本文件,我想用Java读取它的内容.

正如您在上面的屏幕截图中看到的那样,文件内容在Notepad ++中显得很好,但是当我使用此代码读取它时,只是在控制台中打印垃圾:
String textFilePath = "c:\strange_file_encoding.txt"
BufferedReader reader = new BufferedReader( new InputStreamReader( new FileInputStream( filePath ), "UTF8" ) );
String line = "";
while ( ( line = reader.readLine() ) != null ) {
System.out.println( line ); // Prints garbage characters
}
Run Code Online (Sandbox Code Playgroud)
重点是用户选择要读取的文件,因此它可以是任何编码,并且因为我无法检测文件编码,所以我使用"UTF8"对其进行解码,但如上例所示,它无法正确读取.
有没有以正确的方式阅读这些奇怪的文件?或者至少可以检测出我的代码是否无法正确读取它?
有人可以解释为什么这个结构不起作用:
while (fileInputStream.available()>0) {
fileOutputStream.write(fileInputStream.read());
}
Run Code Online (Sandbox Code Playgroud)
这个工作得很好:
while (fileInputStream.available()>0) {
int data = fileInputStream.read();
fileOutputStream.write(data);
}
Run Code Online (Sandbox Code Playgroud)
至于我,他们是相同的,但第一个不会正确写入数据(将写入一半的文件长度/数据).
fileinputstream ×10
java ×9
android ×3
io ×2
disk ×1
file ×1
inputstream ×1
java-io ×1
nio ×1
seek ×1
text-files ×1